sync pause state
This commit is contained in:
@@ -1,7 +1,7 @@
|
|||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use tokio::time::{interval, Duration};
|
use tokio::time::{interval, Duration};
|
||||||
use tauri::{AppHandle, Manager};
|
use tauri::{AppHandle, Manager, Emitter};
|
||||||
use xcap::Monitor;
|
use xcap::Monitor;
|
||||||
use chrono::Local;
|
use chrono::Local;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
@@ -10,13 +10,25 @@ use tauri_plugin_store::StoreExt;
|
|||||||
|
|
||||||
pub struct AppState {
|
pub struct AppState {
|
||||||
pub is_paused: Arc<AtomicBool>,
|
pub is_paused: Arc<AtomicBool>,
|
||||||
|
pub toggle_menu_item: std::sync::Mutex<Option<tauri::menu::MenuItem<tauri::Wry>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub fn toggle_pause(state: tauri::State<'_, AppState>) -> bool {
|
pub fn toggle_pause(app: tauri::AppHandle, state: tauri::State<'_, AppState>) -> bool {
|
||||||
let current = state.is_paused.load(Ordering::SeqCst);
|
let current = state.is_paused.load(Ordering::SeqCst);
|
||||||
state.is_paused.store(!current, Ordering::SeqCst);
|
let new_state = !current;
|
||||||
!current
|
state.is_paused.store(new_state, Ordering::SeqCst);
|
||||||
|
|
||||||
|
// Sync with Tray
|
||||||
|
if let Some(item) = state.toggle_menu_item.lock().unwrap().as_ref() {
|
||||||
|
let text = if new_state { "恢复记录" } else { "暂停记录" };
|
||||||
|
let _ = item.set_text(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Notify Frontend
|
||||||
|
let _ = app.emit("pause-state-changed", new_state);
|
||||||
|
|
||||||
|
new_state
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ pub fn run() {
|
|||||||
.setup(|app| {
|
.setup(|app| {
|
||||||
app.manage(engine::AppState {
|
app.manage(engine::AppState {
|
||||||
is_paused: Arc::new(AtomicBool::new(false)),
|
is_paused: Arc::new(AtomicBool::new(false)),
|
||||||
|
toggle_menu_item: std::sync::Mutex::new(None),
|
||||||
});
|
});
|
||||||
tray::create_tray(app.handle())?;
|
tray::create_tray(app.handle())?;
|
||||||
engine::start_engine(app.handle().clone());
|
engine::start_engine(app.handle().clone());
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use tauri::{
|
use tauri::{
|
||||||
menu::{Menu, MenuItem},
|
menu::{Menu, MenuItem},
|
||||||
tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent},
|
tray::{MouseButton, MouseButtonState, TrayIconBuilder, TrayIconEvent},
|
||||||
AppHandle, Manager,
|
AppHandle, Manager, Emitter,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub fn create_tray(app: &AppHandle) -> tauri::Result<()> {
|
pub fn create_tray(app: &AppHandle) -> tauri::Result<()> {
|
||||||
@@ -11,7 +11,9 @@ pub fn create_tray(app: &AppHandle) -> tauri::Result<()> {
|
|||||||
|
|
||||||
let menu = Menu::with_items(app, &[&open_i, &toggle_i, &quit_i])?;
|
let menu = Menu::with_items(app, &[&open_i, &toggle_i, &quit_i])?;
|
||||||
|
|
||||||
let toggle_i_clone = toggle_i.clone();
|
// Store the toggle item in state for future updates
|
||||||
|
let state = app.state::<crate::engine::AppState>();
|
||||||
|
*state.toggle_menu_item.lock().unwrap() = Some(toggle_i.clone());
|
||||||
|
|
||||||
TrayIconBuilder::with_id("main_tray")
|
TrayIconBuilder::with_id("main_tray")
|
||||||
.tooltip("Chrono Snap")
|
.tooltip("Chrono Snap")
|
||||||
@@ -31,8 +33,13 @@ pub fn create_tray(app: &AppHandle) -> tauri::Result<()> {
|
|||||||
let new_state = !current;
|
let new_state = !current;
|
||||||
state.is_paused.store(new_state, std::sync::atomic::Ordering::SeqCst);
|
state.is_paused.store(new_state, std::sync::atomic::Ordering::SeqCst);
|
||||||
|
|
||||||
|
// Update menu text
|
||||||
|
if let Some(item) = state.toggle_menu_item.lock().unwrap().as_ref() {
|
||||||
let text = if new_state { "恢复记录" } else { "暂停记录" };
|
let text = if new_state { "恢复记录" } else { "暂停记录" };
|
||||||
let _ = toggle_i_clone.set_text(text);
|
let _ = item.set_text(text);
|
||||||
|
}
|
||||||
|
|
||||||
|
let _ = app.emit("pause-state-changed", new_state);
|
||||||
}
|
}
|
||||||
"quit" => {
|
"quit" => {
|
||||||
app.exit(0);
|
app.exit(0);
|
||||||
|
|||||||
12
src/App.vue
12
src/App.vue
@@ -2,7 +2,8 @@
|
|||||||
import { ref, onMounted } from "vue";
|
import { ref, onMounted } from "vue";
|
||||||
import { load } from "@tauri-apps/plugin-store";
|
import { load } from "@tauri-apps/plugin-store";
|
||||||
import { open } from "@tauri-apps/plugin-dialog";
|
import { open } from "@tauri-apps/plugin-dialog";
|
||||||
import { convertFileSrc, invoke } from "@tauri-apps/api/core";
|
import { invoke } from "@tauri-apps/api/core";
|
||||||
|
import { listen } from "@tauri-apps/api/event";
|
||||||
import { FolderOpen, Settings, Play, Pause, Maximize2, X } from "lucide-vue-next";
|
import { FolderOpen, Settings, Play, Pause, Maximize2, X } from "lucide-vue-next";
|
||||||
|
|
||||||
const isSetupComplete = ref(false);
|
const isSetupComplete = ref(false);
|
||||||
@@ -31,6 +32,11 @@ onMounted(async () => {
|
|||||||
isPaused.value = await invoke("get_pause_state");
|
isPaused.value = await invoke("get_pause_state");
|
||||||
await loadTimeline();
|
await loadTimeline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Listen for backend pause state changes (e.g. from tray)
|
||||||
|
await listen<boolean>("pause-state-changed", (event) => {
|
||||||
|
isPaused.value = event.payload;
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
const selectFolder = async () => {
|
const selectFolder = async () => {
|
||||||
@@ -79,10 +85,6 @@ const selectImage = async (img: { time: string; path: string }) => {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const getSrc = (path: string) => {
|
|
||||||
return convertFileSrc(path);
|
|
||||||
};
|
|
||||||
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
|
|||||||
Reference in New Issue
Block a user