feat: deeplinks

This commit is contained in:
neoapps-dev
2026-06-16 19:20:50 +03:00
parent 6312fb4540
commit 38fca607fd
18 changed files with 1003 additions and 392 deletions

113
src-tauri/Cargo.lock generated
View File

@@ -564,6 +564,26 @@ dependencies = [
"crossbeam-utils",
]
[[package]]
name = "const-random"
version = "0.1.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87e00182fe74b066627d63b85fd550ac2998d4b0bd86bfed477a0ae4c7c71359"
dependencies = [
"const-random-macro",
]
[[package]]
name = "const-random-macro"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
dependencies = [
"getrandom 0.2.17",
"once_cell",
"tiny-keccak",
]
[[package]]
name = "convert_case"
version = "0.4.0"
@@ -929,6 +949,15 @@ dependencies = [
"syn 2.0.117",
]
[[package]]
name = "dlv-list"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "442039f5147480ba31067cb00ada1adae6892028e40e45fc5de7b7df6dcc1b5f"
dependencies = [
"const-random",
]
[[package]]
name = "dom_query"
version = "0.27.0"
@@ -1033,10 +1062,12 @@ dependencies = [
"steam_shortcuts_util",
"tauri",
"tauri-build",
"tauri-plugin-deep-link",
"tauri-plugin-drpc",
"tauri-plugin-gamepad",
"tauri-plugin-opener",
"tauri-plugin-process",
"tauri-plugin-single-instance",
"tauri-plugin-updater",
"tokio",
"tokio-tungstenite",
@@ -1773,6 +1804,12 @@ version = "0.12.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888"
[[package]]
name = "hashbrown"
version = "0.14.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
[[package]]
name = "hashbrown"
version = "0.15.5"
@@ -2993,6 +3030,16 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d"
[[package]]
name = "ordered-multimap"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49203cdcae0030493bad186b28da2fa25645fa276a51b6fec8010d281e02ef79"
dependencies = [
"dlv-list",
"hashbrown 0.14.5",
]
[[package]]
name = "ordered-stream"
version = "0.2.0"
@@ -3851,6 +3898,16 @@ dependencies = [
"uuid 0.8.2",
]
[[package]]
name = "rust-ini"
version = "0.21.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "796e8d2b6696392a43bea58116b667fb4c29727dc5abd27d6acf338bb4f688c7"
dependencies = [
"cfg-if",
"ordered-multimap",
]
[[package]]
name = "rustc-hash"
version = "2.1.2"
@@ -4809,6 +4866,27 @@ dependencies = [
"walkdir",
]
[[package]]
name = "tauri-plugin-deep-link"
version = "2.4.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70ee75bc5627f77bfdf40c913255ebc258117b10ebe2b2239a1a1cf40b0b58aa"
dependencies = [
"dunce",
"plist",
"rust-ini",
"serde",
"serde_json",
"tauri",
"tauri-plugin",
"tauri-utils",
"thiserror 2.0.18",
"tracing",
"url",
"windows-registry",
"windows-result 0.3.4",
]
[[package]]
name = "tauri-plugin-drpc"
version = "0.1.6"
@@ -4873,6 +4951,21 @@ dependencies = [
"tauri-plugin",
]
[[package]]
name = "tauri-plugin-single-instance"
version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c8f29386f5e9fdc699182388a33ee80a56de436d91b67459e86afef426282af"
dependencies = [
"serde",
"serde_json",
"tauri",
"thiserror 2.0.18",
"tracing",
"windows-sys 0.60.2",
"zbus",
]
[[package]]
name = "tauri-plugin-updater"
version = "2.10.1"
@@ -5122,6 +5215,15 @@ dependencies = [
"time-core",
]
[[package]]
name = "tiny-keccak"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2c9d3793400a45f954c52e73d068316d76b6f4e36977e3fcebb13a2721e80237"
dependencies = [
"crunchy",
]
[[package]]
name = "tinystr"
version = "0.8.3"
@@ -6165,6 +6267,17 @@ dependencies = [
"windows-link 0.2.1",
]
[[package]]
name = "windows-registry"
version = "0.5.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b8a9ed28765efc97bbc954883f4e6796c33a06546ebafacbabee9696967499e"
dependencies = [
"windows-link 0.1.3",
"windows-result 0.3.4",
"windows-strings 0.4.2",
]
[[package]]
name = "windows-result"
version = "0.3.4"

View File

@@ -38,6 +38,8 @@ flate2 = "1"
once_cell = "1"
lzxd = "0.2.6"
uuid = { version = "1", features = ["v4"] }
tauri-plugin-deep-link = "2"
tauri-plugin-single-instance = "2"
[target.'cfg(not(any(target_os = "android", target_os = "ios")))'.dependencies]
tauri-plugin-updater = "2"

View File

@@ -35,6 +35,7 @@
}
]
},
"process:default"
"process:default",
"deep-link:default"
]
}

View File

