Skip to content

Commit

Permalink
Fix deep linking on mac
Browse files Browse the repository at this point in the history
  • Loading branch information
Geometrically committed Aug 17, 2024
1 parent b105c7e commit e9268fa
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 37 deletions.
4 changes: 2 additions & 2 deletions apps/app/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@
<string>Owner</string>
<key>LSItemContentTypes</key>
<array>
<string>ModrinthApp-type</string>
<string>com.modrinth.theseus-type</string>
</array>
<key>NSDocumentClass</key>
<string>NSDocument</string>
Expand All @@ -45,7 +45,7 @@
<key>UTTypeIcons</key>
<dict/>
<key>UTTypeIdentifier</key>
<string>ModrinthApp-type</string>
<string>com.modrinth.theseus-type</string>
<key>UTTypeTagSpecification</key>
<dict>
<key>public.filename-extension</key>
Expand Down
23 changes: 21 additions & 2 deletions apps/app/src/api/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use theseus::{
};

use crate::api::Result;
use std::{env, path::PathBuf};
use dashmap::DashMap;
use std::path::PathBuf;

pub fn init<R: tauri::Runtime>() -> tauri::plugin::TauriPlugin<R> {
tauri::plugin::Builder::new("utils")
Expand Down Expand Up @@ -44,7 +45,7 @@ pub enum OS {
// Values provided should not be used directly, as they are not guaranteed to be up-to-date
#[tauri::command]
pub async fn progress_bars_list(
) -> Result<std::collections::HashMap<uuid::Uuid, theseus::LoadingBar>> {
) -> Result<DashMap<uuid::Uuid, theseus::LoadingBar>> {
let res = theseus::EventState::list_progress_bars().await?;
Ok(res)
}
Expand Down Expand Up @@ -92,10 +93,28 @@ pub fn show_launcher_logs_folder() {
// This should be called once and only when the app is done booting up and ready to receive a command
// Returns a Command struct- see events.js
#[tauri::command]
#[cfg(target_os = "macos")]
pub async fn get_opening_command(
state: tauri::State<'_, crate::macos::deep_link::InitialPayload>,
) -> Result<Option<CommandPayload>> {
let payload = state.payload.lock().await;

return if let Some(payload) = payload.as_ref() {
tracing::info!("opening command {payload}");

Ok(Some(handler::parse_command(payload).await?))
} else {
Ok(None)
};
}

#[cfg(not(target_os = "macos"))]
pub async fn get_opening_command() -> Result<Option<CommandPayload>> {
// Tauri is not CLI, we use arguments as path to file to call
let cmd_arg = env::args_os().nth(1);

tracing::info!("opening command {cmd_arg:?}");

let cmd_arg = cmd_arg.map(|path| path.to_string_lossy().to_string());
if let Some(cmd) = cmd_arg {
tracing::debug!("Opening command: {:?}", cmd);
Expand Down
6 changes: 6 additions & 0 deletions apps/app/src/macos/deep_link.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use std::sync::Arc;
use tokio::sync::Mutex;

pub struct InitialPayload {
pub payload: Arc<Mutex<Option<String>>>,
}
1 change: 1 addition & 0 deletions apps/app/src/macos/mod.rs
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
pub mod deep_link;
pub mod delegate;
pub mod window_ext;
63 changes: 52 additions & 11 deletions apps/app/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,16 +89,64 @@ fn main() {
}))
.plugin(tauri_plugin_window_state::Builder::default().build())
.setup(|app| {
// Register deep link handler, allowing reading of modrinth:// links
if let Err(e) = tauri_plugin_deep_link::register(
#[cfg(target_os = "macos")]
let res = {
use macos::deep_link::InitialPayload;
let mtx = std::sync::Arc::new(tokio::sync::Mutex::new(None));

app.manage(InitialPayload {
payload: mtx.clone(),
});

let mtx_copy = mtx.clone();
macos::delegate::register_open_file(move |filename| {
let mtx_copy = mtx_copy.clone();

tauri::async_runtime::spawn(async move {
tracing::info!("Handling file open {request}");

let mut payload = mtx_copy.lock().await;
if payload.is_none() {
*payload = Some(filename.clone());
}

let _ = api::utils::handle_command(filename).await;
});
})
.unwrap();

let mtx_copy = mtx.clone();
tauri_plugin_deep_link::register(
"modrinth",
move |request: String| {
let mtx_copy = mtx_copy.clone();

tauri::async_runtime::spawn(async move {
tracing::info!("Handling deep link {request}");

let mut payload = mtx_copy.lock().await;
if payload.is_none() {
*payload = Some(request.clone());
}

let _ = api::utils::handle_command(request).await;
});
},
)
};

#[cfg(not(target_os = "macos"))]
let res = tauri_plugin_deep_link::register(
"modrinth",
|request: String| {
tracing::info!("Handling deep link {request}");
tauri::async_runtime::spawn(api::utils::handle_command(
request,
));
},
) {
// Allow it to fail- see https://github.com/FabianLars/tauri-plugin-deep-link/issues/19
);

if let Err(e) = res {
tracing::error!("Error registering deep link handler: {}", e);
}

Expand All @@ -117,13 +165,6 @@ fn main() {
use macos::window_ext::WindowExt;
window.set_transparent_titlebar(true);
window.position_traffic_lights(9.0, 16.0);

macos::delegate::register_open_file(|filename| {
tauri::async_runtime::spawn(
api::utils::handle_command(filename),
);
})
.unwrap();
}
}

Expand Down
7 changes: 3 additions & 4 deletions packages/app-lib/src/event/emit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ pub async fn init_loading_unsafe(
let event_state = crate::EventState::get().await?;
let key = LoadingBarId(Uuid::new_v4());

event_state.loading_bars.write().await.insert(
event_state.loading_bars.insert(
key.0,
LoadingBar {
loading_bar_uuid: key.0,
Expand Down Expand Up @@ -121,7 +121,7 @@ pub async fn edit_loading(
) -> crate::Result<()> {
let event_state = crate::EventState::get().await?;

if let Some(bar) = event_state.loading_bars.write().await.get_mut(&id.0) {
if let Some(mut bar) = event_state.loading_bars.get_mut(&id.0) {
bar.bar_type = bar_type;
bar.total = total;
bar.message = title.to_string();
Expand Down Expand Up @@ -152,8 +152,7 @@ pub async fn emit_loading(
) -> crate::Result<()> {
let event_state = crate::EventState::get().await?;

let mut loading_bar = event_state.loading_bars.write().await;
let loading_bar = match loading_bar.get_mut(&key.0) {
let mut loading_bar = match event_state.loading_bars.get_mut(&key.0) {
Some(f) => f,
None => {
return Err(EventError::NoLoadingBar(key.0).into());
Expand Down
29 changes: 11 additions & 18 deletions packages/app-lib/src/event/mod.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Theseus state management system
use dashmap::DashMap;
use serde::{Deserialize, Serialize};
use std::{collections::HashMap, path::PathBuf, sync::Arc};
use std::{path::PathBuf, sync::Arc};
use tokio::sync::OnceCell;
use tokio::sync::RwLock;
use uuid::Uuid;

pub mod emit;
Expand All @@ -14,7 +14,7 @@ pub struct EventState {
/// Tauri app
#[cfg(feature = "tauri")]
pub app: tauri::AppHandle,
pub loading_bars: RwLock<HashMap<Uuid, LoadingBar>>,
pub loading_bars: DashMap<Uuid, LoadingBar>,
}

impl EventState {
Expand All @@ -24,7 +24,7 @@ impl EventState {
.get_or_try_init(|| async {
Ok(Arc::new(Self {
app,
loading_bars: RwLock::new(HashMap::new()),
loading_bars: DashMap::new(),
}))
})
.await
Expand All @@ -36,7 +36,7 @@ impl EventState {
EVENT_STATE
.get_or_try_init(|| async {
Ok(Arc::new(Self {
loading_bars: RwLock::new(HashMap::new()),
loading_bars: DashMap::new(),
}))
})
.await
Expand All @@ -55,17 +55,10 @@ impl EventState {
}

// Values provided should not be used directly, as they are clones and are not guaranteed to be up-to-date
pub async fn list_progress_bars() -> crate::Result<HashMap<Uuid, LoadingBar>>
pub async fn list_progress_bars() -> crate::Result<DashMap<Uuid, LoadingBar>>
{
let value = Self::get().await?;
let read = value.loading_bars.read().await;

let mut display_list: HashMap<Uuid, LoadingBar> = HashMap::new();
for (uuid, loading_bar) in read.iter() {
display_list.insert(*uuid, loading_bar.clone());
}

Ok(display_list)
Ok(value.loading_bars.clone())
}

#[cfg(feature = "tauri")]
Expand Down Expand Up @@ -100,10 +93,10 @@ impl Drop for LoadingBarId {
let loader_uuid = self.0;
tokio::spawn(async move {
if let Ok(event_state) = EventState::get().await {
let mut bars = event_state.loading_bars.write().await;

#[cfg(any(feature = "tauri", feature = "cli"))]
if let Some(bar) = bars.remove(&loader_uuid) {
if let Some((_, bar)) =
event_state.loading_bars.remove(&loader_uuid)
{
#[cfg(feature = "tauri")]
{
let loader_uuid = bar.loading_bar_uuid;
Expand Down Expand Up @@ -135,7 +128,7 @@ impl Drop for LoadingBarId {
}

#[cfg(not(any(feature = "tauri", feature = "cli")))]
bars.remove(&loader_uuid);
event_state.loading_bars.remove(&loader_uuid);
}
});
}
Expand Down

0 comments on commit e9268fa

Please sign in to comment.