feat: add menu action to navigate to project settings page; introduces the notion of 'current project'; the app now starts with the last current project

This commit is contained in:
Kiril Videlov 2023-11-22 18:45:34 +01:00 committed by Kiril Videlov
parent 2cefd8493c
commit db46907fb0
8 changed files with 99 additions and 0 deletions

View File

@ -27,7 +27,13 @@ fn main() {
let tray_menu = tauri::SystemTrayMenu::new().add_item(hide).add_item(quit);
let tray = tauri::SystemTray::new().with_menu(tray_menu);
let project_settings = tauri::CustomMenuItem::new("projectSettings".to_string(), "Project Settings");
let project_submenu = tauri::Submenu::new("Project", tauri::Menu::new().add_item(project_settings.disabled()));
let menu = tauri::Menu::os_default(&app_title)
.add_submenu(project_submenu);
tauri::Builder::default()
.menu(menu)
.system_tray(tray)
.on_system_tray_event(|app_handle, event| {
if let tauri::SystemTrayEvent::MenuItemClick { id, .. } = event {
@ -62,6 +68,11 @@ fn main() {
api.prevent_close();
}
})
.on_menu_event(move |event| {
if event.menu_item_id() == "projectSettings" {
_ = event.window().emit("menuAction", Some("projectSettings"));
}
})
.setup(move |tauri_app| {
let window =
create_window(&tauri_app.handle()).expect("Failed to create window");
@ -157,6 +168,8 @@ fn main() {
users::commands::set_user,
users::commands::delete_user,
users::commands::get_user,
users::commands::get_current_project,
users::commands::set_current_project,
projects::commands::add_project,
projects::commands::get_project,
projects::commands::update_project,

View File

@ -55,6 +55,54 @@ pub async fn set_user(handle: AppHandle, user: User) -> Result<User, Error> {
Ok(proxy.proxy_user(user).await)
}
#[tauri::command(async)]
#[instrument(skip(handle))]
pub async fn set_current_project(
handle: tauri::AppHandle,
project_id: Option<&str>,
) -> Result<(), Error> {
let app = handle.state::<Controller>();
match app.get_user()? {
Some(user) => {
let mut user = user;
match project_id {
Some(project_id) => {
user.current_project = Some(project_id.to_string());
}
None => {
user.current_project = None;
}
}
app.set_user(&user)?;
if let Some(win) = handle.get_window("main") {
let menu_handle = win.menu_handle();
_ = menu_handle
.get_item("projectsettings")
.set_enabled(project_id.is_some());
}
Ok(())
}
None => Err({
tracing::error!("failed to get user");
Error::Unknown
}),
}
}
#[tauri::command(async)]
#[instrument(skip(handle))]
pub async fn get_current_project(handle: tauri::AppHandle) -> Result<Option<String>, Error> {
let app = handle.state::<Controller>();
match app.get_user()? {
Some(user) => Ok(user.current_project),
None => Err({
tracing::error!("failed to get user");
Error::Unknown
}),
}
}
impl From<controller::DeleteError> for Error {
fn from(value: controller::DeleteError) -> Self {
match value {

View File

@ -17,6 +17,8 @@ pub struct User {
pub github_access_token: Option<String>,
#[serde(default)]
pub github_username: Option<String>,
#[serde(default)]
pub current_project: Option<String>,
}
impl TryFrom<User> for git::Signature<'_> {

View File

@ -2,6 +2,8 @@ import { handleErrorWithSentry, init } from '@sentry/sveltekit';
import type { NavigationEvent } from '@sveltejs/kit';
import { dev } from '$app/environment';
import { PUBLIC_SENTRY_ENVIRONMENT } from '$env/static/public';
import { goto } from '$app/navigation';
import { getCurrentProject } from '$lib/backend/users';
init({
enabled: !dev,
@ -28,3 +30,10 @@ window.onunhandledrejection = (event: PromiseRejectionEvent) => {
console.log('Unhandled exception', event.reason);
originalUnhandledHandler?.bind(window)(event);
};
// getCurrentProject().then((projectId) => {
// // Start on the last used project
// if (projectId) {
// goto(`/${projectId}/base`);
// }
// });

View File

@ -0,0 +1,10 @@
import { listen } from '$lib/backend/ipc';
import { goto } from '$app/navigation';
export function handleMenuActions(projectId: string) {
return listen<string>(`menuAction`, (event) => {
if (event.payload === 'projectSettings') {
goto(`/${projectId}/settings`);
}
});
}

View File

@ -9,5 +9,13 @@ export async function set(params: { user: User }) {
return invoke<User>('set_user', params);
}
export async function setCurrentProject(params: { projectId: string | undefined }) {
return invoke<void>('set_current_project', params);
}
export async function getCurrentProject() {
return invoke<string | undefined>('get_current_project');
}
const del = () => invoke<void>('delete_user');
export { del as delete };

View File

@ -15,6 +15,8 @@
import ShareIssueModal from './ShareIssueModal.svelte';
import { SETTINGS_CONTEXT, loadUserSettings } from '$lib/settings/userSettings';
import { initTheme } from './user/theme';
import { navigating } from '$app/stores';
import { setCurrentProject } from '$lib/backend/users';
export let data: LayoutData;
const { projectService, cloud, user$ } = data;
@ -29,6 +31,11 @@
$: zoom = $userSettings.zoom || 1;
$: document.documentElement.style.fontSize = zoom + 'rem';
$: userSettings.update((s) => ({ ...s, zoom: zoom }));
$: if ($navigating) {
// Keeps the backend aware of what is the current project
let projectId = $navigating?.to?.params?.projectId;
setCurrentProject({ projectId });
}
onMount(() =>
unsubscribe(

View File

@ -14,6 +14,7 @@
import Link from '$lib/components/Link.svelte';
import Button from '$lib/components/Button.svelte';
import { syncToCloud } from '$lib/backend/cloud';
import { handleMenuActions } from '$lib/backend/menu_actions';
export let data: LayoutData;
@ -36,6 +37,7 @@
const userSettings = getContext<SettingsStore>(SETTINGS_CONTEXT);
let trayViewport: HTMLElement;
handleMenuActions(data.projectId);
onMount(() => {
return unsubscribe(hotkeys.on('Meta+Shift+S', () => syncToCloud($project$?.id)));