mirror of
https://github.com/Nheko-Reborn/nheko.git
synced 2024-11-25 20:48:52 +03:00
Make the notification bubble its own component
This commit is contained in:
parent
e446e3d679
commit
8ec0577807
3 changed files with 86 additions and 79 deletions
|
@ -3,6 +3,7 @@
|
||||||
//
|
//
|
||||||
// SPDX-License-Identifier: GPL-3.0-or-later
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
import "./components"
|
||||||
import "./dialogs"
|
import "./dialogs"
|
||||||
import Qt.labs.platform 1.1 as Platform
|
import Qt.labs.platform 1.1 as Platform
|
||||||
import QtQml 2.12
|
import QtQml 2.12
|
||||||
|
@ -57,19 +58,29 @@ Page {
|
||||||
property color unimportantText: Nheko.colors.buttonText
|
property color unimportantText: Nheko.colors.buttonText
|
||||||
property color bubbleBackground: Nheko.colors.highlight
|
property color bubbleBackground: Nheko.colors.highlight
|
||||||
property color bubbleText: Nheko.colors.highlightedText
|
property color bubbleText: Nheko.colors.highlightedText
|
||||||
|
required property string avatarUrl
|
||||||
|
required property string displayName
|
||||||
|
required property string tooltip
|
||||||
|
required property bool collapsed
|
||||||
|
required property bool collapsible
|
||||||
|
required property bool hidden
|
||||||
|
required property int depth
|
||||||
|
required property string id
|
||||||
|
required property int unreadMessages
|
||||||
|
required property bool hasLoudNotification
|
||||||
|
|
||||||
height: avatarSize + 2 * Nheko.paddingMedium
|
height: avatarSize + 2 * Nheko.paddingMedium
|
||||||
width: ListView.view.width
|
width: ListView.view.width
|
||||||
state: "normal"
|
state: "normal"
|
||||||
ToolTip.visible: hovered && collapsed
|
ToolTip.visible: hovered && collapsed
|
||||||
ToolTip.text: model.tooltip
|
ToolTip.text: communityItem.tooltip
|
||||||
ToolTip.delay: Nheko.tooltipDelay
|
ToolTip.delay: Nheko.tooltipDelay
|
||||||
onClicked: Communities.setCurrentTagId(model.id)
|
onClicked: Communities.setCurrentTagId(communityItem.id)
|
||||||
onPressAndHold: communityContextMenu.show(model.id)
|
onPressAndHold: communityContextMenu.show(communityItem.id)
|
||||||
states: [
|
states: [
|
||||||
State {
|
State {
|
||||||
name: "highlight"
|
name: "highlight"
|
||||||
when: (communityItem.hovered || model.hidden) && !(Communities.currentTagId == model.id)
|
when: (communityItem.hovered || communityItem.hidden) && !(Communities.currentTagId === communityItem.id)
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: communityItem
|
target: communityItem
|
||||||
|
@ -83,7 +94,7 @@ Page {
|
||||||
},
|
},
|
||||||
State {
|
State {
|
||||||
name: "selected"
|
name: "selected"
|
||||||
when: Communities.currentTagId == model.id
|
when: Communities.currentTagId == communityItem.id
|
||||||
|
|
||||||
PropertyChanges {
|
PropertyChanges {
|
||||||
target: communityItem
|
target: communityItem
|
||||||
|
@ -102,7 +113,7 @@ Page {
|
||||||
|
|
||||||
TapHandler {
|
TapHandler {
|
||||||
acceptedButtons: Qt.RightButton
|
acceptedButtons: Qt.RightButton
|
||||||
onSingleTapped: communityContextMenu.show(model.id)
|
onSingleTapped: communityContextMenu.show(communityItem.id)
|
||||||
gesturePolicy: TapHandler.ReleaseWithinBounds
|
gesturePolicy: TapHandler.ReleaseWithinBounds
|
||||||
acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus | PointerDevice.TouchPad
|
acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus | PointerDevice.TouchPad
|
||||||
}
|
}
|
||||||
|
@ -114,27 +125,27 @@ Page {
|
||||||
spacing: Nheko.paddingMedium
|
spacing: Nheko.paddingMedium
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: Nheko.paddingMedium
|
anchors.margins: Nheko.paddingMedium
|
||||||
anchors.leftMargin: Nheko.paddingMedium + (communitySidebar.collapsed ? 0 : (fontMetrics.lineSpacing * model.depth))
|
anchors.leftMargin: Nheko.paddingMedium + (communitySidebar.collapsed ? 0 : (fontMetrics.lineSpacing * communityItem.depth))
|
||||||
|
|
||||||
ImageButton {
|
ImageButton {
|
||||||
visible: !communitySidebar.collapsed && model.collapsible
|
visible: !communitySidebar.collapsed && communityItem.collapsible
|
||||||
Layout.preferredHeight: fontMetrics.lineSpacing
|
Layout.preferredHeight: fontMetrics.lineSpacing
|
||||||
Layout.preferredWidth: fontMetrics.lineSpacing
|
Layout.preferredWidth: fontMetrics.lineSpacing
|
||||||
Layout.alignment: Qt.AlignVCenter
|
Layout.alignment: Qt.AlignVCenter
|
||||||
height: fontMetrics.lineSpacing
|
height: fontMetrics.lineSpacing
|
||||||
width: fontMetrics.lineSpacing
|
width: fontMetrics.lineSpacing
|
||||||
image: model.collapsed ? ":/icons/icons/ui/collapsed.svg" : ":/icons/icons/ui/expanded.svg"
|
image: communityItem.collapsed ? ":/icons/icons/ui/collapsed.svg" : ":/icons/icons/ui/expanded.svg"
|
||||||
ToolTip.visible: hovered
|
ToolTip.visible: hovered
|
||||||
ToolTip.delay: Nheko.tooltipDelay
|
ToolTip.delay: Nheko.tooltipDelay
|
||||||
ToolTip.text: model.collapsed ? qsTr("Expand") : qsTr("Collapse")
|
ToolTip.text: communityItem.collapsed ? qsTr("Expand") : qsTr("Collapse")
|
||||||
hoverEnabled: true
|
hoverEnabled: true
|
||||||
|
|
||||||
onClicked: model.collapsed = !model.collapsed
|
onClicked: communityItem.collapsed = !communityItem.collapsed
|
||||||
}
|
}
|
||||||
|
|
||||||
Item {
|
Item {
|
||||||
Layout.preferredWidth: fontMetrics.lineSpacing
|
Layout.preferredWidth: fontMetrics.lineSpacing
|
||||||
visible: !communitySidebar.collapsed && !model.collapsible && Communities.containsSubspaces
|
visible: !communitySidebar.collapsed && !communityItem.collapsible && Communities.containsSubspaces
|
||||||
}
|
}
|
||||||
|
|
||||||
Avatar {
|
Avatar {
|
||||||
|
@ -145,48 +156,25 @@ Page {
|
||||||
height: avatarSize
|
height: avatarSize
|
||||||
width: avatarSize
|
width: avatarSize
|
||||||
url: {
|
url: {
|
||||||
if (model.avatarUrl.startsWith("mxc://"))
|
if (communityItem.avatarUrl.startsWith("mxc://"))
|
||||||
return model.avatarUrl.replace("mxc://", "image://MxcImage/");
|
return communityItem.avatarUrl.replace("mxc://", "image://MxcImage/");
|
||||||
else
|
else
|
||||||
return "image://colorimage/" + model.avatarUrl + "?" + communityItem.unimportantText;
|
return "image://colorimage/" + communityItem.avatarUrl + "?" + communityItem.unimportantText;
|
||||||
}
|
}
|
||||||
roomid: model.id
|
roomid: communityItem.id
|
||||||
displayName: model.displayName
|
displayName: communityItem.displayName
|
||||||
color: communityItem.backgroundColor
|
color: communityItem.backgroundColor
|
||||||
|
|
||||||
Rectangle {
|
NotificationBubble {
|
||||||
id: collapsedNotificationBubble
|
notificationCount: communityItem.unreadMessages
|
||||||
|
hasLoudNotification: communityItem.hasLoudNotification
|
||||||
visible: model.unreadMessages > 0 && communitySidebar.collapsed
|
bubbleBackgroundColor: communityItem.bubbleBackground
|
||||||
|
bubbleTextColor: communityItem.bubbleText
|
||||||
|
font.pixelSize: fontMetrics.font.pixelSize * 0.6
|
||||||
|
mayBeVisible: communitySidebar.collapsed
|
||||||
anchors.right: avatar.right
|
anchors.right: avatar.right
|
||||||
anchors.bottom: avatar.bottom
|
anchors.bottom: avatar.bottom
|
||||||
anchors.margins: -Nheko.paddingSmall
|
anchors.margins: -Nheko.paddingSmall
|
||||||
height: collapsedNotificationBubbleText.height + Nheko.paddingMedium
|
|
||||||
width: Math.max(collapsedNotificationBubbleText.width, height)
|
|
||||||
radius: height / 2
|
|
||||||
color: model.hasLoudNotification ? Nheko.theme.red : communityItem.bubbleBackground
|
|
||||||
ToolTip.text: model.unreadMessages
|
|
||||||
ToolTip.delay: Nheko.tooltipDelay
|
|
||||||
ToolTip.visible: collapsedNotificationBubbleHover.hovered && (model.unreadMessages > 9999)
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: collapsedNotificationBubbleText
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
width: Math.max(implicitWidth + Nheko.paddingMedium, parent.height)
|
|
||||||
font.bold: true
|
|
||||||
font.pixelSize: fontMetrics.font.pixelSize * 0.6
|
|
||||||
color: model.hasLoudNotification ? "white" : communityItem.bubbleText
|
|
||||||
text: model.unreadMessages > 9999 ? "9999+" : model.unreadMessages
|
|
||||||
|
|
||||||
HoverHandler {
|
|
||||||
id: collapsedNotificationBubbleHover
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -197,7 +185,7 @@ Page {
|
||||||
color: communityItem.importantText
|
color: communityItem.importantText
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
elideWidth: width
|
elideWidth: width
|
||||||
fullText: model.displayName
|
fullText: communityItem.displayName
|
||||||
textFormat: Text.PlainText
|
textFormat: Text.PlainText
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -205,44 +193,20 @@ Page {
|
||||||
Layout.fillWidth: true
|
Layout.fillWidth: true
|
||||||
}
|
}
|
||||||
|
|
||||||
Rectangle {
|
NotificationBubble {
|
||||||
id: notificationBubble
|
notificationCount: communityItem.unreadMessages
|
||||||
|
hasLoudNotification: communityItem.hasLoudNotification
|
||||||
visible: model.unreadMessages > 0 && !communitySidebar.collapsed
|
bubbleBackgroundColor: communityItem.bubbleBackground
|
||||||
|
bubbleTextColor: communityItem.bubbleText
|
||||||
|
mayBeVisible: !communitySidebar.collapsed
|
||||||
Layout.alignment: Qt.AlignRight
|
Layout.alignment: Qt.AlignRight
|
||||||
Layout.leftMargin: Nheko.paddingSmall
|
Layout.leftMargin: Nheko.paddingSmall
|
||||||
height: notificationBubbleText.height + Nheko.paddingMedium
|
|
||||||
Layout.preferredWidth: Math.max(notificationBubbleText.width, height)
|
|
||||||
radius: height / 2
|
|
||||||
color: model.hasLoudNotification ? Nheko.theme.red : communityItem.bubbleBackground
|
|
||||||
ToolTip.text: model.unreadMessages
|
|
||||||
ToolTip.delay: Nheko.tooltipDelay
|
|
||||||
ToolTip.visible: notificationBubbleHover.hovered && (model.unreadMessages > 9999)
|
|
||||||
|
|
||||||
Label {
|
|
||||||
id: notificationBubbleText
|
|
||||||
|
|
||||||
anchors.centerIn: parent
|
|
||||||
horizontalAlignment: Text.AlignHCenter
|
|
||||||
verticalAlignment: Text.AlignVCenter
|
|
||||||
width: Math.max(implicitWidth + Nheko.paddingMedium, parent.height)
|
|
||||||
font.bold: true
|
|
||||||
font.pixelSize: fontMetrics.font.pixelSize * 0.8
|
|
||||||
color: model.hasLoudNotification ? "white" : communityItem.bubbleText
|
|
||||||
text: model.unreadMessages > 9999 ? "9999+" : model.unreadMessages
|
|
||||||
|
|
||||||
HoverHandler {
|
|
||||||
id: notificationBubbleHover
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
background: Rectangle {
|
background: Rectangle {
|
||||||
color: backgroundColor
|
color: communityItem.backgroundColor
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
42
resources/qml/components/NotificationBubble.qml
Normal file
42
resources/qml/components/NotificationBubble.qml
Normal file
|
@ -0,0 +1,42 @@
|
||||||
|
import QtQuick 2.15
|
||||||
|
import QtQuick.Controls 2.15
|
||||||
|
import im.nheko 1.0
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: bubbleRoot
|
||||||
|
|
||||||
|
required property int notificationCount
|
||||||
|
required property bool hasLoudNotification
|
||||||
|
required property color bubbleBackgroundColor
|
||||||
|
required property color bubbleTextColor
|
||||||
|
property bool mayBeVisible: true
|
||||||
|
property alias font: notificationBubbleText.font
|
||||||
|
|
||||||
|
visible: mayBeVisible && notificationCount > 0
|
||||||
|
implicitHeight: notificationBubbleText.height + Nheko.paddingMedium
|
||||||
|
implicitWidth: Math.max(notificationBubbleText.width, height)
|
||||||
|
radius: height / 2
|
||||||
|
color: hasLoudNotification ? Nheko.theme.red : bubbleBackgroundColor
|
||||||
|
ToolTip.text: notificationCount
|
||||||
|
ToolTip.delay: Nheko.tooltipDelay
|
||||||
|
ToolTip.visible: notificationBubbleHover.hovered && (notificationCount > 9999)
|
||||||
|
|
||||||
|
Label {
|
||||||
|
id: notificationBubbleText
|
||||||
|
|
||||||
|
anchors.centerIn: bubbleRoot
|
||||||
|
horizontalAlignment: Text.AlignHCenter
|
||||||
|
verticalAlignment: Text.AlignVCenter
|
||||||
|
width: Math.max(implicitWidth + Nheko.paddingMedium, bubbleRoot.height)
|
||||||
|
font.bold: true
|
||||||
|
font.pixelSize: fontMetrics.font.pixelSize * 0.8
|
||||||
|
color: bubbleRoot.hasLoudNotification ? "white" : bubbleRoot.bubbleTextColor
|
||||||
|
text: bubbleRoot.notificationCount > 9999 ? "9999+" : bubbleRoot.notificationCount
|
||||||
|
|
||||||
|
HoverHandler {
|
||||||
|
id: notificationBubbleHover
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -182,6 +182,7 @@
|
||||||
<file>qml/voip/PlaceCall.qml</file>
|
<file>qml/voip/PlaceCall.qml</file>
|
||||||
<file>qml/voip/ScreenShare.qml</file>
|
<file>qml/voip/ScreenShare.qml</file>
|
||||||
<file>qml/voip/VideoCall.qml</file>
|
<file>qml/voip/VideoCall.qml</file>
|
||||||
|
<file>qml/components/NotificationBubble.qml</file>
|
||||||
</qresource>
|
</qresource>
|
||||||
<qresource prefix="/media">
|
<qresource prefix="/media">
|
||||||
<file>media/ring.ogg</file>
|
<file>media/ring.ogg</file>
|
||||||
|
|
Loading…
Reference in a new issue