Skip to content

Commit

Permalink
feat: add option to autostart w operating system
Browse files Browse the repository at this point in the history
  • Loading branch information
Xstoudi committed Jul 19, 2023
1 parent b9d68e3 commit e9aef42
Show file tree
Hide file tree
Showing 14 changed files with 205 additions and 30 deletions.
19 changes: 19 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -37,11 +37,13 @@
"react-router-dom": "^6.13.0",
"react-use": "^17.4.0",
"sanitize-html": "^2.11.0",
"tauri-plugin-autostart-api": "github:tauri-apps/tauri-plugin-autostart#v1",
"tauri-plugin-sql-api": "github:tauri-apps/tauri-plugin-sql#v1"
},
"devDependencies": {
"@commitlint/cli": "^17.6.6",
"@commitlint/config-conventional": "^17.6.6",
"@simbathesailor/use-what-changed": "^2.0.0",
"@tauri-apps/cli": "^1.4.0",
"@types/node": "^18.7.10",
"@types/react": "^18.0.15",
Expand Down
47 changes: 46 additions & 1 deletion src-tauri/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 2 additions & 4 deletions src-tauri/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,8 @@ reqwest = { version = "0.11", features = ["blocking", "json"] }
chrono = "0.4.26"
feed-rs = "1.3.0"
tauri-plugin-window-state = "0.1.0"
[dependencies.tauri-plugin-sql]
git = "https://github.com/tauri-apps/plugins-workspace"
branch = "v1"
features = ["sqlite"]
tauri-plugin-autostart = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1" }
tauri-plugin-sql = { git = "https://github.com/tauri-apps/plugins-workspace", branch = "v1", features = ["sqlite"] }

[features]
# this feature is used for production builds or when `devPath` points to the filesystem
Expand Down
2 changes: 1 addition & 1 deletion src-tauri/src/commands/splashscreen.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use tauri::{Manager, Window};

#[tauri::command]
pub async fn close_spashscreen(window: Window) {
pub async fn close_splashscreen(window: Window) {
if let Some(splashscreen) = window.get_window("splashscreen") {
splashscreen.close().unwrap();
}
Expand Down
6 changes: 4 additions & 2 deletions src-tauri/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,9 @@ pub mod structs;
pub mod enums;

use commands::fetcher::{sync, sync_all};
use commands::splashscreen::close_spashscreen;
use commands::splashscreen::close_splashscreen;
use tauri::{generate_handler, generate_context, Manager, Builder, SystemTray, SystemTrayEvent, SystemTrayMenu, CustomMenuItem, AppHandle, Wry};
use tauri_plugin_autostart::MacosLauncher;

fn show_main_window(app: &AppHandle<Wry>) {
let window = app.get_window("main").unwrap();
Expand All @@ -32,7 +33,8 @@ fn main() {
Builder::default()
.plugin(tauri_plugin_window_state::Builder::default().build())
.plugin(tauri_plugin_sql::Builder::default().build())
.invoke_handler(generate_handler![sync, sync_all, close_spashscreen])
.plugin(tauri_plugin_autostart::init(MacosLauncher::LaunchAgent, None))
.invoke_handler(generate_handler![sync, sync_all, close_splashscreen])
.system_tray(system_tray)
.on_system_tray_event(|app, event| match event {
SystemTrayEvent::DoubleClick {
Expand Down
4 changes: 2 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import { PreferenceProvider } from './components/context/PreferenceContext';
import { ViewProvider } from './components/context/ViewContext';
import FooterBar from './components/layout/FooterBar';
import WindowBar from './components/layout/WindowBar';
import BackupManager from './components/utils/BackupManager';
import Clock from './components/utils/Clock';
import LoadManager from './components/utils/LoadManager';
import {
dataReducer,
initialDataState as defaultDataState,
Expand Down Expand Up @@ -45,7 +45,7 @@ function App() {
<ViewProvider value={viewState}>
<DispatchProvider value={dispatchers}>
<Clock />
<BackupManager />
<LoadManager />
<ThemeManager>
<div className="flex flex-col h-screen text-neutral-800 dark:text-zinc-400 overflow-hidden">
<WindowBar />
Expand Down
7 changes: 7 additions & 0 deletions src/components/modal/PreferenceModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ function PreferenceModal() {
darkMode: false,
showFeedIcons: false,
showArticleThumbnails: false,
autoStart: false,
}
: state,
[isStateEmpty, state],
Expand Down Expand Up @@ -93,6 +94,12 @@ function PreferenceModal() {
setForm({ ...form, showArticleThumbnails })
}
/>
<Switch
label="Launch at startup"
name="autoStart"
value={form.autoStart}
onChange={(autoStart) => setForm({ ...form, autoStart })}
/>

<div className={clsx('mt-4 flex justify-between flex-row-reverse')}>
<Form.Submit asChild>
Expand Down
40 changes: 40 additions & 0 deletions src/components/utils/AutostartManager.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import { memo, useEffect } from 'react';
import {
enable,
isEnabled as isEnabledFunction,
disable,
} from 'tauri-plugin-autostart-api';

import usePreference from '../../hooks/usePreference';

interface AutostartManagerProps {
loaded: boolean;
triggerLoaded: (state?: boolean) => void;
}

function AutostartManager({ loaded, triggerLoaded }: AutostartManagerProps) {
const preferenceState = usePreference();

useEffect(() => {
async function handleAutostart() {
const wantedAutostart = preferenceState.autoStart;
const currentAutostart = (await isEnabledFunction()) ?? false;

if (wantedAutostart && !currentAutostart) {
await enable();
}

if (!wantedAutostart && currentAutostart) {
await disable();
}
}

handleAutostart()
.catch((error) => console.error(error))
.finally(() => triggerLoaded(true));
}, [loaded, preferenceState.autoStart, triggerLoaded]);

return null;
}

export default memo(AutostartManager);
63 changes: 45 additions & 18 deletions src/components/utils/BackupManager.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { invoke } from '@tauri-apps/api';
import { memo, useEffect } from 'react';
import { memo, useEffect, useMemo } from 'react';

import { DataBackup, PreferenceBackup } from '../../data/Backup';
import * as Backup from '../../data/Backup';
Expand All @@ -9,15 +8,19 @@ import useData from '../../hooks/useData';
import useDataDispatch from '../../hooks/useDataDispatch';
import usePreference from '../../hooks/usePreference';
import usePreferenceDispatch from '../../hooks/usePreferenceDispatch';
import usePromise from '../../hooks/usePromise';
import useThrottle from '../../hooks/useThrottle';
import { LOAD } from '../../state/data/DataActionType';
import { SET_PREFERENCES } from '../../state/preference/PreferenceActionType';

const throttleTime = 2000;

let loaded = false;
interface BackupManagerProps {
loaded: boolean;
triggerLoaded: (state?: boolean) => void;
}

function BackupManager() {
function BackupManager({ loaded, triggerLoaded }: BackupManagerProps) {
const rawDataState = useData();
const dataDispatch = useDataDispatch();
const rawPreferenceState = usePreference();
Expand All @@ -36,7 +39,7 @@ function BackupManager() {
state: dataState,
};
save(backupStructure).catch((error) => console.error(error));
}, [dataState]);
}, [dataState, loaded]);

// save preference state
useEffect(() => {
Expand All @@ -48,36 +51,60 @@ function BackupManager() {
state: preferenceState,
};
save(backupStructure).catch((error) => console.error(error));
}, [preferenceState]);
}, [loaded, preferenceState]);

useEffect(() => {
Promise.all([
const dataPromise = useMemo(
() =>
loadData().then((backup) => {
if (backup !== null) {
dataDispatch({
type: LOAD,
payload: backup.state,
});
}
return backup;
}),
[dataDispatch],
);

const preferencePromise = useMemo(
() =>
loadPreference().then((backup) => {
if (backup !== null) {
preferenceDispatch({
type: SET_PREFERENCES,
payload: backup.state,
});
}
return backup;
}),
])
.then(() => {
loaded = true;
})
.then(() => invoke('close_spashscreen'))
.catch((error) => {
// TODO : error on loading backup, explode to not corrupt data
console.error(error);
});
}, [dataDispatch, preferenceDispatch]);
[preferenceDispatch],
);

const { loading: dataLoading, error: dataError } = usePromise(dataPromise);

const { loading: preferenceLoading, error: preferenceError } =
usePromise(preferencePromise);

useEffect(() => {
if (dataLoading || preferenceLoading) return;

if (dataError || preferenceError) {
// TODO : error on loading backup, explode to not corrupt data

Check warning on line 93 in src/components/utils/BackupManager.ts

View workflow job for this annotation

GitHub Actions / lint

Unexpected 'todo' comment: 'TODO : error on loading backup, explode...'
console.error(dataError);
console.error(preferenceError);
return;
}

triggerLoaded(true);
}, [
dataError,
dataLoading,
loaded,
preferenceError,
preferenceLoading,
triggerLoaded,
]);

return null;
}
Expand Down

0 comments on commit e9aef42

Please sign in to comment.