Add file assosiation for Tauri

This commit is contained in:
kwaroran
2024-10-09 21:06:22 +09:00
parent 5a931d4ba0
commit d3500ce55c
4 changed files with 136 additions and 5 deletions

View File

@@ -420,6 +420,47 @@ async fn streamed_fetch(
} }
use std::path::PathBuf;
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
fn handle_file_associations(app: AppHandle, files: Vec<PathBuf>) {
// -- Scope handling start --
// You can remove this block if you only want to know about the paths, but not actually "use" them in the frontend.
// This requires the `fs` tauri plugin and is required to make the plugin's frontend work:
// use tauri_plugin_fs::FsExt;
// let fs_scope = app.fs_scope();
// This is for the `asset:` protocol to work:
let asset_protocol_scope = app.asset_protocol_scope();
for file in &files {
// This requires the `fs` plugin:
// let _ = fs_scope.allow_file(file);
// This is for the `asset:` protocol:
let _ = asset_protocol_scope.allow_file(file);
}
// -- Scope handling end --
let files = files
.into_iter()
.map(|f| {
let file = f.to_string_lossy().replace("\\", "\\\\"); // escape backslash
format!("\"{file}\"",) // wrap in quotes for JS array
})
.collect::<Vec<_>>()
.join(",");
tauri::WebviewWindowBuilder::new(&app, "main", Default::default())
.initialization_script(&format!("window.tauriOpenedFiles = [{files}]"))
.build()
.unwrap();
}
fn main() { fn main() {
tauri::Builder::default() tauri::Builder::default()
.plugin(tauri_plugin_http::init()) .plugin(tauri_plugin_http::init())
@@ -429,6 +470,35 @@ fn main() {
.plugin(tauri_plugin_dialog::init()) .plugin(tauri_plugin_dialog::init())
.plugin(tauri_plugin_os::init()) .plugin(tauri_plugin_os::init())
.plugin(tauri_plugin_fs::init()) .plugin(tauri_plugin_fs::init())
.setup(|#[allow(unused_variables)] app| {
#[cfg(any(windows, target_os = "linux"))]
{
let mut files = Vec::new();
// NOTICE: `args` may include URL protocol (`your-app-protocol://`)
// or arguments (`--`) if your app supports them.
// files may aslo be passed as `file://path/to/file`
for maybe_file in std::env::args().skip(1) {
// skip flags like -f or --flag
if maybe_file.starts_with("-") {
continue;
}
// handle `file://` path urls and skip other urls
if let Ok(url) = url::Url::parse(&maybe_file) {
if let Ok(path) = url.to_file_path() {
files.push(path);
}
} else {
files.push(PathBuf::from(maybe_file))
}
}
handle_file_associations(app.handle().clone(), files);
}
Ok(())
})
.invoke_handler(tauri::generate_handler![ .invoke_handler(tauri::generate_handler![
greet, greet,
native_request, native_request,
@@ -441,8 +511,26 @@ fn main() {
install_py_dependencies, install_py_dependencies,
streamed_fetch, streamed_fetch,
]) ])
.run(tauri::generate_context!()) .build(tauri::generate_context!())
.expect("error while running tauri application"); .expect("error while running tauri application")
.run(
// Copyright 2019-2024 Tauri Programme within The Commons Conservancy
// SPDX-License-Identifier: Apache-2.0
// SPDX-License-Identifier: MIT
#[allow(unused_variables)]
|app, event| {
#[cfg(any(target_os = "macos", target_os = "ios"))]
if let tauri::RunEvent::Opened { urls } = event {
let files = urls
.into_iter()
.filter_map(|url| url.to_file_path().ok())
.collect::<Vec<_>>();
handle_file_associations(app.clone(), files);
}
},
);
} }
fn header_map_to_json(header_map: &HeaderMap) -> serde_json::Value { fn header_map_to_json(header_map: &HeaderMap) -> serde_json::Value {

View File

@@ -18,7 +18,14 @@
"src-python/*" "src-python/*"
], ],
"targets": "all", "targets": "all",
"createUpdaterArtifacts": "v1Compatible" "createUpdaterArtifacts": "v1Compatible",
"fileAssociations": [
{
"ext": [
"risum", "risup", "charx"
]
}
]
}, },
"productName": "RisuAI", "productName": "RisuAI",
"mainBinaryName": "RisuAI", "mainBinaryName": "RisuAI",

View File

@@ -15,6 +15,7 @@ import type { OnnxModelFiles } from "./process/transformers"
import { CharXReader, CharXWriter } from "./process/processzip" import { CharXReader, CharXWriter } from "./process/processzip"
import { Capacitor } from "@capacitor/core" import { Capacitor } from "@capacitor/core"
import { exportModule, readModule, type RisuModule } from "./process/modules" import { exportModule, readModule, type RisuModule } from "./process/modules"
import { readFile } from "@tauri-apps/plugin-fs"
export const hubURL = "https://sv.risuai.xyz" export const hubURL = "https://sv.risuai.xyz"
@@ -408,6 +409,41 @@ export async function characterURLImport() {
} }
}); });
} }
if("tauriOpenedFiles" in window){
//@ts-ignore
const files:string[] = window.tauriOpenedFiles
if(files){
for(const file of files){
const data = await readFile(file)
if(file.endsWith('.charx')){
await importCharacterProcess({
name: file,
data: data
})
}
if(file.endsWith('.risupreset') || file.endsWith('.risup')){
await importPreset({
name: file,
data: data
})
SettingsMenuIndex.set(1)
settingsOpen.set(true)
alertNormal(language.successImport)
}
if(file.endsWith('risum')){
const md = await readModule(Buffer.from(data))
md.id = v4()
const db = get(DataBase)
db.modules.push(md)
setDatabase(db)
alertNormal(language.successImport)
SettingsMenuIndex.set(14)
settingsOpen.set(true)
}
}
}
}
} }

View File

@@ -1,9 +1,9 @@
{ {
"extends": "@tsconfig/svelte/tsconfig.json", "extends": "@tsconfig/svelte/tsconfig.json",
"compilerOptions": { "compilerOptions": {
"target": "ESNext", "target": "ES2022",
"useDefineForClassFields": true, "useDefineForClassFields": true,
"module": "ESNext", "module": "ES2022",
"resolveJsonModule": true, "resolveJsonModule": true,
"baseUrl": ".", "baseUrl": ".",
/** /**