Skip to content

Commit f3eca45

Browse files
committed
feat: add favorites feature for notifications
Add ability to mark notifications as favorites with a star icon. Includes database migration, backend commands, sidebar navigation, settings toggle, and dedicated favorites view. Bump version to 1.1.0.
1 parent 61ea6ed commit f3eca45

28 files changed

Lines changed: 616 additions & 210 deletions

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "ntfier",
3-
"version": "1.0.0",
3+
"version": "1.1.0",
44
"private": true,
55
"scripts": {
66
"dev": "tauri dev",

src-tauri/Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src-tauri/Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ntfier"
3-
version = "1.0.0"
3+
version = "1.1.0"
44
description = "Desktop notification client for ntfy"
55
authors = [""]
66
license = ""
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE notifications DROP COLUMN is_favorite;
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE notifications ADD COLUMN is_favorite INTEGER NOT NULL DEFAULT 0;

src-tauri/src/commands/notifications.rs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -98,6 +98,24 @@ pub async fn delete_notification(
9898
Ok(())
9999
}
100100

101+
#[tauri::command]
102+
#[specta::specta]
103+
pub fn set_notification_favorite(
104+
db: State<'_, Database>,
105+
id: String,
106+
favorite: bool,
107+
) -> Result<(), AppError> {
108+
db.set_notification_favorite(&id, favorite)
109+
}
110+
111+
#[tauri::command]
112+
#[specta::specta]
113+
pub fn get_favorite_notifications(
114+
db: State<'_, Database>,
115+
) -> Result<Vec<Notification>, AppError> {
116+
db.get_favorite_notifications()
117+
}
118+
101119
#[tauri::command]
102120
#[specta::specta]
103121
pub fn set_notification_expanded(

src-tauri/src/commands/settings.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,3 +132,9 @@ pub fn set_expand_new_messages(db: State<'_, Database>, enabled: bool) -> Result
132132
pub fn set_delete_local_only(db: State<'_, Database>, enabled: bool) -> Result<(), AppError> {
133133
db.set_setting("delete_local_only", if enabled { "true" } else { "false" })
134134
}
135+
136+
#[tauri::command]
137+
#[specta::specta]
138+
pub fn set_favorites_enabled(db: State<'_, Database>, enabled: bool) -> Result<(), AppError> {
139+
db.set_setting("favorites_enabled", if enabled { "true" } else { "false" })
140+
}

src-tauri/src/db/models.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ pub struct NotificationRow {
7979
pub actions: JsonActions,
8080
pub attachments: JsonAttachments,
8181
pub is_expanded: i32,
82+
pub is_favorite: i32,
8283
}
8384

8485
impl NotificationRow {
@@ -96,6 +97,7 @@ impl NotificationRow {
9697
attachments: self.attachments.into_inner(),
9798
read: self.read == 1,
9899
is_expanded: self.is_expanded == 1,
100+
is_favorite: self.is_favorite == 1,
99101
}
100102
}
101103
}
@@ -116,6 +118,7 @@ pub struct NewNotification<'a> {
116118
pub actions: JsonActions,
117119
pub attachments: JsonAttachments,
118120
pub is_expanded: i32,
121+
pub is_favorite: i32,
119122
}
120123

121124
// ===== Setting =====

src-tauri/src/db/queries/notifications.rs

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ impl Database {
6666
actions: JsonActions::new(notification.actions.clone()),
6767
attachments: JsonAttachments::new(notification.attachments.clone()),
6868
is_expanded: i32::from(notification.is_expanded),
69+
is_favorite: i32::from(notification.is_favorite),
6970
};
7071

7172
diesel::replace_into(notifications::table)
@@ -102,6 +103,7 @@ impl Database {
102103
actions: JsonActions::new(notification.actions.clone()),
103104
attachments: JsonAttachments::new(notification.attachments.clone()),
104105
is_expanded: i32::from(notification.is_expanded),
106+
is_favorite: i32::from(notification.is_favorite),
105107
};
106108

107109
diesel::insert_or_ignore_into(notifications::table)
@@ -135,6 +137,32 @@ impl Database {
135137
Ok(())
136138
}
137139

140+
/// Sets the favorite state of a notification.
141+
pub fn set_notification_favorite(&self, id: &str, favorite: bool) -> Result<(), AppError> {
142+
let mut conn = self.conn()?;
143+
144+
diesel::update(notifications::table.filter(notifications::id.eq(id)))
145+
.set(notifications::is_favorite.eq(i32::from(favorite)))
146+
.execute(&mut *conn)?;
147+
148+
Ok(())
149+
}
150+
151+
/// Gets all favorite notifications, ordered by timestamp descending.
152+
pub fn get_favorite_notifications(&self) -> Result<Vec<Notification>, AppError> {
153+
let mut conn = self.conn()?;
154+
155+
let rows: Vec<NotificationRow> = notifications::table
156+
.filter(notifications::is_favorite.eq(1))
157+
.order(notifications::timestamp.desc())
158+
.load(&mut *conn)?;
159+
160+
Ok(rows
161+
.into_iter()
162+
.map(NotificationRow::into_notification)
163+
.collect())
164+
}
165+
138166
/// Sets the expanded state of a notification.
139167
pub fn set_notification_expanded(&self, id: &str, expanded: bool) -> Result<(), AppError> {
140168
let mut conn = self.conn()?;

src-tauri/src/db/queries/settings.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -104,6 +104,9 @@ impl Database {
104104
// Deletion settings
105105
let delete_local_only = self.get_setting_bool("delete_local_only", true)?;
106106

107+
// Favorites settings
108+
let favorites_enabled = self.get_setting_bool("favorites_enabled", false)?;
109+
107110
let servers = self.get_servers_with_credentials()?;
108111
let default_server = self.get_default_server_url()?;
109112

@@ -121,6 +124,7 @@ impl Database {
121124
compact_view,
122125
expand_new_messages,
123126
delete_local_only,
127+
favorites_enabled,
124128
})
125129
}
126130

0 commit comments

Comments
 (0)