Lomiri
Loading...
Searching...
No Matches
MessageMenuItemFactory.qml
1/*
2 * Copyright 2013 Canonical Ltd.
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU Lesser General Public License as published by
6 * the Free Software Foundation; version 3.
7 *
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU Lesser General Public License for more details.
12 *
13 * You should have received a copy of the GNU Lesser General Public License
14 * along with this program. If not, see <http://www.gnu.org/licenses/>.
15 *
16 * Authors:
17 * Renato Araujo Oliveira Filho <renato@canonical.com>
18 * Olivier Tilloy <olivier.tilloy@canonical.com>
19 */
20
21import QtQuick 2.12
22import Lomiri.Components 1.3
23import Lomiri.Settings.Menus 0.1 as Menus
24import QMenuModel 1.0 as QMenuModel
25import Utils 0.1 as Utils
26
27Loader {
28 id: messageFactoryItem
29 objectName: "messageItem"
30 property var menuModel: null
31 property QtObject menuData: null
32 property int menuIndex: -1
33
34 property bool selected: false
35 signal menuSelected
36 signal menuDeselected
37
38 QtObject {
39 id: priv
40 property var extendedData: menuData && menuData.ext || undefined
41 property var actionsDescription: getExtendedProperty(extendedData, "xAyatanaMessageActions", undefined)
42 property date time: new Date(getExtendedProperty(extendedData, "xAyatanaTime", 0) / 1000)
43 property string timeString: i18n.relativeDateTime(time)
44 }
45 LiveTimer {
46 frequency: LiveTimer.Relative
47 relativeTime: priv.time
48 onTrigger: priv.timeString = Qt.binding(function() { return i18n.relativeDateTime(priv.time); })
49 }
50
51 onMenuModelChanged: {
52 loadAttributes();
53 }
54 onMenuIndexChanged: {
55 loadAttributes();
56 }
57
58 sourceComponent: loadMessage(priv.actionsDescription)
59
60 function loadMessage(actions)
61 {
62 var parameterType = ""
63 for (var actIndex in actions) {
64 var desc = actions[actIndex];
65 if (desc["parameter-type"] !== undefined) {
66 parameterType += desc["parameter-type"];
67 } else {
68 parameterType += "_";
69 }
70 }
71
72 if (parameterType === "") {
73 return simpleMessage;
74 } else if (parameterType === "s") {
75 return textMessage;
76 } else if (parameterType === "_s") {
77 return snapDecision;
78 } else {
79 console.debug("Unknown paramater type: " + parameterType);
80 }
81 return undefined;
82 }
83
84 function loadAttributes() {
85 if (!menuModel || menuIndex == -1) return;
86 menuModel.loadExtendedAttributes(menuIndex, {'x-ayatana-time': 'int64',
87 'x-ayatana-text': 'string',
88 'x-ayatana-message-actions': 'variant',
89 'icon': 'icon',
90 'x-ayatana-app-icon': 'icon'});
91 }
92
93 function getExtendedProperty(object, propertyName, defaultValue) {
94 if (object && object.hasOwnProperty(propertyName)) {
95 return object[propertyName];
96 }
97 return defaultValue;
98 }
99
100 Component {
101 id: simpleMessage
102
103 Menus.SimpleMessageMenu {
104 id: message
105 objectName: "simpleTextMessage"
106 // text
107 title: menuData && menuData.label || ""
108 time: priv.timeString
109 body: getExtendedProperty(priv.extendedData, "xAyatanaText", "")
110 // icons
111 avatar: getExtendedProperty(priv.extendedData, "icon", "image://theme/contact")
112 icon: getExtendedProperty(priv.extendedData, "xAyatanaAppIcon", "image://theme/message")
113 // actions
114 enabled: menuData && menuData.sensitive || false
115 removable: !selected
116 confirmRemoval: true
117 selected: messageFactoryItem.selected
118
119 onIconActivated: {
120 menuModel.activate(menuIndex, true);
121 }
122 onDismissed: {
123 menuModel.activate(menuIndex, false);
124 }
125 onTriggered: {
126 menuModel.activate(menuIndex, true);
127 }
128 }
129 }
130
131 Component {
132 id: textMessage
133
134 Menus.TextMessageMenu {
135 id: message
136 objectName: "textMessage"
137 property var replyActionDescription: priv.actionsDescription && priv.actionsDescription.length > 0 ?
138 priv.actionsDescription[0] :
139 undefined
140
141 property var replyAction: QMenuModel.AyatanaMenuAction {
142 model: menuModel
143 index: menuIndex
144 name: getExtendedProperty(replyActionDescription, "name", "")
145 }
146
147 // text
148 title: menuData && menuData.label || ""
149 time: priv.timeString
150 body: getExtendedProperty(priv.extendedData, "xAyatanaText", "")
151 replyButtonText: getExtendedProperty(replyActionDescription, "label", i18n.ctr("Button: Send a reply message", "Send"))
152 replyHintText: i18n.ctr("Label: Hint in message indicator line edit", "Reply")
153 // icons
154 avatar: getExtendedProperty(priv.extendedData, "icon", "image://theme/contact")
155 icon: getExtendedProperty(priv.extendedData, "xAyatanaAppIcon", "image://theme/message")
156 // actions
157 replyEnabled: replyAction.valid && replyAction.enabled
158 enabled: menuData && menuData.sensitive || false
159 removable: !selected
160 confirmRemoval: true
161 selected: messageFactoryItem.selected
162 highlightWhenPressed: false
163
164 onIconActivated: {
165 menuModel.activate(menuIndex, true);
166 }
167 onDismissed: {
168 menuModel.activate(menuIndex, false);
169 }
170 onReplied: {
171 replyAction.activate(value);
172 }
173 onTriggered: {
174 if (selected) {
175 menuDeselected();
176 } else {
177 menuSelected();
178 }
179 }
180 }
181 }
182
183 Component {
184 id: snapDecision
185
186 Menus.SnapDecisionMenu {
187 id: message
188 objectName: "snapDecision"
189 property var activateActionDescription: priv.actionsDescription && priv.actionsDescription.length > 0 ?
190 priv.actionsDescription[0] : undefined
191 property var replyActionDescription: priv.actionsDescription && priv.actionsDescription.length > 1 ?
192 priv.actionsDescription[1] : undefined
193
194 property var activateAction: QMenuModel.AyatanaMenuAction {
195 model: menuModel
196 index: menuIndex
197 name: getExtendedProperty(activateActionDescription, "name", "")
198 }
199 property var replyAction: QMenuModel.AyatanaMenuAction {
200 model: menuModel
201 index: menuIndex
202 name: getExtendedProperty(replyActionDescription, "name", "")
203 }
204
205 // text
206 title: menuData && menuData.label || ""
207 time: priv.timeString
208 body: getExtendedProperty(priv.extendedData, "xAyatanaText", "")
209 actionButtonText: getExtendedProperty(activateActionDescription, "label", i18n.ctr("Button: Call back on phone", "Call back"))
210 replyButtonText: getExtendedProperty(replyActionDescription, "label", i18n.ctr("Button: Send a reply message", "Send"))
211 // icons
212 avatar: getExtendedProperty(priv.extendedData, "icon", "image://theme/contact")
213 icon: getExtendedProperty(priv.extendedData, "xAyatanaAppIcon", "image://theme/missed-call")
214 // actions
215 actionEnabled: activateAction.valid && activateAction.enabled
216 replyEnabled: replyAction.valid && replyAction.enabled
217 enabled: menuData && menuData.sensitive || false
218 removable: !selected
219 confirmRemoval: true
220 selected: messageFactoryItem.selected
221 highlightWhenPressed: false
222
223 onIconActivated: {
224 menuModel.activate(menuIndex, true);
225 }
226 onDismissed: {
227 menuModel.activate(menuIndex, false);
228 }
229 onActionActivated: {
230 activateAction.activate();
231 }
232 onReplied: {
233 replyAction.activate(value);
234 }
235 onTriggered: {
236 if (selected) {
237 menuDeselected();
238 } else {
239 menuSelected();
240 }
241 }
242 }
243 }
244}