Auto-commit 2026-03-30 16:30

This commit is contained in:
2026-03-30 16:30:46 -04:00
parent 5fc7ed74c4
commit a6da9ef9cf
41 changed files with 3438 additions and 0 deletions

View File

@@ -0,0 +1,373 @@
/*
* notification-manager.vala
*
* Notification manager for RSSuper on Linux.
* Coordinates notifications, badge management, and tray integration.
*/
using Gio;
using GLib;
using Gtk;
namespace RSSuper {
/**
* NotificationManager - Manager for coordinating notifications
*/
public class NotificationManager : Object {
// Singleton instance
private static NotificationManager? _instance;
// Notification service
private NotificationService? _notification_service;
// Badge reference
private Gtk.Badge? _badge;
// Tray icon reference
private Gtk.TrayIcon? _tray_icon;
// App reference
private Gtk.App? _app;
// Current unread count
private int _unread_count = 0;
// Badge visibility
private bool _badge_visible = true;
/**
* Get singleton instance
*/
public static NotificationManager? get_instance() {
if (_instance == null) {
_instance = new NotificationManager();
}
return _instance;
}
/**
* Get the instance
*/
private NotificationManager() {
_notification_service = NotificationService.get_instance();
_app = Gtk.App.get_active();
}
/**
* Initialize the notification manager
*/
public void initialize() {
// Set up badge
_badge = Gtk.Badge.new();
_badge.set_visible(_badge_visible);
_badge.set_halign(Gtk.Align.START);
// Connect badge changed signal
_badge.changed.connect(_on_badge_changed);
// Set up tray icon
_tray_icon = Gtk.TrayIcon.new();
_tray_icon.set_icon_name("rssuper");
_tray_icon.set_tooltip_text("RSSuper - Press for notifications");
// Connect tray icon clicked signal
_tray_icon.clicked.connect(_on_tray_clicked);
// Set up tray icon popup menu
var popup = new PopupMenu();
popup.add_item(new Gtk.Label("Notifications: " + _unread_count.toString()));
popup.add_item(new Gtk.Separator());
popup.add_item(new Gtk.Label("Mark all as read"));
popup.add_item(new Gtk.Separator());
popup.add_item(new Gtk.Label("Settings"));
popup.add_item(new Gtk.Label("Exit"));
popup.connect_closed(_on_tray_closed);
_tray_icon.set_popup(popup);
// Connect tray icon popup menu signal
popup.menu_closed.connect(_on_tray_popup_closed);
// Set up tray icon popup handler
_tray_icon.set_popup_handler(_on_tray_popup);
// Set up tray icon tooltip
_tray_icon.set_tooltip_text("RSSuper - Press for notifications");
}
/**
* Set up the badge in the app header
*/
public void set_up_badge() {
_badge.set_visible(_badge_visible);
_badge.set_halign(Gtk.Align.START);
// Set up badge changed signal
_badge.changed.connect(_on_badge_changed);
}
/**
* Set up the tray icon
*/
public void set_up_tray_icon() {
_tray_icon.set_icon_name("rssuper");
_tray_icon.set_tooltip_text("RSSuper - Press for notifications");
// Connect tray icon clicked signal
_tray_icon.clicked.connect(_on_tray_clicked);
// Set up tray icon popup menu
var popup = new PopupMenu();
popup.add_item(new Gtk.Label("Notifications: " + _unread_count.toString()));
popup.add_item(new Gtk.Separator());
popup.add_item(new Gtk.Label("Mark all as read"));
popup.add_item(new Gtk.Separator());
popup.add_item(new Gtk.Label("Settings"));
popup.add_item(new Gtk.Label("Exit"));
popup.connect_closed(_on_tray_closed);
_tray_icon.set_popup(popup);
// Connect tray icon popup menu signal
popup.menu_closed.connect(_on_tray_popup_closed);
// Set up tray icon popup handler
_tray_icon.set_popup_handler(_on_tray_popup);
// Set up tray icon tooltip
_tray_icon.set_tooltip_text("RSSuper - Press for notifications");
}
/**
* Show badge
*/
public void show_badge() {
_badge.set_visible(_badge_visible);
}
/**
* Hide badge
*/
public void hide_badge() {
_badge.set_visible(false);
}
/**
* Show badge with count
*/
public void show_badge_with_count(int count) {
_badge.set_visible(_badge_visible);
_badge.set_label(count.toString());
}
/**
* Set unread count
*/
public void set_unread_count(int count) {
_unread_count = count;
// Update badge
if (_badge != null) {
_badge.set_label(count.toString());
}
// Update tray icon popup
if (_tray_icon != null) {
var popup = _tray_icon.get_popup();
if (popup != null) {
popup.set_label("Notifications: " + count.toString());
}
}
// Show badge if count > 0
if (count > 0) {
show_badge();
}
}
/**
* Clear unread count
*/
public void clear_unread_count() {
_unread_count = 0;
hide_badge();
// Update tray icon popup
if (_tray_icon != null) {
var popup = _tray_icon.get_popup();
if (popup != null) {
popup.set_label("Notifications: 0");
}
}
}
/**
* Get unread count
*/
public int get_unread_count() {
return _unread_count;
}
/**
* Get badge reference
*/
public Gtk.Badge? get_badge() {
return _badge;
}
/**
* Get tray icon reference
*/
public Gtk.TrayIcon? get_tray_icon() {
return _tray_icon;
}
/**
* Get app reference
*/
public Gtk.App? get_app() {
return _app;
}
/**
* Check if badge should be visible
*/
public bool should_show_badge() {
return _unread_count > 0 && _badge_visible;
}
/**
* Set badge visibility
*/
public void set_badge_visibility(bool visible) {
_badge_visible = visible;
if (_badge != null) {
_badge.set_visible(visible);
}
}
/**
* Show notification with badge
*/
public void show_with_badge(string title, string body,
string icon = null,
Urgency urgency = Urgency.NORMAL) {
var notification = _notification_service.create(title, body, icon, urgency);
notification.show_with_timeout(5000);
// Show badge
if (_unread_count == 0) {
show_badge_with_count(1);
}
}
/**
* Show notification without badge
*/
public void show_without_badge(string title, string body,
string icon = null,
Urgency urgency = Urgency.NORMAL) {
var notification = _notification_service.create(title, body, icon, urgency);
notification.show_with_timeout(5000);
}
/**
* Show critical notification
*/
public void show_critical(string title, string body,
string icon = null) {
show_with_badge(title, body, icon, Urgency.CRITICAL);
}
/**
* Show low priority notification
*/
public void show_low(string title, string body,
string icon = null) {
show_with_badge(title, body, icon, Urgency.LOW);
}
/**
* Show normal notification
*/
public void show_normal(string title, string body,
string icon = null) {
show_with_badge(title, body, icon, Urgency.NORMAL);
}
/**
* Handle badge changed signal
*/
private void _on_badge_changed(Gtk.Badge badge) {
var count = badge.get_label();
if (!string.IsNullOrEmpty(count)) {
_unread_count = int.Parse(count);
}
}
/**
* Handle tray icon clicked signal
*/
private void _on_tray_clicked(Gtk.TrayIcon tray) {
show_notifications_panel();
}
/**
* Handle tray icon popup closed signal
*/
private void _on_tray_popup_closed(Gtk.Popup popup) {
// Popup closed, hide icon
if (_tray_icon != null) {
_tray_icon.hide();
}
}
/**
* Handle tray icon popup open signal
*/
private void _on_tray_popup(Gtk.TrayIcon tray, Gtk.MenuItem menu) {
// Show icon when popup is opened
if (_tray_icon != null) {
_tray_icon.show();
}
}
/**
* Handle tray icon closed signal
*/
private void _on_tray_closed(Gtk.App app) {
// App closed, hide tray icon
if (_tray_icon != null) {
_tray_icon.hide();
}
}
/**
* Show notifications panel
*/
private void show_notifications_panel() {
// TODO: Show notifications panel
print("Notifications panel requested");
}
/**
* Get notification service
*/
public NotificationService? get_notification_service() {
return _notification_service;
}
/**
* Check if notification manager is available
*/
public bool is_available() {
return _notification_service != null && _notification_service.is_available();
}
}
}