@@ -10,6 +10,7 @@
],
"permissions": [
"updater:default",
"process:default"
"process:default",
"deep-link:default"
]
}

File diff suppressed because one or more lines are too long

View File

@@ -1 +1 @@
{"default":{"identifier":"default","description":"Default permissions","local":true,"windows":["main"],"permissions":["core:default","core:app:default","core:event:default","core:image:default","core:menu:default","core:path:default","core:resources:default","core:tray:default","core:webview:default","core:window:default","opener:default","gamepad:default","drpc:default","updater:default",{"identifier":"opener:allow-open-path","allow":[{"path":"**"}]},{"identifier":"opener:allow-reveal-item-in-dir","allow":[{"path":"**"}]},"process:default"]},"desktop-capability":{"identifier":"desktop-capability","description":"","local":true,"windows":["main"],"permissions":["updater:default","process:default"],"platforms":["macOS","windows","linux"]}}
{"default":{"identifier":"default","description":"Default permissions","local":true,"windows":["main"],"permissions":["core:default","core:app:default","core:event:default","core:image:default","core:menu:default","core:path:default","core:resources:default","core:tray:default","core:webview:default","core:window:default","opener:default","gamepad:default","drpc:default","updater:default",{"identifier":"opener:allow-open-path","allow":[{"path":"**"}]},{"identifier":"opener:allow-reveal-item-in-dir","allow":[{"path":"**"}]},"process:default","deep-link:default"]},"desktop-capability":{"identifier":"desktop-capability","description":"","local":true,"windows":["main"],"permissions":["updater:default","process:default","deep-link:default"],"platforms":["macOS","windows","linux"]}}

View File

