Dekko
Loading...
Searching...
No Matches
ContentWorker.qml
1/* Copyright (C) 2016 - 2017 Dan Chapman <dpniel@ubuntu.com>
2
3 This file is part of Dekko email client for Ubuntu devices
4
5 This program is free software; you can redistribute it and/or
6 modify it under the terms of the GNU General Public License as
7 published by the Free Software Foundation; either version 2 of
8 the License or (at your option) version 3
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <http://www.gnu.org/licenses/>.
17*/
18import QtQuick 2.4
19import QtQuick.Window 2.1
20import QuickFlux 1.0
21import Lomiri.Components.Popups 1.3
22import Lomiri.Content 1.1
23import Dekko.Mail.API 1.0
24import Dekko.Mail.Stores.Views 1.0
25import Dekko.Mail.Stores.Composer 1.0
26import Dekko.Mail 1.0
27import Dekko.Lomiri.Dialogs 1.0
28
41AppListener {
42
43 waitFor: [ViewStore.listenerId, ComposerStore.listenerId]
44 property string pickerUrl: ""
45
46 Connections {
47 target: ContentHub
48 onImportRequested: {
49 Log.logStatus("[ContentHub::importRequested]", "import requested, running import...")
50 ContentActions.importFromContentHub(transfer)
51 }
52 onShareRequested: {
53 Log.logStatus("[ContentHub::shareRequested]", "share requested. importing share")
54 ContentActions.importFromContentHub(transfer)
55 }
56 onExportRequested: {
57 Log.logStatus("ContentHub::exportRequested", "NotImplementedYet")
58 }
59 }
60
61 AppScript {
62 runWhen: ContentKeys.pickFile
63 script: {
64 // First open the file picker for the platform
65 // This will either be the ContentHub picker
66 // or Qt's own FileDialog for non unity8 platforms
67 ContentActions.openFilePicker(message.root)
68 // Listen on selected files and add them to the composer
69 once(ContentKeys.filesSelected, function(message) {
70 console.debug("FILES: ", message.files)
71 const files = message.files
72 for (let i in message.files) {
73 console.debug("File: ", message.files[i])
74 const file = message.files[i]
75 ComposerActions.addFileAttachment(file.toString().replace("file://", ""))
76 }
77 })
78 // Drop all callbacks if the picker is closed with no selections
79 once(ContentKeys.pickerClosed, exit.bind(this, 0))
80 }
81 }
82
83 Component {
84 id: chp
86 }
87
88 Component {
89 id: contactPickerComponent
91 }
92
93 Component {
94 id: emailSelectionComponent
96 }
97
98 AppScript {
99 runWhen: ContentKeys.pickContacts
100 script: {
101 const rootItem = message.root;
102 const recipientType = message.type;
103 console.debug("[ContentWorker] pickContacts triggered, recipientType:", recipientType)
104 // Open the ContactPickerDialog popup (ContentPeerPicker inside)
105 ContentActions.openContactPicker(rootItem)
106 // Wait for contacts to be selected
107 once(ContentKeys.contactsSelected, function(message) {
108 const files = message.files;
109 console.debug("[ContentWorker] contactsSelected, files:", JSON.stringify(files))
110 // Helper to parse VCard using FileReaderHelper C++ backend
111 const reader = Qt.createQmlObject('import Dekko.Components 1.0; FileReaderHelper {}', rootItem, "Reader");
112 for (let i = 0; i < files.length; i++) {
113 const vcardData = reader.readFromFile(files[i]);
114 if (!vcardData) {
115 console.debug("[ContentWorker] Could not read vCard file:", files[i])
116 continue;
117 }
118 // Simple Regex to extract EMAIL values from vCard
119 const emailRegex = /^EMAIL(?:;[^:]*)?:(.*)$/gm;
120 let match;
121 const emails = [];
122 while ((match = emailRegex.exec(vcardData)) !== null) {
123 const email = match[1].trim();
124 if (emails.indexOf(email) === -1) {
125 emails.push(email);
126 }
127 }
128 console.debug("[ContentWorker] Found emails:", JSON.stringify(emails))
129 if (emails.length === 1) {
130 ComposerActions.addRecipientFromAddress(recipientType, emails[0]);
131 } else if (emails.length > 1) {
132 const dialog = PopupUtils.open(emailSelectionComponent, rootItem, {"emailList": emails, "recipientType": recipientType})
133 dialog.emailSelected.connect(function(email, type) {
134 if (email) ComposerActions.addRecipientFromAddress(type, email)
135 })
136 }
137 }
138 reader.destroy();
139 }); // once contactsSelected
140 // Drop all callbacks if the picker is closed with no selections
141 once(ContentKeys.contactPickerClosed, exit.bind(this, 0))
142 }
143 }
144
145 Filter {
146 type: ContentKeys.openContactPicker
147 onDispatched: {
148 console.debug("[ContentWorker] openContactPicker dispatched")
149 const chPicker = PopupUtils.open(contactPickerComponent, message.root)
150 chPicker.contactsImported.connect(function(files) {
151 console.debug("[ContentWorker] contactsImported, files:", JSON.stringify(files))
152 ContentActions.contactsSelected(files)
153 })
154 }
155 }
156
157// Component {
158// id: fp
159// FilePickerDialog{}
160// }
161
162 Filter {
163 type: ContentKeys.openFilePicker
164 onDispatched: {
165 if (true) {
166 const chPicker = PopupUtils.open(chp, message.root, {isExport: false})
167 chPicker.filesImported.connect(function(files){
168 const imports = new Array()
169 for (let i in files) {
170 Log.logInfo("ContentManager::filesPicked", "File selected: %1".arg(files[i].url))
171 imports.push(files[i].url)
172 }
173 ContentActions.filesSelected(imports)
174 })
175 } else {
176 const c = Qt.createComponent("")
177 const filePicker = c.createObject(message.root)
178 filePicker.accepted.connect(function(){
179 const files = new Array()
180 for (let i in filePicker.fileUrls) {
181 Log.logInfo("ContentManager::filesPicked", "File selected: %1".arg(filePicker.fileUrls[i]))
182 files.push(filePicker.fileUrls[i])
183 }
184 ContentActions.filesSelected(files)
185 filePicker.close()
186 filePicker.destroy()
187 })
188 filePicker.rejected.connect(function() {
189 Log.logInfo("ContentManager::filePickerRejected", "No attachments selected")
190 ContentActions.pickerClosed()
191 })
192 }
193 }
194 }
195
196 Filter {
197 type: ContentKeys.importFromContentHub
198 onDispatched: {
199 if (message.transfer.length === 0) {
200 Log.logWarning("ContentManager::importFromContentHub", "Not items to transfer :-/")
201 return
202 }
203 Log.logInfo("ContentManager::importFromContentHub", "Number of transferred items: " + message.transfer.items.length)
204 // open the composer
205 ViewActions.delayCallWithArgs(ViewKeys.openComposer, {})
206 for (let item in message.transfer.items) {
207 const url = message.transfer.items[item].url
208 Log.logInfo("ContentManager::importFromContentHub", "Item url: " + url)
209 const text = message.transfer.items[item].text
210 Log.logInfo("ContentManager::importFromContentHub", "Item text: " + text)
211 switch (message.transfer.contentType) {
212 case ContentType.Links:
213 Log.logInfo("ContentManager::importFromContentHub", "ContentType is Link: " + url.toString())
214 ViewActions.delayCallWithArgs(ComposerKeys.appendTextToSubject, {text: text})
215 ViewActions.delayCallWithArgs(ComposerKeys.appendTextToBody, {text: url.toString()})
216 break;
217 case ContentType.Text:
218 Log.logInfo("ContentManager::importFromContentHub", "ContentType is Text: " + text)
219 ViewActions.delayCallWithArgs(ComposerKeys.appendTextToBody, {text: text})
220 break;
221 default:
222 const other = url.toString().replace("file://", "")
223 Log.logInfo("ContentManager::importFromContentHub", "ContentType is Other, most likely a file: " + other)
224 ComposerActions.addFileAttachment(other)
225 break;
226 }
227 }
228 }
229 }
230
231 Filter {
232 type: ContentKeys.exportFile
233 onDispatched: {
234 PopupUtils.open(chp, message.root, {fileUrl: message.file})
235 }
236 }
237}
238