Skip to content

Commit 87edc63

Browse files
committed
feat: notification settings toggle
1 parent eaa4f39 commit 87edc63

File tree

10 files changed

+106
-11
lines changed

10 files changed

+106
-11
lines changed

apps/desktop/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@
3939
"@tauri-apps/plugin-shell": ">=2.0.0-rc.0",
4040
"@tauri-apps/plugin-store": "2.1.0",
4141
"@tauri-apps/plugin-updater": "2.0.0-rc.0",
42+
"@tauri-apps/plugin-notification": "2.0.0-rc.0",
4243
"@types/react-tooltip": "^4.2.4",
4344
"cva": "npm:class-variance-authority@^0.7.0",
4445
"effect": "^3.7.2",

apps/desktop/src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ tauri-plugin-process = "2.0.0"
3030
tauri-plugin-decorum = "1.0.0"
3131
tauri-plugin-dialog = "2.0.0"
3232
tauri-plugin-updater = "2.0.0"
33-
tauri-plugin-notification = "2.0.0"
33+
tauri-plugin-notification = "2.0.0-rc"
3434
tauri-plugin-oauth = { git = "https://github.com/FabianLars/tauri-plugin-oauth", branch = "v2" }
3535
tauri-plugin-global-shortcut = "2.0.0"
3636
tauri-specta = { version = "=2.0.0-rc.20", features = ["derive", "typescript"] }

