Quality of life notification enhancement
This commit is contained in:
88
gui.py
88
gui.py
@@ -23,8 +23,8 @@ def normalize_file_path(path_str: str) -> str:
|
||||
else:
|
||||
path_str = urllib.parse.unquote(path_str[7:])
|
||||
return os.path.abspath(path_str)
|
||||
from PySide6.QtCore import Qt, QThread, QObject, Signal, QUrl, QFile, QIODevice
|
||||
from PySide6.QtGui import QIcon, QAction, QPixmap, QPainter, QColor, QFont, QPen, QImage, QDesktopServices
|
||||
from PySide6.QtCore import Qt, QThread, QObject, Signal, QUrl, QFile, QIODevice, QTimer, QMimeData
|
||||
from PySide6.QtGui import QIcon, QAction, QPixmap, QPainter, QColor, QFont, QPen, QImage, QDesktopServices, QDrag
|
||||
from PySide6.QtNetwork import QNetworkAccessManager, QNetworkRequest, QHttpMultiPart, QHttpPart, QNetworkReply, QLocalServer, QLocalSocket
|
||||
from PySide6.QtWidgets import (
|
||||
QApplication, QSystemTrayIcon, QMenu, QDialog, QVBoxLayout, QHBoxLayout,
|
||||
@@ -533,6 +533,39 @@ class SettingsDialog(QDialog):
|
||||
else:
|
||||
QMessageBox.critical(self, "Error", "Failed to save configuration file.")
|
||||
|
||||
# ==========================================
|
||||
# Draggable File Label Widget
|
||||
# ==========================================
|
||||
class DraggableImageLabel(QLabel):
|
||||
def __init__(self, file_path, parent=None):
|
||||
super().__init__(parent)
|
||||
self.file_path = file_path
|
||||
self.drag_start_pos = None
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
if event.button() == Qt.MouseButton.LeftButton:
|
||||
self.drag_start_pos = event.pos()
|
||||
super().mousePressEvent(event)
|
||||
|
||||
def mouseMoveEvent(self, event):
|
||||
if not (event.buttons() & Qt.MouseButton.LeftButton):
|
||||
return
|
||||
if self.drag_start_pos is None:
|
||||
return
|
||||
if (event.pos() - self.drag_start_pos).manhattanLength() < QApplication.startDragDistance():
|
||||
return
|
||||
|
||||
if self.file_path and os.path.exists(self.file_path):
|
||||
drag = QDrag(self)
|
||||
mime_data = QMimeData()
|
||||
mime_data.setUrls([QUrl.fromLocalFile(self.file_path)])
|
||||
drag.setMimeData(mime_data)
|
||||
|
||||
if self.pixmap() and not self.pixmap().isNull():
|
||||
drag.setPixmap(self.pixmap().scaled(80, 80, Qt.AspectRatioMode.KeepAspectRatio, Qt.TransformationMode.SmoothTransformation))
|
||||
|
||||
drag.exec(Qt.DropAction.CopyAction)
|
||||
|
||||
# ==========================================
|
||||
# Upload Gallery Window & Components
|
||||
# ==========================================
|
||||
@@ -559,10 +592,13 @@ class GalleryCard(QFrame):
|
||||
layout.setContentsMargins(8, 8, 8, 8)
|
||||
layout.setSpacing(6)
|
||||
|
||||
# Thumbnail
|
||||
self.thumb_label = QLabel()
|
||||
# Thumbnail with Drag & Drop support
|
||||
file_path = item.get("file_path", "")
|
||||
self.thumb_label = DraggableImageLabel(file_path)
|
||||
self.thumb_label.setFixedSize(160, 100)
|
||||
self.thumb_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
||||
self.thumb_label.setCursor(Qt.CursorShape.OpenHandCursor)
|
||||
self.thumb_label.setToolTip("Click & Drag to drop file into other apps")
|
||||
self.thumb_label.setStyleSheet("background-color: #121216; border-radius: 4px;")
|
||||
|
||||
thumb_path = item.get("thumbnail_path", "")
|
||||
@@ -1238,14 +1274,48 @@ class SystemTrayApp(QObject):
|
||||
if not config.get("enable_notifications", True):
|
||||
return
|
||||
|
||||
thumb_path = generate_thumbnail(file_path)
|
||||
if thumb_path and os.path.exists(thumb_path):
|
||||
body_text = f'<div><a href="{item_url}"><img src="file://{thumb_path}" height="80" style="height:80px; max-width:100%; object-fit:cover;" /></a></div><br/><br/><a href="{item_url}">{item_url}</a>'
|
||||
abs_path = os.path.abspath(file_path)
|
||||
ext = os.path.splitext(abs_path)[1].lower()
|
||||
if ext in [".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp", ".avif"]:
|
||||
img_path = abs_path
|
||||
else:
|
||||
body_text = f'Upload Successful: <a href="{item_url}">{item_url}</a>'
|
||||
img_path = generate_thumbnail(abs_path) or abs_path
|
||||
|
||||
file_url = "file://" + abs_path
|
||||
|
||||
body_text = f'<a href="{item_url}">{item_url}</a>'
|
||||
|
||||
# Direct DBus Notification for Spectacle-style centered image preview & file drag-and-drop
|
||||
try:
|
||||
subprocess.run(["notify-send", "-a", "f0ckm", "Upload Successful", body_text], check=False)
|
||||
import dbus
|
||||
bus = dbus.SessionBus()
|
||||
notify_obj = bus.get_object('org.freedesktop.Notifications', '/org/freedesktop/Notifications')
|
||||
notify_iface = dbus.Interface(notify_obj, 'org.freedesktop.Notifications')
|
||||
|
||||
hints = {
|
||||
'urls': dbus.Array([dbus.String(file_url)], signature='s', variant_level=1),
|
||||
'x-kde-urls': dbus.Array([dbus.String(file_url)], signature='s', variant_level=1),
|
||||
'desktop-entry': dbus.String('', variant_level=1),
|
||||
'x-kde-app-icon': dbus.String('', variant_level=1)
|
||||
}
|
||||
notify_iface.Notify('f0ckm Uploader', dbus.UInt32(0), '', '', body_text, [], hints, -1)
|
||||
return
|
||||
except Exception as e:
|
||||
print(f"DBus notification error: {e}")
|
||||
|
||||
# Fallback to notify-send
|
||||
try:
|
||||
cmd = [
|
||||
"notify-send",
|
||||
"-a", "f0ckm Uploader",
|
||||
"-h", f"string:x-kde-urls:{file_url}",
|
||||
"-h", f"string:urls:{file_url}",
|
||||
"-h", "string:desktop-entry:",
|
||||
"-h", "string:x-kde-app-icon:",
|
||||
"",
|
||||
body_text
|
||||
]
|
||||
subprocess.run(cmd, check=False)
|
||||
except Exception as e:
|
||||
print(f"Notification error: {e}")
|
||||
|
||||
|
||||
Reference in New Issue
Block a user