Compare commits
No commits in common. "6609d647521aebe837e96552d8a77f9741c35018" and "733dd48663f658da422f02cd6177c3136b72a5ee" have entirely different histories.
6609d64752
...
733dd48663
33
src-tauri/Cargo.lock
generated
33
src-tauri/Cargo.lock
generated
@ -332,7 +332,6 @@ dependencies = [
|
|||||||
"chrono",
|
"chrono",
|
||||||
"image",
|
"image",
|
||||||
"md-5",
|
"md-5",
|
||||||
"mime_guess",
|
|
||||||
"mountpoints",
|
"mountpoints",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"serde",
|
"serde",
|
||||||
@ -342,7 +341,6 @@ dependencies = [
|
|||||||
"tauri-build",
|
"tauri-build",
|
||||||
"thiserror",
|
"thiserror",
|
||||||
"tokio",
|
"tokio",
|
||||||
"urlencoding",
|
|
||||||
"uuid 1.3.0",
|
"uuid 1.3.0",
|
||||||
"walkdir",
|
"walkdir",
|
||||||
]
|
]
|
||||||
@ -1618,22 +1616,6 @@ dependencies = [
|
|||||||
"autocfg",
|
"autocfg",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mime"
|
|
||||||
version = "0.3.17"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "6877bb514081ee2a7ff5ef9de3281f14a4dd4bceac4c09388074a6b5df8a139a"
|
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "mime_guess"
|
|
||||||
version = "2.0.4"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "4192263c238a5f0d0c6bfd21f336a313a4ce1c450542449ca191bb657b4642ef"
|
|
||||||
dependencies = [
|
|
||||||
"mime",
|
|
||||||
"unicase",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "miniz_oxide"
|
name = "miniz_oxide"
|
||||||
version = "0.6.2"
|
version = "0.6.2"
|
||||||
@ -3225,15 +3207,6 @@ version = "1.16.0"
|
|||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "unicase"
|
|
||||||
version = "2.6.0"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "50f37be617794602aabbeee0be4f259dc1778fabe05e2d67ee8f79326d5cb4f6"
|
|
||||||
dependencies = [
|
|
||||||
"version_check",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "unicode-bidi"
|
name = "unicode-bidi"
|
||||||
version = "0.3.10"
|
version = "0.3.10"
|
||||||
@ -3279,12 +3252,6 @@ dependencies = [
|
|||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "urlencoding"
|
|
||||||
version = "2.1.2"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "utf-8"
|
name = "utf-8"
|
||||||
version = "0.7.6"
|
version = "0.7.6"
|
||||||
|
@ -14,7 +14,7 @@ tauri-build = { version = "1.2", features = [] }
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
once_cell = "1.17.0"
|
once_cell = "1.17.0"
|
||||||
tauri = { version = "1.2", features = ["dialog-open", "fs-exists", "fs-read-dir", "fs-read-file", "protocol-all", "shell-open"] }
|
tauri = { version = "1.2", features = ["dialog-open", "fs-exists", "fs-read-dir", "fs-read-file", "protocol-asset", "shell-open"] }
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
serde_json = "1.0"
|
serde_json = "1.0"
|
||||||
chrono = { version = "0.4.23", features = ["serde"] }
|
chrono = { version = "0.4.23", features = ["serde"] }
|
||||||
@ -27,8 +27,6 @@ image = "0.24.5"
|
|||||||
uuid = "1.3.0"
|
uuid = "1.3.0"
|
||||||
mountpoints = "0.2.1"
|
mountpoints = "0.2.1"
|
||||||
md-5 = "0.10.5"
|
md-5 = "0.10.5"
|
||||||
urlencoding = "2.1.2"
|
|
||||||
mime_guess = "2.0.4"
|
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
# this feature is used for production builds or when `devPath` points to the filesystem
|
# this feature is used for production builds or when `devPath` points to the filesystem
|
||||||
|
@ -2,16 +2,13 @@
|
|||||||
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
#![cfg_attr(not(debug_assertions), windows_subsystem = "windows")]
|
||||||
|
|
||||||
mod commands;
|
mod commands;
|
||||||
mod protocol;
|
|
||||||
mod utils;
|
mod utils;
|
||||||
|
|
||||||
use commands::AppHold;
|
use commands::AppHold;
|
||||||
use protocol::comic_protocol;
|
|
||||||
use tauri::Manager;
|
use tauri::Manager;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
tauri::Builder::default()
|
tauri::Builder::default()
|
||||||
.register_uri_scheme_protocol("comic", comic_protocol)
|
|
||||||
.invoke_handler(tauri::generate_handler![
|
.invoke_handler(tauri::generate_handler![
|
||||||
commands::prelude::scan_directory,
|
commands::prelude::scan_directory,
|
||||||
commands::prelude::show_drives,
|
commands::prelude::show_drives,
|
||||||
|
@ -1,42 +0,0 @@
|
|||||||
use std::{error::Error, fs, path::Path};
|
|
||||||
|
|
||||||
use tauri::{
|
|
||||||
http::{Request, Response, ResponseBuilder},
|
|
||||||
AppHandle, Runtime,
|
|
||||||
};
|
|
||||||
use urlencoding::decode;
|
|
||||||
|
|
||||||
pub fn comic_protocol<R: Runtime>(
|
|
||||||
_app_handler: &AppHandle<R>,
|
|
||||||
request: &Request,
|
|
||||||
) -> Result<Response, Box<dyn Error>> {
|
|
||||||
let response_builder = ResponseBuilder::new();
|
|
||||||
let path = request
|
|
||||||
.uri()
|
|
||||||
.strip_prefix("comic://localhost/")
|
|
||||||
.map(|u| decode(u).unwrap())
|
|
||||||
.unwrap();
|
|
||||||
println!("[debug]request: {}", path);
|
|
||||||
if path.len() == 0 {
|
|
||||||
return response_builder
|
|
||||||
.mimetype("text/plain")
|
|
||||||
.status(404)
|
|
||||||
.body(Vec::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
let path = Path::new(path.as_ref());
|
|
||||||
if !path.exists() {
|
|
||||||
return response_builder
|
|
||||||
.mimetype("text/plain")
|
|
||||||
.status(404)
|
|
||||||
.body(Vec::new());
|
|
||||||
}
|
|
||||||
|
|
||||||
let mimetype = mime_guess::from_path(path);
|
|
||||||
let content = fs::read(path)?;
|
|
||||||
|
|
||||||
response_builder
|
|
||||||
.mimetype(mimetype.first_or_text_plain().essence_str())
|
|
||||||
.status(200)
|
|
||||||
.body(content)
|
|
||||||
}
|
|
@ -29,7 +29,11 @@
|
|||||||
"writeFile": false
|
"writeFile": false
|
||||||
},
|
},
|
||||||
"protocol": {
|
"protocol": {
|
||||||
"all": true
|
"all": false,
|
||||||
|
"asset": true,
|
||||||
|
"assetScope": [
|
||||||
|
"*"
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"shell": {
|
"shell": {
|
||||||
"all": false,
|
"all": false,
|
||||||
@ -62,7 +66,7 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"security": {
|
"security": {
|
||||||
"csp": null
|
"csp": "default-src 'self'; img-src 'self' asset: https://asset.localhost"
|
||||||
},
|
},
|
||||||
"updater": {
|
"updater": {
|
||||||
"active": false
|
"active": false
|
||||||
|
@ -7,6 +7,7 @@ import { FC, useMemo } from 'react';
|
|||||||
import { useMount } from 'react-use';
|
import { useMount } from 'react-use';
|
||||||
import { DirTree } from './components/DirTree';
|
import { DirTree } from './components/DirTree';
|
||||||
import { FileList } from './components/FileList';
|
import { FileList } from './components/FileList';
|
||||||
|
import { FileToolbar } from './components/FileTools';
|
||||||
import { loadDrives } from './queries/directories';
|
import { loadDrives } from './queries/directories';
|
||||||
|
|
||||||
const bgSelectFn = ifElse(
|
const bgSelectFn = ifElse(
|
||||||
@ -58,6 +59,7 @@ export const NavMenu: FC = () => {
|
|||||||
</Tabs.Panel>
|
</Tabs.Panel>
|
||||||
<Tabs.Panel value="files" h="100%">
|
<Tabs.Panel value="files" h="100%">
|
||||||
<Stack spacing={8} py={4} w="100%" h="100%" align="center">
|
<Stack spacing={8} py={4} w="100%" h="100%" align="center">
|
||||||
|
<FileToolbar />
|
||||||
<FileList />
|
<FileList />
|
||||||
</Stack>
|
</Stack>
|
||||||
</Tabs.Panel>
|
</Tabs.Panel>
|
||||||
|
48
src/components/FileTools.tsx
Normal file
48
src/components/FileTools.tsx
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
//@ts-nocheck
|
||||||
|
import { Button, Group, Tooltip } from '@mantine/core';
|
||||||
|
import { notifications } from '@mantine/notifications';
|
||||||
|
import { IconFolder } from '@tabler/icons-react';
|
||||||
|
import { invoke } from '@tauri-apps/api';
|
||||||
|
import { open } from '@tauri-apps/api/dialog';
|
||||||
|
import EventEmitter from 'events';
|
||||||
|
import { length } from 'ramda';
|
||||||
|
import { FC, useCallback, useContext } from 'react';
|
||||||
|
import { EventBusContext } from '../EventBus';
|
||||||
|
import { useFileListStore } from '../states/files';
|
||||||
|
|
||||||
|
export const FileToolbar: FC = () => {
|
||||||
|
const storeFiles = useFileListStore.use.updateFiles();
|
||||||
|
const ebus = useContext<EventEmitter>(EventBusContext);
|
||||||
|
const handleOpenAction = useCallback(async () => {
|
||||||
|
try {
|
||||||
|
const directory = await open({
|
||||||
|
title: '打开要浏览的漫画所在的文件夹',
|
||||||
|
directory: true,
|
||||||
|
multiple: false
|
||||||
|
});
|
||||||
|
const files = await invoke('scan_directory', { target: directory });
|
||||||
|
console.log('[debug]获取到文件个数:', length(files));
|
||||||
|
storeFiles(files);
|
||||||
|
ebus.emit('reset_views');
|
||||||
|
} catch (e) {
|
||||||
|
console.error('[error]打开文件夹', e);
|
||||||
|
notifications.show({ title: '未能成功打开指定文件夹,请重试。', color: 'red' });
|
||||||
|
}
|
||||||
|
}, [storeFiles]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Group align="start" w="100%" spacing={4}>
|
||||||
|
<Tooltip label="打开漫画所在文件夹">
|
||||||
|
<Button
|
||||||
|
size="xs"
|
||||||
|
variant="subtle"
|
||||||
|
fullWidth
|
||||||
|
leftIcon={<IconFolder stroke={1.5} size={14} />}
|
||||||
|
onClick={handleOpenAction}
|
||||||
|
>
|
||||||
|
打开文件夹
|
||||||
|
</Button>
|
||||||
|
</Tooltip>
|
||||||
|
</Group>
|
||||||
|
);
|
||||||
|
};
|
@ -24,8 +24,7 @@ export const useFileListStore = createStoreHook<FileListState & FileListActions>
|
|||||||
updateFiles(files) {
|
updateFiles(files) {
|
||||||
set(df => {
|
set(df => {
|
||||||
df.files = addIndex<Omit<FileItem, 'sort'>, FileItem>(map)(
|
df.files = addIndex<Omit<FileItem, 'sort'>, FileItem>(map)(
|
||||||
(item, index) =>
|
(item, index) => mergeLeft({ sort: index * 10, path: convertFileSrc(item.path) }, item),
|
||||||
mergeLeft({ sort: index * 10, path: convertFileSrc(item.path, 'comic') }, item),
|
|
||||||
files
|
files
|
||||||
);
|
);
|
||||||
df.actives = [];
|
df.actives = [];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user