mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-04-14 09:42:10 -04:00
notifications: handle material icons
This commit is contained in:
@@ -89,7 +89,17 @@ Rectangle {
|
|||||||
|
|
||||||
DankCircularImage {
|
DankCircularImage {
|
||||||
id: iconContainer
|
id: iconContainer
|
||||||
readonly property bool hasNotificationImage: historyItem.image && historyItem.image !== ""
|
readonly property string rawImage: historyItem.image || ""
|
||||||
|
readonly property string iconFromImage: {
|
||||||
|
if (rawImage.startsWith("image://icon/"))
|
||||||
|
return rawImage.substring(13);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
readonly property bool imageHasSpecialPrefix: {
|
||||||
|
const icon = iconFromImage;
|
||||||
|
return icon.startsWith("material:") || icon.startsWith("svg:") || icon.startsWith("unicode:") || icon.startsWith("image:");
|
||||||
|
}
|
||||||
|
readonly property bool hasNotificationImage: rawImage !== "" && !rawImage.startsWith("image://icon/")
|
||||||
|
|
||||||
width: iconSize
|
width: iconSize
|
||||||
height: iconSize
|
height: iconSize
|
||||||
@@ -99,17 +109,24 @@ Rectangle {
|
|||||||
imageSource: {
|
imageSource: {
|
||||||
if (hasNotificationImage)
|
if (hasNotificationImage)
|
||||||
return historyItem.image;
|
return historyItem.image;
|
||||||
if (historyItem.appIcon) {
|
if (imageHasSpecialPrefix)
|
||||||
const appIcon = historyItem.appIcon;
|
return "";
|
||||||
if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://"))
|
const appIcon = historyItem.appIcon;
|
||||||
return appIcon;
|
if (!appIcon)
|
||||||
return Quickshell.iconPath(appIcon, true);
|
return iconFromImage ? "image://icon/" + iconFromImage : "";
|
||||||
}
|
if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://") || appIcon.includes("/"))
|
||||||
return "";
|
return appIcon;
|
||||||
|
if (appIcon.startsWith("material:") || appIcon.startsWith("svg:") || appIcon.startsWith("unicode:") || appIcon.startsWith("image:"))
|
||||||
|
return "";
|
||||||
|
return Quickshell.iconPath(appIcon, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasImage: hasNotificationImage
|
hasImage: hasNotificationImage
|
||||||
fallbackIcon: ""
|
fallbackIcon: {
|
||||||
|
if (imageHasSpecialPrefix)
|
||||||
|
return iconFromImage;
|
||||||
|
return historyItem.appIcon || iconFromImage || "";
|
||||||
|
}
|
||||||
fallbackText: {
|
fallbackText: {
|
||||||
const appName = historyItem.appName || "?";
|
const appName = historyItem.appName || "?";
|
||||||
return appName.charAt(0).toUpperCase();
|
return appName.charAt(0).toUpperCase();
|
||||||
|
|||||||
@@ -113,7 +113,17 @@ Rectangle {
|
|||||||
|
|
||||||
DankCircularImage {
|
DankCircularImage {
|
||||||
id: iconContainer
|
id: iconContainer
|
||||||
readonly property bool hasNotificationImage: notificationGroup?.latestNotification?.image && notificationGroup.latestNotification.image !== ""
|
readonly property string rawImage: notificationGroup?.latestNotification?.image || ""
|
||||||
|
readonly property string iconFromImage: {
|
||||||
|
if (rawImage.startsWith("image://icon/"))
|
||||||
|
return rawImage.substring(13);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
readonly property bool imageHasSpecialPrefix: {
|
||||||
|
const icon = iconFromImage;
|
||||||
|
return icon.startsWith("material:") || icon.startsWith("svg:") || icon.startsWith("unicode:") || icon.startsWith("image:");
|
||||||
|
}
|
||||||
|
readonly property bool hasNotificationImage: rawImage !== "" && !rawImage.startsWith("image://icon/")
|
||||||
|
|
||||||
width: iconSize
|
width: iconSize
|
||||||
height: iconSize
|
height: iconSize
|
||||||
@@ -123,17 +133,24 @@ Rectangle {
|
|||||||
imageSource: {
|
imageSource: {
|
||||||
if (hasNotificationImage)
|
if (hasNotificationImage)
|
||||||
return notificationGroup.latestNotification.cleanImage;
|
return notificationGroup.latestNotification.cleanImage;
|
||||||
if (notificationGroup?.latestNotification?.appIcon) {
|
if (imageHasSpecialPrefix)
|
||||||
const appIcon = notificationGroup.latestNotification.appIcon;
|
return "";
|
||||||
if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://"))
|
const appIcon = notificationGroup?.latestNotification?.appIcon;
|
||||||
return appIcon;
|
if (!appIcon)
|
||||||
return Quickshell.iconPath(appIcon, true);
|
return iconFromImage ? "image://icon/" + iconFromImage : "";
|
||||||
}
|
if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://") || appIcon.includes("/"))
|
||||||
return "";
|
return appIcon;
|
||||||
|
if (appIcon.startsWith("material:") || appIcon.startsWith("svg:") || appIcon.startsWith("unicode:") || appIcon.startsWith("image:"))
|
||||||
|
return "";
|
||||||
|
return Quickshell.iconPath(appIcon, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasImage: hasNotificationImage
|
hasImage: hasNotificationImage
|
||||||
fallbackIcon: ""
|
fallbackIcon: {
|
||||||
|
if (imageHasSpecialPrefix)
|
||||||
|
return iconFromImage;
|
||||||
|
return notificationGroup?.latestNotification?.appIcon || iconFromImage || "";
|
||||||
|
}
|
||||||
fallbackText: {
|
fallbackText: {
|
||||||
const appName = notificationGroup?.appName || "?";
|
const appName = notificationGroup?.appName || "?";
|
||||||
return appName.charAt(0).toUpperCase();
|
return appName.charAt(0).toUpperCase();
|
||||||
@@ -360,7 +377,17 @@ Rectangle {
|
|||||||
DankCircularImage {
|
DankCircularImage {
|
||||||
id: messageIcon
|
id: messageIcon
|
||||||
|
|
||||||
readonly property bool hasNotificationImage: modelData?.image && modelData.image !== ""
|
readonly property string rawImage: modelData?.image || ""
|
||||||
|
readonly property string iconFromImage: {
|
||||||
|
if (rawImage.startsWith("image://icon/"))
|
||||||
|
return rawImage.substring(13);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
readonly property bool imageHasSpecialPrefix: {
|
||||||
|
const icon = iconFromImage;
|
||||||
|
return icon.startsWith("material:") || icon.startsWith("svg:") || icon.startsWith("unicode:") || icon.startsWith("image:");
|
||||||
|
}
|
||||||
|
readonly property bool hasNotificationImage: rawImage !== "" && !rawImage.startsWith("image://icon/")
|
||||||
|
|
||||||
width: expandedIconSize
|
width: expandedIconSize
|
||||||
height: expandedIconSize
|
height: expandedIconSize
|
||||||
@@ -371,18 +398,23 @@ Rectangle {
|
|||||||
imageSource: {
|
imageSource: {
|
||||||
if (hasNotificationImage)
|
if (hasNotificationImage)
|
||||||
return modelData.cleanImage;
|
return modelData.cleanImage;
|
||||||
|
if (imageHasSpecialPrefix)
|
||||||
if (modelData?.appIcon) {
|
return "";
|
||||||
const appIcon = modelData.appIcon;
|
const appIcon = modelData?.appIcon;
|
||||||
if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://"))
|
if (!appIcon)
|
||||||
return appIcon;
|
return iconFromImage ? "image://icon/" + iconFromImage : "";
|
||||||
|
if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://") || appIcon.includes("/"))
|
||||||
return Quickshell.iconPath(appIcon, true);
|
return appIcon;
|
||||||
}
|
if (appIcon.startsWith("material:") || appIcon.startsWith("svg:") || appIcon.startsWith("unicode:") || appIcon.startsWith("image:"))
|
||||||
return "";
|
return "";
|
||||||
|
return Quickshell.iconPath(appIcon, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
fallbackIcon: ""
|
fallbackIcon: {
|
||||||
|
if (imageHasSpecialPrefix)
|
||||||
|
return iconFromImage;
|
||||||
|
return modelData?.appIcon || iconFromImage || "";
|
||||||
|
}
|
||||||
|
|
||||||
fallbackText: {
|
fallbackText: {
|
||||||
const appName = modelData?.appName || "?";
|
const appName = modelData?.appName || "?";
|
||||||
|
|||||||
@@ -384,8 +384,18 @@ PanelWindow {
|
|||||||
DankCircularImage {
|
DankCircularImage {
|
||||||
id: iconContainer
|
id: iconContainer
|
||||||
|
|
||||||
readonly property bool hasNotificationImage: notificationData && notificationData.image && notificationData.image !== ""
|
readonly property string rawImage: notificationData?.image || ""
|
||||||
readonly property bool needsImagePersist: hasNotificationImage && notificationData.image.startsWith("image://qsimage/") && !notificationData.persistedImagePath
|
readonly property string iconFromImage: {
|
||||||
|
if (rawImage.startsWith("image://icon/"))
|
||||||
|
return rawImage.substring(13);
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
readonly property bool imageHasSpecialPrefix: {
|
||||||
|
const icon = iconFromImage;
|
||||||
|
return icon.startsWith("material:") || icon.startsWith("svg:") || icon.startsWith("unicode:") || icon.startsWith("image:");
|
||||||
|
}
|
||||||
|
readonly property bool hasNotificationImage: rawImage !== "" && !rawImage.startsWith("image://icon/")
|
||||||
|
readonly property bool needsImagePersist: hasNotificationImage && rawImage.startsWith("image://qsimage/") && !notificationData.persistedImagePath
|
||||||
|
|
||||||
width: popupIconSize
|
width: popupIconSize
|
||||||
height: popupIconSize
|
height: popupIconSize
|
||||||
@@ -395,22 +405,26 @@ PanelWindow {
|
|||||||
imageSource: {
|
imageSource: {
|
||||||
if (!notificationData)
|
if (!notificationData)
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
if (hasNotificationImage)
|
if (hasNotificationImage)
|
||||||
return notificationData.cleanImage || "";
|
return notificationData.cleanImage || "";
|
||||||
|
if (imageHasSpecialPrefix)
|
||||||
if (notificationData.appIcon) {
|
return "";
|
||||||
const appIcon = notificationData.appIcon;
|
const appIcon = notificationData.appIcon;
|
||||||
if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://"))
|
if (!appIcon)
|
||||||
return appIcon;
|
return iconFromImage ? "image://icon/" + iconFromImage : "";
|
||||||
|
if (appIcon.startsWith("file://") || appIcon.startsWith("http://") || appIcon.startsWith("https://") || appIcon.includes("/"))
|
||||||
return Quickshell.iconPath(appIcon, true);
|
return appIcon;
|
||||||
}
|
if (appIcon.startsWith("material:") || appIcon.startsWith("svg:") || appIcon.startsWith("unicode:") || appIcon.startsWith("image:"))
|
||||||
return "";
|
return "";
|
||||||
|
return Quickshell.iconPath(appIcon, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
hasImage: hasNotificationImage
|
hasImage: hasNotificationImage
|
||||||
fallbackIcon: ""
|
fallbackIcon: {
|
||||||
|
if (imageHasSpecialPrefix)
|
||||||
|
return iconFromImage;
|
||||||
|
return notificationData?.appIcon || iconFromImage || "";
|
||||||
|
}
|
||||||
fallbackText: {
|
fallbackText: {
|
||||||
const appName = notificationData?.appName || "?";
|
const appName = notificationData?.appName || "?";
|
||||||
return appName.charAt(0).toUpperCase();
|
return appName.charAt(0).toUpperCase();
|
||||||
|
|||||||
@@ -20,17 +20,17 @@ Item {
|
|||||||
property real materialIconSizeAdjustment: Theme.spacingM
|
property real materialIconSizeAdjustment: Theme.spacingM
|
||||||
property real unicodeIconScale: 0.7
|
property real unicodeIconScale: 0.7
|
||||||
property real fallbackTextScale: 0.4
|
property real fallbackTextScale: 0.4
|
||||||
property alias iconMargins: iconImg.anchors.margins
|
property real iconMargins: 0
|
||||||
property real fallbackLeftMargin: 0
|
property real fallbackLeftMargin: 0
|
||||||
property real fallbackRightMargin: 0
|
property real fallbackRightMargin: 0
|
||||||
property real fallbackTopMargin: 0
|
property real fallbackTopMargin: 0
|
||||||
property real fallbackBottomMargin: 0
|
property real fallbackBottomMargin: 0
|
||||||
|
|
||||||
readonly property bool isMaterial: iconValue.startsWith("material:")
|
readonly property bool isMaterial: iconValue && iconValue.startsWith("material:")
|
||||||
readonly property bool isUnicode: iconValue.startsWith("unicode:")
|
readonly property bool isUnicode: iconValue && iconValue.startsWith("unicode:")
|
||||||
readonly property bool isSvgCorner: iconValue.startsWith("svg+corner:")
|
readonly property bool isSvgCorner: iconValue && iconValue.startsWith("svg+corner:")
|
||||||
readonly property bool isSvg: !isSvgCorner && iconValue.startsWith("svg:")
|
readonly property bool isSvg: iconValue && !isSvgCorner && iconValue.startsWith("svg:")
|
||||||
readonly property bool isImage: iconValue.startsWith("image:")
|
readonly property bool isImage: iconValue && iconValue.startsWith("image:")
|
||||||
readonly property bool hasColorOverride: colorOverride.a > 0
|
readonly property bool hasColorOverride: colorOverride.a > 0
|
||||||
readonly property string materialName: isMaterial ? iconValue.substring(9) : ""
|
readonly property string materialName: isMaterial ? iconValue.substring(9) : ""
|
||||||
readonly property string unicodeChar: isUnicode ? iconValue.substring(8) : ""
|
readonly property string unicodeChar: isUnicode ? iconValue.substring(8) : ""
|
||||||
@@ -45,7 +45,12 @@ Item {
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
readonly property string svgCornerIcon: isSvgCorner ? (iconValue.substring(11).split("|")[1] || "") : ""
|
readonly property string svgCornerIcon: isSvgCorner ? (iconValue.substring(11).split("|")[1] || "") : ""
|
||||||
readonly property string iconPath: isMaterial || isUnicode || isSvg || isSvgCorner || isImage ? "" : Quickshell.iconPath(iconValue, true) || DesktopService.resolveIconPath(iconValue)
|
readonly property bool hasSpecialPrefix: isMaterial || isUnicode || isSvg || isSvgCorner || isImage
|
||||||
|
readonly property string iconPath: {
|
||||||
|
if (hasSpecialPrefix || !iconValue)
|
||||||
|
return "";
|
||||||
|
return Quickshell.iconPath(iconValue, true) || DesktopService.resolveIconPath(iconValue);
|
||||||
|
}
|
||||||
|
|
||||||
visible: iconValue !== undefined && iconValue !== ""
|
visible: iconValue !== undefined && iconValue !== ""
|
||||||
|
|
||||||
@@ -85,15 +90,19 @@ Item {
|
|||||||
visible: root.isImage && status === Image.Ready
|
visible: root.isImage && status === Image.Ready
|
||||||
}
|
}
|
||||||
|
|
||||||
IconImage {
|
Loader {
|
||||||
id: iconImg
|
id: iconImgLoader
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
source: root.iconPath
|
anchors.margins: root.iconMargins
|
||||||
backer.sourceSize: Qt.size(root.iconSize, root.iconSize)
|
active: !root.hasSpecialPrefix && root.iconPath !== ""
|
||||||
mipmap: true
|
sourceComponent: IconImage {
|
||||||
asynchronous: true
|
anchors.fill: parent
|
||||||
visible: !root.isMaterial && !root.isUnicode && !root.isSvg && !root.isSvgCorner && !root.isImage && root.iconPath !== "" && status === Image.Ready
|
source: root.iconPath
|
||||||
|
backer.sourceSize: Qt.size(root.iconSize, root.iconSize)
|
||||||
|
mipmap: true
|
||||||
|
asynchronous: true
|
||||||
|
visible: status === Image.Ready
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
Rectangle {
|
||||||
@@ -104,7 +113,7 @@ Item {
|
|||||||
anchors.rightMargin: root.fallbackRightMargin
|
anchors.rightMargin: root.fallbackRightMargin
|
||||||
anchors.topMargin: root.fallbackTopMargin
|
anchors.topMargin: root.fallbackTopMargin
|
||||||
anchors.bottomMargin: root.fallbackBottomMargin
|
anchors.bottomMargin: root.fallbackBottomMargin
|
||||||
visible: !root.isMaterial && !root.isUnicode && !root.isSvg && !root.isSvgCorner && !root.isImage && (root.iconPath === "" || iconImg.status !== Image.Ready)
|
visible: !root.hasSpecialPrefix && (root.iconPath === "" || !iconImgLoader.item || iconImgLoader.item.status !== Image.Ready)
|
||||||
color: root.fallbackBackgroundColor
|
color: root.fallbackBackgroundColor
|
||||||
radius: Theme.cornerRadius
|
radius: Theme.cornerRadius
|
||||||
border.width: 0
|
border.width: 0
|
||||||
|
|||||||
@@ -71,12 +71,18 @@ Rectangle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
DankIcon {
|
AppIconRenderer {
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
name: root.fallbackIcon
|
width: parent.width * 0.75
|
||||||
size: parent.width * 0.5
|
height: width
|
||||||
color: Theme.surfaceVariantText
|
|
||||||
visible: (internalImage.status !== Image.Ready || root.imageSource === "") && root.fallbackIcon !== ""
|
visible: (internalImage.status !== Image.Ready || root.imageSource === "") && root.fallbackIcon !== ""
|
||||||
|
iconValue: root.fallbackIcon
|
||||||
|
iconSize: width
|
||||||
|
iconColor: Theme.surfaceVariantText
|
||||||
|
materialIconSizeAdjustment: 0
|
||||||
|
fallbackText: root.fallbackText
|
||||||
|
fallbackBackgroundColor: "transparent"
|
||||||
|
fallbackTextColor: Theme.surfaceVariantText
|
||||||
}
|
}
|
||||||
|
|
||||||
StyledText {
|
StyledText {
|
||||||
|
|||||||
Reference in New Issue
Block a user