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:
|
else:
|
||||||
path_str = urllib.parse.unquote(path_str[7:])
|
path_str = urllib.parse.unquote(path_str[7:])
|
||||||
return os.path.abspath(path_str)
|
return os.path.abspath(path_str)
|
||||||
from PySide6.QtCore import Qt, QThread, QObject, Signal, QUrl, QFile, QIODevice
|
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
|
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.QtNetwork import QNetworkAccessManager, QNetworkRequest, QHttpMultiPart, QHttpPart, QNetworkReply, QLocalServer, QLocalSocket
|
||||||
from PySide6.QtWidgets import (
|
from PySide6.QtWidgets import (
|
||||||
QApplication, QSystemTrayIcon, QMenu, QDialog, QVBoxLayout, QHBoxLayout,
|
QApplication, QSystemTrayIcon, QMenu, QDialog, QVBoxLayout, QHBoxLayout,
|
||||||
@@ -533,6 +533,39 @@ class SettingsDialog(QDialog):
|
|||||||
else:
|
else:
|
||||||
QMessageBox.critical(self, "Error", "Failed to save configuration file.")
|
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
|
# Upload Gallery Window & Components
|
||||||
# ==========================================
|
# ==========================================
|
||||||
@@ -559,10 +592,13 @@ class GalleryCard(QFrame):
|
|||||||
layout.setContentsMargins(8, 8, 8, 8)
|
layout.setContentsMargins(8, 8, 8, 8)
|
||||||
layout.setSpacing(6)
|
layout.setSpacing(6)
|
||||||
|
|
||||||
# Thumbnail
|
# Thumbnail with Drag & Drop support
|
||||||
self.thumb_label = QLabel()
|
file_path = item.get("file_path", "")
|
||||||
|
self.thumb_label = DraggableImageLabel(file_path)
|
||||||
self.thumb_label.setFixedSize(160, 100)
|
self.thumb_label.setFixedSize(160, 100)
|
||||||
self.thumb_label.setAlignment(Qt.AlignmentFlag.AlignCenter)
|
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;")
|
self.thumb_label.setStyleSheet("background-color: #121216; border-radius: 4px;")
|
||||||
|
|
||||||
thumb_path = item.get("thumbnail_path", "")
|
thumb_path = item.get("thumbnail_path", "")
|
||||||
@@ -1238,14 +1274,48 @@ class SystemTrayApp(QObject):
|
|||||||
if not config.get("enable_notifications", True):
|
if not config.get("enable_notifications", True):
|
||||||
return
|
return
|
||||||
|
|
||||||
thumb_path = generate_thumbnail(file_path)
|
abs_path = os.path.abspath(file_path)
|
||||||
if thumb_path and os.path.exists(thumb_path):
|
ext = os.path.splitext(abs_path)[1].lower()
|
||||||
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>'
|
if ext in [".png", ".jpg", ".jpeg", ".gif", ".webp", ".bmp", ".avif"]:
|
||||||
|
img_path = abs_path
|
||||||
else:
|
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:
|
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:
|
except Exception as e:
|
||||||
print(f"Notification error: {e}")
|
print(f"Notification error: {e}")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user