@@ -2312,6 +2312,60 @@
"const": "core:window:deny-unminimize",
"markdownDescription": "Denies the unminimize command without any pre-configured scope."
},
{
"description": "Allows reading the opened deep link via the get_current command\n#### This default permission set includes:\n\n- `allow-get-current`",
"type": "string",
"const": "deep-link:default",
"markdownDescription": "Allows reading the opened deep link via the get_current command\n#### This default permission set includes:\n\n- `allow-get-current`"
},
{
"description": "Enables the get_current command without any pre-configured scope.",
"type": "string",
"const": "deep-link:allow-get-current",
"markdownDescription": "Enables the get_current command without any pre-configured scope."
},
{
"description": "Enables the is_registered command without any pre-configured scope.",
"type": "string",
"const": "deep-link:allow-is-registered",
"markdownDescription": "Enables the is_registered command without any pre-configured scope."
},
{
"description": "Enables the register command without any pre-configured scope.",
"type": "string",
"const": "deep-link:allow-register",
"markdownDescription": "Enables the register command without any pre-configured scope."
},
{
"description": "Enables the unregister command without any pre-configured scope.",
"type": "string",
"const": "deep-link:allow-unregister",
"markdownDescription": "Enables the unregister command without any pre-configured scope."
},
{
"description": "Denies the get_current command without any pre-configured scope.",
"type": "string",
"const": "deep-link:deny-get-current",
"markdownDescription": "Denies the get_current command without any pre-configured scope."
},
{
"description": "Denies the is_registered command without any pre-configured scope.",
"type": "string",
"const": "deep-link:deny-is-registered",
"markdownDescription": "Denies the is_registered command without any pre-configured scope."
},
{
"description": "Denies the register command without any pre-configured scope.",
"type": "string",
"const": "deep-link:deny-register",
"markdownDescription": "Denies the register command without any pre-configured scope."
},
{
"description": "Denies the unregister command without any pre-configured scope.",
"type": "string",
"const": "deep-link:deny-unregister",
"markdownDescription": "Denies the unregister command without any pre-configured scope."
},
{
"description": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-spawn-thread`\n- `allow-destroy-thread`\n- `allow-set-activity`\n- `allow-is-running`",
"type": "string",

View File

@@ -2312,6 +2312,60 @@
"const": "core:window:deny-unminimize",
"markdownDescription": "Denies the unminimize command without any pre-configured scope."
},
{
"description": "Allows reading the opened deep link via the get_current command\n#### This default permission set includes:\n\n- `allow-get-current`",
"type": "string",
"const": "deep-link:default",
"markdownDescription": "Allows reading the opened deep link via the get_current command\n#### This default permission set includes:\n\n- `allow-get-current`"
},
{
"description": "Enables the get_current command without any pre-configured scope.",
"type": "string",
"const": "deep-link:allow-get-current",
"markdownDescription": "Enables the get_current command without any pre-configured scope."
},
{
"description": "Enables the is_registered command without any pre-configured scope.",
"type": "string",
"const": "deep-link:allow-is-registered",
"markdownDescription": "Enables the is_registered command without any pre-configured scope."
},
{
"description": "Enables the register command without any pre-configured scope.",
"type": "string",
"const": "deep-link:allow-register",
"markdownDescription": "Enables the register command without any pre-configured scope."
},
{
"description": "Enables the unregister command without any pre-configured scope.",
"type": "string",
"const": "deep-link:allow-unregister",
"markdownDescription": "Enables the unregister command without any pre-configured scope."
},
{
"description": "Denies the get_current command without any pre-configured scope.",
"type": "string",
"const": "deep-link:deny-get-current",
"markdownDescription": "Denies the get_current command without any pre-configured scope."
},
{
"description": "Denies the is_registered command without any pre-configured scope.",
"type": "string",
"const": "deep-link:deny-is-registered",
"markdownDescription": "Denies the is_registered command without any pre-configured scope."
},
{
"description": "Denies the register command without any pre-configured scope.",
"type": "string",
"const": "deep-link:deny-register",
"markdownDescription": "Denies the register command without any pre-configured scope."
},
{
"description": "Denies the unregister command without any pre-configured scope.",
"type": "string",
"const": "deep-link:deny-unregister",
"markdownDescription": "Denies the unregister command without any pre-configured scope."
},
{
"description": "Default permissions for the plugin\n#### This default permission set includes:\n\n- `allow-spawn-thread`\n- `allow-destroy-thread`\n- `allow-set-activity`\n- `allow-is-running`",
"type": "string",

View File

@@ -10,7 +10,7 @@ mod commands;
use std::collections::HashMap;
use std::sync::Arc;
use tokio::sync::Mutex;
use tauri::Manager;
use tauri::{Emitter, Manager};
use commands::config as config_cmds;
use commands::download;
use commands::file_dialogs;
@@ -29,6 +29,21 @@ use state::{DownloadState, GameState, ProxyGuard};
#[cfg_attr(mobile, tauri::mobile_entry_point)]
pub fn run() {
tauri::Builder::default()
.plugin(tauri_plugin_deep_link::init())
.plugin(tauri_plugin_single_instance::init(|app, args, _cwd| {
let urls: Vec<String> = args
.iter()
.filter(|a| {
a.starts_with("emerald://")
|| a.starts_with("emeraldlauncher://")
|| a.starts_with("discord-1482504445152460871://")
})
.cloned()
.collect();
if !urls.is_empty() {
let _ = app.emit("deep-link", urls);
}
}))
.plugin(tauri_plugin_process::init())
.plugin(tauri_plugin_updater::Builder::new().build())
.manage(DownloadState {
@@ -112,21 +127,27 @@ pub fn run() {
let args: Vec<String> = std::env::args().collect();
if args.len() > 1 && !args[1].starts_with('-') {
let instance_id = args[1].clone();
let app_handle = app.handle().clone();
tauri::async_runtime::spawn(async move {
if let Some(window) = app_handle.get_webview_window("main") {
let _ = window.hide();
}
let state = app_handle.state::<GameState>();
match game::launch_game(app_handle.clone(), state, instance_id, Vec::new(), vec![]).await {
Ok(_) => app_handle.exit(0),
Err(e) => {
eprintln!("Auto-launch error: {}", e);
app_handle.exit(1);
let first = &args[1];
let is_deep_link = first.starts_with("emerald://")
|| first.starts_with("emeraldlauncher://")
|| first.starts_with("discord-1482504445152460871://");
if !is_deep_link {
let instance_id = first.clone();
let app_handle_clone = app.handle().clone();
tauri::async_runtime::spawn(async move {
if let Some(window) = app_handle_clone.get_webview_window("main") {
let _ = window.hide();
}
}
});
let state = app_handle_clone.state::<GameState>();
match game::launch_game(app_handle_clone.clone(), state, instance_id, Vec::new(), vec![]).await {
Ok(_) => app_handle_clone.exit(0),
Err(e) => {
eprintln!("Auto-launch error: {}", e);
app_handle_clone.exit(1);
}
}
});
}
}
Ok(())
})

View File

@@ -27,6 +27,11 @@
]
},
"plugins": {
"deep-link": {
"desktop": {
"schemes": ["emerald", "discord-1482504445152460871", "emeraldlauncher"]
}
},
"updater": {
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDM1NTk5MjQ4QjMxQjFCQgpSV1M3c1RHTEpKbFZBMEtxMnNUZ3F5V2FmQmQrREY5Z0pkbnJuUlBYL2d1cUtzRkJIeDFkUkR4RQo=",
"endpoints": [

View File

@@ -27,6 +27,11 @@
]
},
"plugins": {
"deep-link": {
"desktop": {
"schemes": ["emerald", "discord-1482504445152460871", "emeraldlauncher"]
}
},
"updater": {
"pubkey": "dW50cnVzdGVkIGNvbW1lbnQ6IG1pbmlzaWduIHB1YmxpYyBrZXk6IDM1NTk5MjQ4QjMxQjFCQgpSV1M3c1RHTEpKbFZBMEtxMnNUZ3F5V2FmQmQrREY5Z0pkbnJuUlBYL2d1cUtzRkJIeDFkUkR4RQo=",
"endpoints": [