Unity 8
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 
21 import QtQuick 2.12
22 import Ubuntu.Components 1.3
23 import Ubuntu.Settings.Menus 0.1 as Menus
24 import QMenuModel 0.1 as QMenuModel
25 import Utils 0.1 as Utils
26 
27 Loader {
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, "xCanonicalMessageActions", undefined)
42  property date time: new Date(getExtendedProperty(extendedData, "xCanonicalTime", 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-canonical-time': 'int64',
87  'x-canonical-text': 'string',
88  'x-canonical-message-actions': 'variant',
89  'icon': 'icon',
90  'x-canonical-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, "xCanonicalText", "")
110  // icons
111  avatar: getExtendedProperty(priv.extendedData, "icon", "image://theme/contact")
112  icon: getExtendedProperty(priv.extendedData, "xCanonicalAppIcon", "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.UnityMenuAction {
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, "xCanonicalText", "")
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, "xCanonicalAppIcon", "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.UnityMenuAction {
195  model: menuModel
196  index: menuIndex
197  name: getExtendedProperty(activateActionDescription, "name", "")
198  }
199  property var replyAction: QMenuModel.UnityMenuAction {
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, "xCanonicalText", "")
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, "xCanonicalAppIcon", "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 }