Add file associations to support system "open with Readest" function, closes #1
Support passing files as command line args to Readest
This commit is contained in:
@@ -26,6 +26,7 @@
|
||||
},
|
||||
"dependencies": {
|
||||
"@tauri-apps/api": "2.1.1",
|
||||
"@tauri-apps/plugin-cli": "^2.0.0",
|
||||
"@tauri-apps/plugin-dialog": "^2.0.1",
|
||||
"@tauri-apps/plugin-fs": "^2.0.3",
|
||||
"@tauri-apps/plugin-http": "^2.0.1",
|
||||
|
||||
Generated
+110
@@ -14,6 +14,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-build 2.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"tauri-plugin-cli",
|
||||
"tauri-plugin-devtools",
|
||||
"tauri-plugin-dialog",
|
||||
"tauri-plugin-fs",
|
||||
@@ -107,6 +108,55 @@ dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstream"
|
||||
version = "0.6.18"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"anstyle-parse",
|
||||
"anstyle-query",
|
||||
"anstyle-wincon",
|
||||
"colorchoice",
|
||||
"is_terminal_polyfill",
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle"
|
||||
version = "1.0.10"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-parse"
|
||||
version = "0.2.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9"
|
||||
dependencies = [
|
||||
"utf8parse",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-query"
|
||||
version = "1.1.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c"
|
||||
dependencies = [
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anstyle-wincon"
|
||||
version = "3.0.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2109dbce0e72be3ec00bed26e6a7479ca384ad226efdd66db8fa2e3a38c83125"
|
||||
dependencies = [
|
||||
"anstyle",
|
||||
"windows-sys 0.59.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyhow"
|
||||
version = "1.0.93"
|
||||
@@ -595,6 +645,33 @@ dependencies = [
|
||||
"windows-targets 0.52.6",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap"
|
||||
version = "4.5.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fb3b4b9e5a7c7514dfa52869339ee98b3156b0bfb4e8a77c4ff4babb64b1604f"
|
||||
dependencies = [
|
||||
"clap_builder",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_builder"
|
||||
version = "4.5.21"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b17a95aa67cc7b5ebd32aa5370189aa0d79069ef1c64ce893bd30fb24bff20ec"
|
||||
dependencies = [
|
||||
"anstream",
|
||||
"anstyle",
|
||||
"clap_lex",
|
||||
"strsim",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "clap_lex"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "afb84c814227b90d6895e01398aee0d8033c00e7466aca416fb6a8e0eb19d8a7"
|
||||
|
||||
[[package]]
|
||||
name = "cocoa"
|
||||
version = "0.25.0"
|
||||
@@ -655,6 +732,12 @@ dependencies = [
|
||||
"objc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorchoice"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990"
|
||||
|
||||
[[package]]
|
||||
name = "colored"
|
||||
version = "2.1.0"
|
||||
@@ -2250,6 +2333,12 @@ dependencies = [
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "is_terminal_polyfill"
|
||||
version = "1.70.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7943c866cc5cd64cbc25b2e01621d07fa8eb2a1a23160ee81ce38704e97b8ecf"
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.12.1"
|
||||
@@ -4684,6 +4773,21 @@ dependencies = [
|
||||
"walkdir",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-cli"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2bccd4692b56822a60874542c7655546c8e7aed3c2e2926166e1498e595bd2a2"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"log",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"tauri",
|
||||
"tauri-plugin",
|
||||
"thiserror 1.0.69",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tauri-plugin-devtools"
|
||||
version = "2.0.0"
|
||||
@@ -5609,6 +5713,12 @@ version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b6c140620e7ffbb22c2dee59cafe6084a59b5ffc27a8859a5f0d494b5d52b6be"
|
||||
|
||||
[[package]]
|
||||
name = "utf8parse"
|
||||
version = "0.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821"
|
||||
|
||||
[[package]]
|
||||
name = "uuid"
|
||||
version = "1.11.0"
|
||||
|
||||
@@ -40,8 +40,6 @@ cocoa = "0.25"
|
||||
objc = "0.2.7"
|
||||
rand = "0.8"
|
||||
|
||||
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
|
||||
tauri-plugin-updater = "2"
|
||||
|
||||
[target.'cfg(any(target_os = "macos", windows, target_os = "linux"))'.dependencies]
|
||||
tauri-plugin-cli = "2"
|
||||
tauri-plugin-updater = "2"
|
||||
|
||||
@@ -57,6 +57,7 @@
|
||||
"shell:default",
|
||||
"updater:default",
|
||||
"process:default",
|
||||
"process:allow-restart"
|
||||
"process:allow-restart",
|
||||
"cli:default"
|
||||
]
|
||||
}
|
||||
|
||||
@@ -14,8 +14,34 @@ mod tauri_traffic_light_positioner_plugin;
|
||||
#[cfg(target_os = "macos")]
|
||||
use tauri::TitleBarStyle;
|
||||
|
||||
use std::path::PathBuf;
|
||||
use tauri::{AppHandle, Emitter, Listener, Manager, Url};
|
||||
use tauri::{WebviewUrl, WebviewWindowBuilder};
|
||||
use tauri_plugin_dialog;
|
||||
use tauri_plugin_fs::FsExt;
|
||||
|
||||
fn handle_file_associations(app: AppHandle, files: Vec<PathBuf>) {
|
||||
let asset_protocol_scope = app.asset_protocol_scope();
|
||||
let fs_scope = app.fs_scope();
|
||||
for file in &files {
|
||||
let _ = fs_scope.allow_file(file);
|
||||
let _ = asset_protocol_scope.allow_file(file);
|
||||
}
|
||||
|
||||
let files = files
|
||||
.into_iter()
|
||||
.map(|f| {
|
||||
let file = f.to_string_lossy().replace("\\", "\\\\");
|
||||
format!("\"{file}\"",)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join(",");
|
||||
let window = app.get_webview_window("main").unwrap();
|
||||
let script = format!("window.TAURI_CLI_ARGS = [{}];", files);
|
||||
if let Err(e) = window.eval(&script) {
|
||||
eprintln!("Failed to set open files variable: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||
pub fn run() {
|
||||
@@ -31,10 +57,37 @@ pub fn run() {
|
||||
let builder = builder.plugin(tauri_traffic_light_positioner_plugin::init());
|
||||
|
||||
builder
|
||||
.setup(|app| {
|
||||
.setup(|#[allow(unused_variables)] app| {
|
||||
#[cfg(desktop)]
|
||||
{
|
||||
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::parse(&maybe_file) {
|
||||
if let Ok(path) = url.to_file_path() {
|
||||
files.push(path);
|
||||
}
|
||||
} else {
|
||||
files.push(PathBuf::from(maybe_file))
|
||||
}
|
||||
}
|
||||
let asset_protocol_scope = app.asset_protocol_scope();
|
||||
let fs_scope = app.fs_scope();
|
||||
for file in &files {
|
||||
let _ = fs_scope.allow_file(file);
|
||||
let _ = asset_protocol_scope.allow_file(file);
|
||||
}
|
||||
}
|
||||
#[cfg(desktop)]
|
||||
app.handle().plugin(tauri_plugin_cli::init())?;
|
||||
#[cfg(desktop)]
|
||||
app.handle()
|
||||
.plugin(tauri_plugin_updater::Builder::new().build())?;
|
||||
if cfg!(debug_assertions) {
|
||||
app.handle().plugin(
|
||||
tauri_plugin_log::Builder::default()
|
||||
@@ -63,8 +116,25 @@ pub fn run() {
|
||||
#[cfg(target_os = "macos")]
|
||||
menu::setup_macos_menu(&app.handle())?;
|
||||
|
||||
app.handle().emit("window-ready", {}).unwrap();
|
||||
|
||||
Ok(())
|
||||
})
|
||||
.run(tauri::generate_context!())
|
||||
.expect("error while running tauri application");
|
||||
.build(tauri::generate_context!())
|
||||
.expect("error while running tauri application")
|
||||
.run(|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<_>>();
|
||||
|
||||
let app_handle = app.clone();
|
||||
app.listen("window-ready", move |_| {
|
||||
println!("Window is ready, proceeding to handle files.");
|
||||
handle_file_associations(app_handle.clone(), files.clone());
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@@ -49,12 +49,81 @@
|
||||
"macOS": {
|
||||
"minimumSystemVersion": "12.0"
|
||||
},
|
||||
"fileAssociations": [
|
||||
{
|
||||
"name": "epub",
|
||||
"ext": ["epub"],
|
||||
"description": "EPUB file",
|
||||
"mimeType": "application/epub+zip",
|
||||
"role": "Viewer"
|
||||
},
|
||||
{
|
||||
"name": "mobi",
|
||||
"ext": ["mobi"],
|
||||
"description": "MOBI file",
|
||||
"mimeType": "application/x-mobipocket-ebook",
|
||||
"role": "Viewer"
|
||||
},
|
||||
{
|
||||
"name": "azw",
|
||||
"ext": ["azw", "azw3"],
|
||||
"description": "AZW file",
|
||||
"mimeType": "application/vnd.amazon.ebook",
|
||||
"role": "Viewer"
|
||||
},
|
||||
{
|
||||
"name": "fb2",
|
||||
"ext": ["fb2"],
|
||||
"description": "FB2 file",
|
||||
"mimeType": "application/x-fictionbook+xml",
|
||||
"role": "Viewer"
|
||||
},
|
||||
{
|
||||
"name": "cbz",
|
||||
"ext": ["cbz"],
|
||||
"description": "CBZ file",
|
||||
"mimeType": "application/vnd.comicbook+zip",
|
||||
"role": "Viewer"
|
||||
},
|
||||
{
|
||||
"name": "pdf",
|
||||
"ext": ["pdf"],
|
||||
"description": "PDF file",
|
||||
"mimeType": "application/pdf",
|
||||
"role": "Viewer"
|
||||
}
|
||||
],
|
||||
"createUpdaterArtifacts": true
|
||||
},
|
||||
"plugins": {
|
||||
"fs": {
|
||||
"requireLiteralLeadingDot": false
|
||||
},
|
||||
"cli": {
|
||||
"description": "Readest CLI",
|
||||
"args": [
|
||||
{
|
||||
"name": "file1",
|
||||
"index": 1,
|
||||
"takesValue": true
|
||||
},
|
||||
{
|
||||
"name": "file2",
|
||||
"index": 2,
|
||||
"takesValue": true
|
||||
},
|
||||
{
|
||||
"name": "file3",
|
||||
"index": 3,
|
||||
"takesValue": true
|
||||
},
|
||||
{
|
||||
"name": "file4",
|
||||
"index": 4,
|
||||
"takesValue": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"updater": {
|
||||
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IEU0OTAxMURGQkUzQjFENTQKUldSVUhUdSszeEdRNUExdmFkWnlvYWNYNG5wamkxMmUxRk5SejlMOTJVd28yNXlVTDh6Wld4OC8K",
|
||||
"endpoints": ["https://github.com/chrox/readest/releases/latest/download/latest.json"]
|
||||
|
||||
@@ -6,7 +6,7 @@ import { AuthProvider } from '@/context/AuthContext';
|
||||
import { EnvProvider } from '@/context/EnvContext';
|
||||
import { CSPostHogProvider } from '@/context/PHContext';
|
||||
import { useTheme } from '@/hooks/useTheme';
|
||||
import { checkForAppUpdates } from '../helpers/updater';
|
||||
import { checkForAppUpdates } from '@/helpers/updater';
|
||||
|
||||
import '../styles/globals.css';
|
||||
import '../styles/fonts.css';
|
||||
|
||||
@@ -2,24 +2,55 @@
|
||||
|
||||
import * as React from 'react';
|
||||
import { useState, useRef } from 'react';
|
||||
import { useRouter } from 'next/navigation';
|
||||
|
||||
import { useEnv } from '@/context/EnvContext';
|
||||
import { useLibraryStore } from '@/store/libraryStore';
|
||||
import { useSettingsStore } from '@/store/settingsStore';
|
||||
|
||||
import { Book } from '@/types/book';
|
||||
import { parseOpenWithFiles } from '@/helpers/cli';
|
||||
import Spinner from '@/components/Spinner';
|
||||
import LibraryHeader from '@/app/library/components/LibraryHeader';
|
||||
import Bookshelf from '@/app/library/components/Bookshelf';
|
||||
import { AppService } from '@/types/system';
|
||||
|
||||
const LibraryPage = () => {
|
||||
const router = useRouter();
|
||||
const { envConfig, appService } = useEnv();
|
||||
const { library: libraryBooks, setLibrary } = useLibraryStore();
|
||||
const {
|
||||
library: libraryBooks,
|
||||
setLibrary,
|
||||
checkOpenWithBooks,
|
||||
clearOpenWithBooks,
|
||||
} = useLibraryStore();
|
||||
const { setSettings } = useSettingsStore();
|
||||
const [loading, setLoading] = useState(false);
|
||||
const isInitiating = useRef(false);
|
||||
const libraryLoaded = useRef(false);
|
||||
const [isSelectMode, setIsSelectMode] = useState(false);
|
||||
|
||||
const processOpenWithFiles = React.useCallback(
|
||||
async (appService: AppService, openWithFiles: string[], libraryBooks: Book[]) => {
|
||||
const bookIds: string[] = [];
|
||||
for (const file of openWithFiles) {
|
||||
const book = await appService.importBook(file, libraryBooks);
|
||||
if (book) {
|
||||
bookIds.push(book.hash);
|
||||
}
|
||||
}
|
||||
setLibrary(libraryBooks);
|
||||
appService.saveLibraryBooks(libraryBooks);
|
||||
|
||||
console.log('Opening books:', bookIds);
|
||||
if (bookIds.length > 0) {
|
||||
router.push(`/reader?ids=${bookIds.join(',')}`);
|
||||
}
|
||||
},
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
[],
|
||||
);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (isInitiating.current) return;
|
||||
isInitiating.current = true;
|
||||
@@ -29,13 +60,32 @@ const LibraryPage = () => {
|
||||
const appService = await envConfig.getAppService();
|
||||
const settings = await appService.loadSettings();
|
||||
setSettings(settings);
|
||||
setLibrary(await appService.loadLibraryBooks());
|
||||
|
||||
const libraryBooks = await appService.loadLibraryBooks();
|
||||
if (checkOpenWithBooks) {
|
||||
await handleOpenWithBooks(appService, libraryBooks);
|
||||
} else {
|
||||
setLibrary(libraryBooks);
|
||||
}
|
||||
|
||||
libraryLoaded.current = true;
|
||||
|
||||
if (loadingTimeout) clearTimeout(loadingTimeout);
|
||||
setLoading(false);
|
||||
};
|
||||
|
||||
const handleOpenWithBooks = async (appService: AppService, libraryBooks: Book[]) => {
|
||||
const openWithFiles = (await parseOpenWithFiles()) || [];
|
||||
|
||||
if (openWithFiles.length > 0) {
|
||||
await processOpenWithFiles(appService, openWithFiles, libraryBooks);
|
||||
} else {
|
||||
setLibrary(libraryBooks);
|
||||
}
|
||||
|
||||
clearOpenWithBooks();
|
||||
};
|
||||
|
||||
initLibrary();
|
||||
// eslint-disable-next-line react-hooks/exhaustive-deps
|
||||
}, []);
|
||||
|
||||
@@ -0,0 +1,40 @@
|
||||
import { getMatches } from '@tauri-apps/plugin-cli';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
TAURI_CLI_ARGS?: string[];
|
||||
}
|
||||
}
|
||||
|
||||
interface CliArgument {
|
||||
value: string;
|
||||
occurrences: number;
|
||||
}
|
||||
|
||||
const parseGlobalArgs = () => {
|
||||
return window.TAURI_CLI_ARGS;
|
||||
};
|
||||
|
||||
const parseCLIArgs = async () => {
|
||||
const matches = await getMatches();
|
||||
const args = matches?.args;
|
||||
const files: string[] = [];
|
||||
if (args) {
|
||||
for (const name of ['file1', 'file2', 'file3', 'file4']) {
|
||||
const arg = args[name] as CliArgument;
|
||||
if (arg && arg.occurrences > 0) {
|
||||
files.push(arg.value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return files;
|
||||
};
|
||||
|
||||
export const parseOpenWithFiles = async () => {
|
||||
let files = parseGlobalArgs();
|
||||
if (!files) {
|
||||
files = await parseCLIArgs();
|
||||
}
|
||||
return files;
|
||||
};
|
||||
@@ -2,7 +2,7 @@ import { check } from '@tauri-apps/plugin-updater';
|
||||
import { ask } from '@tauri-apps/plugin-dialog';
|
||||
import { relaunch } from '@tauri-apps/plugin-process';
|
||||
|
||||
export async function checkForAppUpdates() {
|
||||
export const checkForAppUpdates = async () => {
|
||||
const update = await check();
|
||||
if (update) {
|
||||
const yes = await ask(
|
||||
@@ -41,4 +41,4 @@ export async function checkForAppUpdates() {
|
||||
await relaunch();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
@@ -93,7 +93,7 @@ export abstract class BaseAppService implements AppService {
|
||||
file: string | File,
|
||||
books: Book[],
|
||||
overwrite: boolean = false,
|
||||
): Promise<Book[]> {
|
||||
): Promise<Book | null> {
|
||||
try {
|
||||
let loadedBook: BookDoc;
|
||||
let format: BookFormat;
|
||||
@@ -156,11 +156,11 @@ export abstract class BaseAppService implements AppService {
|
||||
await this.saveBookConfig(book, INIT_BOOK_CONFIG);
|
||||
books.splice(0, 0, book);
|
||||
}
|
||||
return book;
|
||||
} catch (error) {
|
||||
throw error;
|
||||
}
|
||||
|
||||
return books;
|
||||
return null;
|
||||
}
|
||||
|
||||
async deleteBook(book: Book): Promise<void> {
|
||||
|
||||
@@ -4,12 +4,16 @@ import { EnvConfigType } from '@/services/environment';
|
||||
|
||||
interface LibraryState {
|
||||
library: Book[];
|
||||
checkOpenWithBooks: boolean;
|
||||
clearOpenWithBooks: () => void;
|
||||
setLibrary: (books: Book[]) => void;
|
||||
deleteBook: (envConfig: EnvConfigType, book: Book) => void;
|
||||
}
|
||||
|
||||
export const useLibraryStore = create<LibraryState>((set, get) => ({
|
||||
library: [],
|
||||
checkOpenWithBooks: true,
|
||||
clearOpenWithBooks: () => set({ checkOpenWithBooks: false }),
|
||||
setLibrary: (books) => set({ library: books }),
|
||||
deleteBook: async (envConfig: EnvConfigType, book: Book) => {
|
||||
const appService = await envConfig.getAppService();
|
||||
|
||||
@@ -27,7 +27,7 @@ export interface AppService {
|
||||
|
||||
loadSettings(): Promise<SystemSettings>;
|
||||
saveSettings(settings: SystemSettings): Promise<void>;
|
||||
importBook(file: string | File, books: Book[], overwrite?: boolean): Promise<Book[]>;
|
||||
importBook(file: string | File, books: Book[], overwrite?: boolean): Promise<Book | null>;
|
||||
deleteBook(book: Book): Promise<void>;
|
||||
loadBookConfig(book: Book, settings: SystemSettings): Promise<BookConfig>;
|
||||
saveBookConfig(book: Book, config: BookConfig, settings?: SystemSettings): Promise<void>;
|
||||
|
||||
Generated
+10
@@ -38,6 +38,9 @@ importers:
|
||||
'@tauri-apps/api':
|
||||
specifier: 2.1.1
|
||||
version: 2.1.1
|
||||
'@tauri-apps/plugin-cli':
|
||||
specifier: ^2.0.0
|
||||
version: 2.0.0
|
||||
'@tauri-apps/plugin-dialog':
|
||||
specifier: ^2.0.1
|
||||
version: 2.0.1
|
||||
@@ -705,6 +708,9 @@ packages:
|
||||
engines: {node: '>= 10'}
|
||||
hasBin: true
|
||||
|
||||
'@tauri-apps/plugin-cli@2.0.0':
|
||||
resolution: {integrity: sha512-glQmlL1IiCGEa1FHYa/PTPSeYhfu56omLRgHXWlJECDt6DbJyRuJWVgtkQfUxtqnVdYnnU+DGIGeiInoEqtjLw==}
|
||||
|
||||
'@tauri-apps/plugin-dialog@2.0.1':
|
||||
resolution: {integrity: sha512-fnUrNr6EfvTqdls/ufusU7h6UbNFzLKvHk/zTuOiBq01R3dTODqwctZlzakdbfSp/7pNwTKvgKTAgl/NAP/Z0Q==}
|
||||
|
||||
@@ -4098,6 +4104,10 @@ snapshots:
|
||||
'@tauri-apps/cli-win32-ia32-msvc': 2.1.0
|
||||
'@tauri-apps/cli-win32-x64-msvc': 2.1.0
|
||||
|
||||
'@tauri-apps/plugin-cli@2.0.0':
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.1.1
|
||||
|
||||
'@tauri-apps/plugin-dialog@2.0.1':
|
||||
dependencies:
|
||||
'@tauri-apps/api': 2.1.1
|
||||
|
||||
Reference in New Issue
Block a user