apps/desktop/src-tauri/capabilities/default.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
"process:default",
2929
"oauth:allow-start",
3030
"updater:default",
31+
"notification:default",
3132
{
3233
"identifier": "http:default",
3334
"allow": [{ "url": "https://cap.so" }]

apps/desktop/src-tauri/src/general_settings.rs

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,12 @@ pub struct GeneralSettingsStore {
1313
pub hide_dock_icon: bool,
1414
#[serde(default)]
1515
pub auto_create_shareable_link: bool,
16-
#[serde(default)]
17-
pub enable_tooltip_notifications: bool, // New field
16+
#[serde(default = "default_enable_notifications")]
17+
pub enable_notifications: bool,
18+
}
19+
20+
fn default_enable_notifications() -> bool {
21+
true
1822
}
1923

2024
impl GeneralSettingsStore {

apps/desktop/src-tauri/src/lib.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ use std::{
5555
};
5656
use tauri::{AppHandle, Manager, Runtime, State, WindowEvent};
5757
use tauri_nspanel::ManagerExt;
58-
use tauri_plugin_notification::NotificationExt;
58+
use tauri_plugin_notification::{NotificationExt, PermissionState};
5959
use tauri_plugin_shell::ShellExt;
6060
use tauri_specta::Event;
6161
use tokio::task;
@@ -2334,6 +2334,36 @@ async fn seek_to(app: AppHandle, video_id: String, frame_number: u32) {
23342334
.await;
23352335
}
23362336

2337+
async fn check_notification_permissions(app: &AppHandle) {
2338+
// Check if we've already requested permissions
2339+
if let Ok(Some(settings)) = GeneralSettingsStore::get(app) {
2340+
if settings.enable_notifications {
2341+
match app.notification().permission_state() {
2342+
Ok(state) if state != PermissionState::Granted => {
2343+
println!("Requesting notification permission");
2344+
match app.notification().request_permission() {
2345+
Ok(PermissionState::Granted) => {
2346+
println!("Notification permission granted");
2347+
}
2348+
Ok(_) | Err(_) => {
2349+
if let Ok(Some(mut s)) = GeneralSettingsStore::get(app) {
2350+
s.enable_notifications = false;
2351+
GeneralSettingsStore::set(app, s).ok();
2352+
}
2353+
}
2354+
}
2355+
}
2356+
Ok(_) => {
2357+
println!("Notification permission already granted");
2358+
}
2359+
Err(e) => {
2360+
eprintln!("Error checking notification permission state: {}", e);
2361+
}
2362+
}
2363+
}
2364+
}
2365+
}
2366+
23372367
#[cfg_attr(mobile, tauri::mobile_entry_point)]
23382368
pub async fn run() {
23392369
let specta_builder = tauri_specta::Builder::new()
@@ -2373,7 +2403,6 @@ pub async fn run() {
23732403
open_main_window,
23742404
permissions::open_permission_settings,
23752405
permissions::do_permissions_check,
2376-
permissions::request_permission,
23772406
upload_rendered_video,
23782407
upload_screenshot,
23792408
get_recording_meta,
@@ -2452,6 +2481,13 @@ pub async fn run() {
24522481

24532482
let app_handle = app.handle().clone();
24542483

2484+
// Add this line to check notification permissions on startup
2485+
// Fix: Clone the app_handle and move it into the spawned task
2486+
let notification_handle = app_handle.clone();
2487+
tauri::async_runtime::spawn(async move {
2488+
check_notification_permissions(&notification_handle).await;
2489+
});
2490+
24552491
if permissions::do_permissions_check(true).necessary_granted() {
24562492
open_main_window(app_handle.clone());
24572493
} else {

apps/desktop/src-tauri/src/notifications.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::{AppSounds, NewNotification};
1+
use crate::{general_settings::GeneralSettingsStore, AppSounds, NewNotification};
22
use tauri_plugin_notification::NotificationExt;
33
use tauri_specta::Event;
44

@@ -83,6 +83,15 @@ impl NotificationType {
8383
}
8484

8585
pub fn send_notification(app: &tauri::AppHandle, notification_type: NotificationType) {
86+
// Check if notifications are enabled in settings
87+
let enable_notifications = GeneralSettingsStore::get(app)
88+
.map(|settings| settings.map_or(false, |s| s.enable_notifications))
89+
.unwrap_or(false);
90+
91+
if !enable_notifications {
92+
return;
93+
}
94+
8695
let (title, body, is_error) = notification_type.details();
8796

8897
app.notification()

apps/desktop/src-tauri/src/web_api.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use tauri_specta::Event;
55
use crate::auth::{AuthStore, AuthenticationInvalid};
66

77
pub fn make_url(pathname: impl AsRef<str>) -> String {
8-
let server_url_base = "http://localhost:3000"; //dotenvy_macro::dotenv!("NEXT_PUBLIC_URL");
8+
let server_url_base = dotenvy_macro::dotenv!("NEXT_PUBLIC_URL");
99
format!("{server_url_base}{}", pathname.as_ref())
1010
}
1111

apps/desktop/src/routes/(window-chrome)/settings/general.tsx

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@ import { createResource, Show, For } from "solid-js";
22
import { createStore } from "solid-js/store";
33
import { generalSettingsStore } from "~/store";
44
import { commands, type GeneralSettingsStore } from "~/utils/tauri";
5+
import {
6+
isPermissionGranted,
7+
requestPermission,
8+
} from "@tauri-apps/plugin-notification";
59

610
const settingsList = [
711
{
@@ -28,6 +32,13 @@ const settingsList = [
2832
description:
2933
"When enabled, a shareable link will be created automatically after stopping the recording. You'll be redirected to the URL while the upload continues in the background.",
3034
},
35+
{
36+
key: "enable_notifications",
37+
label: "Enable System Notifications",
38+
description:
39+
"Show system notifications for events like copying to clipboard, saving files, and more.",
40+
requiresPermission: true,
41+
},
3142
];
3243

3344
export default function GeneralSettings() {
@@ -51,10 +62,36 @@ function Inner(props: { store: GeneralSettingsStore | null }) {
5162
props.store ?? {
5263
upload_individual_files: false,
5364
open_editor_after_recording: false,
65+
hide_dock_icon: false,
66+
auto_create_shareable_link: false,
67+
enable_notifications: true,
5468
}
5569
);
5670

5771
const handleChange = async (key: string, value: boolean) => {
72+
console.log(`Handling settings change for ${key}: ${value}`);
73+
// Special handling for notifications permission
74+
if (key === "enable_notifications") {
75+
if (value) {
76+
// Check current permission state
77+
console.log("Checking notification permission status");
78+
const permissionGranted = await isPermissionGranted();
79+
console.log(`Current permission status: ${permissionGranted}`);
80+
81+
if (!permissionGranted) {
82+
// Request permission if not granted
83+
console.log("Permission not granted, requesting permission");
84+
const permission = await requestPermission();
85+
console.log(`Permission request result: ${permission}`);
86+
if (permission !== "granted") {
87+
// If permission denied, don't enable the setting
88+
console.log("Permission denied, aborting setting change");
89+
return;
90+
}
91+
}
92+
}
93+
}
94+
5895
setSettings(key as keyof GeneralSettingsStore, value);
5996
await commands.setGeneralSettings({
6097
...settings,

apps/desktop/src/utils/tauri.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,9 +197,6 @@ async openPermissionSettings(permission: OSPermission) : Promise<void> {
197197
async doPermissionsCheck(initialCheck: boolean) : Promise<OSPermissionsCheck> {
198198
return await TAURI_INVOKE("do_permissions_check", { initialCheck });
199199
},
200-
async requestPermission(permission: OSPermission) : Promise<void> {
201-
await TAURI_INVOKE("request_permission", { permission });
202-
},
203200
async uploadRenderedVideo(videoId: string, project: ProjectConfiguration, preCreatedVideo: PreCreatedVideo | null) : Promise<Result<UploadResult, string>> {
204201
try {
205202
return { status: "ok", data: await TAURI_INVOKE("upload_rendered_video", { videoId, project, preCreatedVideo }) };
@@ -389,7 +386,7 @@ export type CursorType = "pointer" | "circle"
389386
export type Display = { path: string }
390387
export type EditorStateChanged = { playhead_position: number }
391388
export type Flags = { recordMouse: boolean; split: boolean; pauseResume: boolean; zoom: boolean }
392-
export type GeneralSettingsStore = { upload_individual_files: boolean; open_editor_after_recording: boolean; hide_dock_icon?: boolean; auto_create_shareable_link?: boolean; enable_tooltip_notifications?: boolean }
389+
export type GeneralSettingsStore = { upload_individual_files: boolean; open_editor_after_recording: boolean; hide_dock_icon?: boolean; auto_create_shareable_link?: boolean; enable_notifications?: boolean }
393390
export type Hotkey = { code: string; meta: boolean; ctrl: boolean; alt: boolean; shift: boolean }
394391
export type HotkeyAction = "startRecording" | "stopRecording" | "restartRecording" | "takeScreenshot"
395392
export type HotkeysConfiguration = { show: boolean }

pnpm-lock.yaml

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)