Changeset View
Changeset View
Standalone View
Standalone View
applets/notifications/package/contents/ui/NotificationHeader.qml
- This file was added.
1 | /* | ||||
---|---|---|---|---|---|
2 | * Copyright 2018-2019 Kai Uwe Broulik <kde@privat.broulik.de> | ||||
3 | * | ||||
4 | * This program is free software; you can redistribute it and/or | ||||
5 | * modify it under the terms of the GNU General Public License as | ||||
6 | * published by the Free Software Foundation; either version 2 of | ||||
7 | * the License or (at your option) version 3 or any later version | ||||
8 | * accepted by the membership of KDE e.V. (or its successor approved | ||||
9 | * by the membership of KDE e.V.), which shall act as a proxy | ||||
10 | * defined in Section 14 of version 3 of the license. | ||||
11 | * | ||||
12 | * This program is distributed in the hope that it will be useful, | ||||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||||
15 | * GNU General Public License for more details. | ||||
16 | * | ||||
17 | * You should have received a copy of the GNU General Public License | ||||
18 | * along with this program. If not, see <http://www.gnu.org/licenses/> | ||||
19 | */ | ||||
20 | | ||||
21 | import QtQuick 2.8 | ||||
22 | import QtQuick.Layouts 1.1 | ||||
23 | import QtQuick.Window 2.2 | ||||
24 | | ||||
25 | import org.kde.plasma.core 2.0 as PlasmaCore | ||||
26 | import org.kde.plasma.components 2.0 as PlasmaComponents | ||||
27 | import org.kde.plasma.extras 2.0 as PlasmaExtras | ||||
28 | | ||||
29 | import org.kde.notificationmanager 1.0 as NotificationManager | ||||
30 | | ||||
31 | import org.kde.kcoreaddons 1.0 as KCoreAddons | ||||
32 | | ||||
33 | import "global" | ||||
34 | | ||||
35 | RowLayout { | ||||
36 | id: notificationHeading | ||||
37 | property bool inGroup | ||||
38 | property int notificationType | ||||
39 | | ||||
40 | property var applicationIconSource | ||||
41 | property string applicationName | ||||
42 | property string deviceName | ||||
43 | | ||||
44 | property string configureActionLabel | ||||
45 | | ||||
46 | property alias configurable: configureButton.visible | ||||
47 | property alias dismissable: dismissButton.visible | ||||
48 | property bool dismissed | ||||
49 | property alias closeButtonTooltip: closeButton.tooltip | ||||
50 | property alias closable: closeButton.visible | ||||
51 | | ||||
52 | property var time | ||||
53 | | ||||
54 | property int jobState | ||||
55 | property QtObject jobDetails | ||||
56 | | ||||
57 | signal configureClicked | ||||
58 | signal dismissClicked | ||||
59 | signal closeClicked | ||||
60 | | ||||
61 | // notification created/updated time changed | ||||
62 | onTimeChanged: updateAgoText() | ||||
63 | | ||||
64 | function updateAgoText() { | ||||
65 | ageLabel.agoText = ageLabel.generateAgoText(); | ||||
66 | } | ||||
67 | | ||||
68 | spacing: units.smallSpacing | ||||
69 | Layout.preferredHeight: Math.max(applicationNameLabel.implicitHeight, units.iconSizes.small) | ||||
70 | | ||||
71 | Connections { | ||||
72 | target: Globals | ||||
73 | // clock time changed | ||||
74 | onTimeChanged: notificationHeading.updateAgoText() | ||||
75 | } | ||||
76 | | ||||
77 | PlasmaCore.IconItem { | ||||
78 | id: applicationIconItem | ||||
79 | Layout.preferredWidth: units.iconSizes.small | ||||
80 | Layout.preferredHeight: units.iconSizes.small | ||||
81 | source: notificationHeading.applicationIconSource | ||||
82 | usesPlasmaTheme: false | ||||
83 | visible: valid | ||||
84 | } | ||||
85 | | ||||
86 | PlasmaExtras.DescriptiveLabel { | ||||
87 | id: applicationNameLabel | ||||
88 | Layout.fillWidth: true | ||||
89 | textFormat: Text.PlainText | ||||
90 | elide: Text.ElideRight | ||||
91 | text: notificationHeading.applicationName + (notificationHeading.deviceName ? " · " + notificationHeading.deviceName : "") | ||||
92 | } | ||||
93 | | ||||
94 | PlasmaExtras.DescriptiveLabel { | ||||
95 | id: ageLabel | ||||
96 | | ||||
97 | // the "n minutes ago" text, for jobs we show remaining time instead | ||||
98 | // updated periodically by a Timer hence this property with generate() function | ||||
99 | property string agoText: "" | ||||
100 | visible: text !== "" | ||||
101 | text: generateRemainingText() || agoText | ||||
102 | Layout.rightMargin: 0 // the ToolButton's margins are enough | ||||
103 | | ||||
104 | function generateAgoText() { | ||||
105 | if (!time || isNaN(time.getTime()) || notificationHeading.jobState === NotificationManager.Notifications.JobStateRunning) { | ||||
106 | return ""; | ||||
107 | } | ||||
108 | | ||||
109 | var now = new Date(); | ||||
110 | var deltaMinutes = Math.floor((now.getTime() - time.getTime()) / 1000 / 60); | ||||
111 | if (deltaMinutes < 1) { | ||||
112 | return ""; | ||||
113 | } | ||||
114 | | ||||
115 | // Received less than an hour ago, show relative minutes | ||||
116 | if (deltaMinutes < 60) { | ||||
117 | return i18ncp("Notification was added minutes ago, keep short", "%1 min ago", "%1 min ago", deltaMinutes); | ||||
118 | } | ||||
119 | // Received less than a day ago, show time, 23 hours so the time isn't ambiguous between today and yesterday | ||||
120 | if (deltaMinutes < 60 * 23) { | ||||
121 | return Qt.formatTime(time, Qt.locale().timeFormat(Locale.ShortFormat).replace(/.ss?/i, "")); | ||||
122 | } | ||||
123 | | ||||
124 | // Otherwise show relative date (Yesterday, "Last Sunday", or just date if too far in the past) | ||||
125 | return KCoreAddons.Format.formatRelativeDate(time, Locale.ShortFormat); | ||||
126 | } | ||||
127 | | ||||
128 | function generateRemainingText() { | ||||
129 | if (notificationHeading.notificationType !== NotificationManager.Notifications.JobType | ||||
130 | || notificationHeading.jobState === NotificationManager.Notifications.JobStateStopped) { | ||||
131 | return ""; | ||||
132 | } | ||||
133 | | ||||
134 | var details = notificationHeading.jobDetails; | ||||
135 | if (!details || !details.speed) { | ||||
136 | return ""; | ||||
137 | } | ||||
138 | | ||||
139 | var remaining = details.totalBytes - details.processedBytes; | ||||
140 | if (remaining <= 0) { | ||||
141 | return ""; | ||||
142 | } | ||||
143 | | ||||
144 | var eta = remaining / details.speed; | ||||
145 | if (!eta) { | ||||
146 | return ""; | ||||
147 | } | ||||
148 | | ||||
149 | if (eta < 60) { // 1 minute | ||||
150 | return i18ncp("seconds remaining, keep short", | ||||
151 | "%1s remaining", "%1s remaining", Math.round(eta)); | ||||
152 | } | ||||
153 | if (eta < 60 * 60) {// 1 hour | ||||
154 | return i18ncp("minutes remaining, keep short", | ||||
155 | "%1min remaining", "%1min remaining", | ||||
156 | Math.round(eta / 60)); | ||||
157 | } | ||||
158 | if (eta < 60 * 60 * 5) { // 5 hours max, if it takes even longer there's no real point in shoing that | ||||
159 | return i18ncp("hours remaining, keep short", | ||||
160 | "%1h remaining", "%1h remaining", | ||||
161 | Math.round(eta / 60 / 60)); | ||||
162 | } | ||||
163 | | ||||
164 | return ""; | ||||
165 | } | ||||
166 | | ||||
167 | PlasmaCore.ToolTipArea { | ||||
168 | anchors.fill: parent | ||||
169 | active: ageLabel.agoText !== "" | ||||
170 | subText: notificationHeading.time ? notificationHeading.time.toLocaleString(Qt.locale(), Locale.LongFormat) : "" | ||||
171 | } | ||||
172 | } | ||||
173 | | ||||
174 | RowLayout { | ||||
175 | id: headerButtonsRow | ||||
176 | spacing: 0 | ||||
177 | | ||||
178 | PlasmaComponents.ToolButton { | ||||
179 | id: configureButton | ||||
180 | tooltip: notificationHeading.configureActionLabel || i18n("Configure") | ||||
181 | iconSource: "configure" | ||||
182 | visible: false | ||||
183 | onClicked: notificationHeading.configureClicked() | ||||
184 | } | ||||
185 | | ||||
186 | PlasmaComponents.ToolButton { | ||||
187 | id: dismissButton | ||||
188 | tooltip: notificationHeading.dismissed ? i18nc("Opposite of minimize", "Restore") : i18n("Minimize") | ||||
189 | iconSource: notificationHeading.dismissed ? "window-restore" : "window-minimize" | ||||
190 | visible: false | ||||
191 | onClicked: notificationHeading.dismissClicked() | ||||
192 | } | ||||
193 | | ||||
194 | PlasmaComponents.ToolButton { | ||||
195 | id: closeButton | ||||
196 | tooltip: i18n("Close") | ||||
197 | iconSource: "window-close" | ||||
198 | visible: false | ||||
199 | onClicked: notificationHeading.closeClicked() | ||||
200 | } | ||||
201 | } | ||||
202 | | ||||
203 | states: [ | ||||
204 | State { | ||||
205 | when: notificationHeading.inGroup | ||||
206 | PropertyChanges { | ||||
207 | target: applicationIconItem | ||||
208 | source: "" | ||||
209 | } | ||||
210 | PropertyChanges { | ||||
211 | target: applicationNameLabel | ||||
212 | visible: false | ||||
213 | } | ||||
214 | } | ||||
215 | | ||||
216 | ] | ||||
217 | } |