Merge lp:~ken-vandine/webapps-core/facebook-userscript into lp:webapps-core

Proposed by Ken VanDine
Status: Merged
Merged at revision: 52
Proposed branch: lp:~ken-vandine/webapps-core/facebook-userscript
Merge into: lp:webapps-core
Diff against target: 604 lines (+518/-6)
8 files modified
webapp-facebook/content-hub/webapp-facebook.json (+5/-0)
webapp-facebook/manifest.json (+4/-4)
webapp-facebook/unity-webapps-facebook/HubSharer.qml (+65/-0)
webapp-facebook/unity-webapps-facebook/Share.qml (+383/-0)
webapp-facebook/unity-webapps-facebook/facebook.user.js (+51/-0)
webapp-facebook/unity-webapps-facebook/manifest.json (+7/-0)
webapp-facebook/webapp-facebook.desktop (+1/-1)
webapp-facebook/webapp-facebook.json (+2/-1)
To merge this branch: bzr merge lp:~ken-vandine/webapps-core/facebook-userscript
Reviewer Review Type Date Requested Status
David Barth Pending
Review via email: mp+223991@code.launchpad.net

Commit message

Implements a share handler in the facebook webapp.

Description of the change

Implements a share handler in the facebook webapp. This requires updates[1] to unity-webapps-qml to be fully functional.

[1] https://code.launchpad.net/~abreu-alexandre/unity-webapps-qml/add-content-hub-share

To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== added directory 'webapp-facebook/content-hub'
2=== added file 'webapp-facebook/content-hub/webapp-facebook.json'
3--- webapp-facebook/content-hub/webapp-facebook.json 1970-01-01 00:00:00 +0000
4+++ webapp-facebook/content-hub/webapp-facebook.json 2014-06-20 21:39:29 +0000
5@@ -0,0 +1,5 @@
6+{
7+ "share": [
8+ "pictures"
9+ ]
10+}
11
12=== modified file 'webapp-facebook/manifest.json'
13--- webapp-facebook/manifest.json 2014-06-20 13:54:52 +0000
14+++ webapp-facebook/manifest.json 2014-06-20 21:39:29 +0000
15@@ -1,11 +1,12 @@
16 {
17 "description": "Facebook (webapp version)",
18- "framework": "ubuntu-sdk-14.04-dev1",
19+ "framework": "ubuntu-sdk-14.10-dev1",
20 "architecture": "all",
21 "hooks": {
22 "webapp-facebook": {
23 "account-application": "webapp-facebook.application",
24- "account-service": "facebook-webapp.service",
25+ "content-hub": "content-hub/webapp-facebook.json",
26+ "account-service": "webapp-facebook.service",
27 "apparmor": "webapp-facebook.json",
28 "desktop": "webapp-facebook.desktop"
29 }
30@@ -13,6 +14,5 @@
31 "maintainer": "Webapps Team <webapps@lists.launchpad.net>",
32 "name": "com.ubuntu.developer.webapps.webapp-facebook",
33 "title": "webapp-facebook",
34- "version": "1.0.13"
35+ "version": "1.0.13.2"
36 }
37-
38
39=== added directory 'webapp-facebook/unity-webapps-facebook'
40=== added file 'webapp-facebook/unity-webapps-facebook/HubSharer.qml'
41--- webapp-facebook/unity-webapps-facebook/HubSharer.qml 1970-01-01 00:00:00 +0000
42+++ webapp-facebook/unity-webapps-facebook/HubSharer.qml 2014-06-20 21:39:29 +0000
43@@ -0,0 +1,65 @@
44+import QtQuick 2.0
45+import Ubuntu.Components 0.1
46+import Ubuntu.Content 0.1
47+
48+Item {
49+ id: main
50+ anchors.fill: parent
51+
52+ signal completed(string result, var uploadCompletedCallback)
53+
54+ property string fileToShare
55+
56+ function _callback(accessToken, fileToShare, message, uploadCompletedCallback) {
57+
58+ itemComp.url = fileToShare;
59+ var dataUri = itemComp.toDataURI();
60+ var result = {accessToken: accessToken,
61+ fileToShare: dataUri.toString(),
62+ message: message};
63+
64+ completed(JSON.stringify(result), uploadCompletedCallback);
65+ }
66+
67+ ContentItem {
68+ id: itemComp
69+ }
70+
71+ Rectangle {
72+ anchors.fill: parent
73+ color: UbuntuColors.lightGrey
74+
75+ Image {
76+ id: background
77+ anchors {
78+ left: parent.left
79+ right: parent.right
80+ bottom: parent.bottom
81+ }
82+ source: Qt.resolvedUrl("assets/background_full.png")
83+ }
84+ }
85+
86+ Share {
87+ id: share
88+ anchors.fill: parent
89+ visible: true
90+ fileToShare: main.fileToShare
91+ callback: _callback
92+ provider: "facebook"
93+ onCanceled: {
94+ completed(JSON.stringify({status: "cancelled"}), uploadCompleted);
95+ parent.destroy();
96+ }
97+ onUploadCompleted: {
98+ console.log (success);
99+ /* if the upload was successful, we need to destroy the parent */
100+ if (success) {
101+ parent.destroy();
102+ } else {
103+ console.error ("Upload failed");
104+ /* FIXME: Display a message to the user */
105+ }
106+ }
107+ }
108+}
109
110=== added file 'webapp-facebook/unity-webapps-facebook/Share.qml'
111--- webapp-facebook/unity-webapps-facebook/Share.qml 1970-01-01 00:00:00 +0000
112+++ webapp-facebook/unity-webapps-facebook/Share.qml 2014-06-20 21:39:29 +0000
113@@ -0,0 +1,383 @@
114+/*
115+ * Copyright (C) 2012-2013 Canonical, Ltd.
116+ *
117+ * This program is free software; you can redistribute it and/or modify
118+ * it under the terms of the GNU General Public License as published by
119+ * the Free Software Foundation; version 3.
120+ *
121+ * This program is distributed in the hope that it will be useful,
122+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
123+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
124+ * GNU General Public License for more details.
125+ *
126+ * You should have received a copy of the GNU General Public License
127+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
128+ */
129+
130+import QtQuick 2.0
131+import QtQuick.Window 2.0
132+import Ubuntu.Components 0.1
133+import Ubuntu.Components.ListItems 0.1 as ListItem
134+import Ubuntu.OnlineAccounts 0.1
135+import Ubuntu.OnlineAccounts.Client 0.1
136+
137+Item {
138+ id: root
139+ anchors.fill: parent
140+ property string fileToShare
141+ property var callback
142+ property string serviceType: "webapps"
143+ property string provider: "facebook"
144+ property string userAccountId
145+ property string accessToken
146+ property var account
147+ signal accountSelected
148+ signal canceled
149+ signal uploadCompleted(bool success)
150+
151+ onUploadCompleted: {
152+ activitySpinner.visible = false;
153+ if (success)
154+ print ("Successfully posted");
155+ else
156+ print ("Failed to post");
157+ }
158+
159+ AccountServiceModel {
160+ id: accounts
161+ serviceType: root.serviceType
162+ provider: root.provider
163+ Component.onCompleted: {
164+ if (count == 1) {
165+ srv.objectHandle = get(0, "accountServiceHandle");
166+ }
167+ }
168+ }
169+
170+ AccountService {
171+ id: srv
172+ onObjectHandleChanged: {
173+ root.account = srv;
174+ root.account.authenticate(null);
175+ }
176+ onAuthenticated: {
177+ root.userAccountId = accountId;
178+ root.accessToken = reply.AccessToken;
179+ shareComponent.visible = true;
180+ sharemenu.visible = false;
181+ }
182+ }
183+
184+ Item {
185+ id: shareComponent
186+ objectName: "shareComponent"
187+ anchors {
188+ left: parent.left
189+ right: parent.right
190+ }
191+ visible: false
192+
193+ Column {
194+ anchors.fill: parent
195+ spacing: units.gu(1)
196+
197+ Item {
198+ id: serviceHeader
199+ y: 0
200+ anchors.left: parent.left
201+ anchors.right: parent.right
202+ anchors.topMargin: units.gu(1)
203+ anchors.leftMargin: units.gu(1)
204+ anchors.rightMargin: units.gu(1)
205+ height: childrenRect.height
206+
207+ ListItem.Subtitled {
208+ anchors {
209+ left: parent.left
210+ right: parent.right
211+ }
212+ iconName: root.account.provider.iconName
213+ text: root.account.provider.displayName
214+ subText: root.account.displayName
215+ showDivider: false
216+ }
217+ }
218+
219+ ListItem.ThinDivider {}
220+
221+ UbuntuShape {
222+ id: messageArea
223+ objectName: "messageArea"
224+ anchors.left: parent.left
225+ anchors.right: parent.right
226+ anchors.topMargin: units.gu(1)
227+ anchors.leftMargin: units.gu(1)
228+ anchors.rightMargin: units.gu(1)
229+ height: units.gu(20)
230+ color: "#f2f2f2"
231+
232+ TextArea {
233+ id: message
234+ //color: "#333333"
235+ anchors.top: parent.top
236+ anchors.left: snapshot.right
237+ anchors.bottom: parent.bottom
238+ anchors.margins: units.gu(1)
239+ wrapMode: Text.Wrap
240+ width: parent.width - snapshot.width -
241+ snapshot.anchors.margins * 2 -
242+ message.anchors.leftMargin - message.anchors.rightMargin
243+ clip: true
244+ font.pixelSize: FontUtils.sizeToPixels("medium")
245+ font.weight: Font.Light
246+ focus: true
247+ }
248+
249+ ActivityIndicator {
250+ id: activitySpinner
251+ anchors.centerIn: message
252+ visible: false
253+ running: visible
254+ }
255+
256+ UbuntuShape {
257+ id: snapshot
258+ anchors.top: parent.top
259+ anchors.left: parent.left
260+ anchors.margins: units.gu(1)
261+ width: units.gu(10)
262+ height: units.gu(10)
263+
264+ image: Image {
265+ source: fileToShare
266+ sourceSize.height: snapshot.height
267+ sourceSize.width: snapshot.width
268+ fillMode: Image.PreserveAspectCrop
269+ }
270+ }
271+ }
272+
273+ Item {
274+ id: actionsBar
275+ anchors.left: parent.left
276+ anchors.right: parent.right
277+ anchors.topMargin: units.gu(2)
278+ anchors.leftMargin: units.gu(1)
279+ anchors.rightMargin: units.gu(1)
280+ height: childrenRect.height
281+
282+ Button {
283+ objectName: "cancelButton"
284+ anchors.left: parent.left
285+ text: i18n.dtr("ubuntu-ui-extras", "Cancel")
286+ color: "#cccccc"
287+ width: units.gu(10)
288+ height: units.gu(4)
289+ onClicked: canceled()
290+ }
291+
292+ Button {
293+ objectName: "postButton"
294+ anchors.right: parent.right
295+ anchors.top: parent.top
296+ text: i18n.dtr("ubuntu-ui-extras", "Post")
297+ color: "#dd4814"
298+ width: units.gu(10)
299+ height: units.gu(4)
300+ enabled: !activitySpinner.visible
301+ onClicked: {
302+ activitySpinner.visible = true;
303+ callback(accessToken, fileToShare, message.text, uploadCompleted);
304+ }
305+ }
306+ }
307+
308+ // toggle to enable including location - Not implemented yet
309+ /*
310+ UbuntuShape {
311+ id: useLocation
312+ anchors {
313+ left: parent.left
314+ leftMargin: units.gu(1)
315+ topMargin: units.gu(1)
316+ }
317+ color: selected ? "#cccccc" : "transparent"
318+ property bool selected: false
319+ width: units.gu(4.5)
320+ height: units.gu(4)
321+
322+ AbstractButton {
323+ anchors.fill: parent
324+ onClicked: parent.selected = !parent.selected
325+ Image {
326+ source: "assets/icon_location.png"
327+ anchors.centerIn: parent
328+ height: parent.height * 0.75
329+ fillMode: Image.PreserveAspectFit
330+ smooth: true
331+ }
332+ }
333+ }
334+
335+ Label {
336+ anchors.left: useLocation.right
337+ anchors.baseline: useLocation.top
338+ anchors.baselineOffset: units.gu(3)
339+ anchors.leftMargin: units.gu(1)
340+ text: i18n.dtr("ubuntu-ui-extras", "Include location")
341+ fontSize: "small"
342+ }
343+ */
344+ // End location toggle
345+
346+ }
347+
348+ states: [
349+ State {
350+ name: "landscape-with-keyborad"
351+ PropertyChanges {
352+ target: serviceHeader
353+ y: - serviceHeader.height
354+ }
355+ PropertyChanges {
356+ target: messageArea
357+ height: units.gu(12)
358+ }
359+ }
360+ ]
361+
362+ state: ((Screen.orientation === Qt.LandscapeOrientation) ||
363+ (Screen.orientation === Qt.InvertedLandscapeOrientation)) &&
364+ Qt.inputMethod.visible ? "landscape-with-keyborad" : ""
365+ }
366+
367+ /* Menu listing online accounts */
368+ Item {
369+ id: sharemenu
370+ anchors.fill: parent
371+ visible: true
372+
373+ signal selected(string accountId, string token)
374+
375+ Component.onCompleted: {
376+ visible = true;
377+ }
378+ onSelected: {
379+ root.userAccountId = accountId;
380+ root.accessToken = token;
381+ shareComponent.visible = true;
382+ sharemenu.visible = false;
383+ }
384+
385+ Component {
386+ id: acctDelegate
387+ Item {
388+ anchors {
389+ left: parent.left
390+ right: parent.right
391+ }
392+ AccountService {
393+ id: service
394+ objectHandle: accountServiceHandle
395+ onAuthenticated: {
396+ sharemenu.selected(accountId, reply.AccessToken);
397+ }
398+ }
399+
400+ height: childrenRect.height
401+
402+ ListItem.Subtitled {
403+ anchors {
404+ left: parent.left
405+ right: parent.right
406+ }
407+ text: service.provider.displayName
408+ subText: displayName
409+ iconName: service.provider.iconName
410+ __iconHeight: units.gu(5)
411+ __iconWidth: units.gu(5)
412+
413+ onClicked: {
414+ root.account = service;
415+ root.account.authenticate(null);
416+ }
417+ }
418+ }
419+ }
420+
421+ ListView {
422+ anchors {
423+ top: parent.top
424+ left: parent.left
425+ right: parent.right
426+ }
427+ height: childrenRect.height
428+ interactive: false
429+ visible: !listView.visible
430+ model: accounts
431+ header: ListItem.Header {
432+ anchors {
433+ left: parent.left
434+ right: parent.right
435+ }
436+ text: i18n.tr("Select account")
437+ }
438+ delegate: acctDelegate
439+ }
440+
441+ ListView {
442+ id: listView
443+ anchors {
444+ top: parent.top
445+ left: parent.left
446+ right: parent.right
447+ }
448+ height: childrenRect.height
449+ header: headerComponent
450+ model: providerModel
451+ visible: accounts.count === 0
452+ delegate: providerDelegate
453+
454+ Component {
455+ id: headerComponent
456+ ListItem.Header {
457+ anchors {
458+ left: parent.left
459+ right: parent.right
460+ }
461+ text: i18n.tr("No online accounts configured")
462+ }
463+ }
464+
465+ Component {
466+ id: providerDelegate
467+ Item {
468+ anchors {
469+ left: parent.left
470+ right: parent.right
471+ }
472+ height: childrenRect.height
473+ ListItem.Standard {
474+ text: model.displayName
475+ iconName: model.iconName
476+ onClicked: {
477+ setup.providerId = providerId
478+ setup.exec()
479+ }
480+ }
481+ }
482+ }
483+
484+
485+ ProviderModel {
486+ id: providerModel
487+ applicationId: "com.ubuntu.developer.webapps.webapp-facebook_webapp-facebook"
488+ }
489+
490+ Setup {
491+ id: setup
492+ applicationId: "com.ubuntu.developer.webapps.webapp-facebook_webapp-facebook"
493+ }
494+ }
495+ }
496+}
497
498=== added directory 'webapp-facebook/unity-webapps-facebook/assets'
499=== added file 'webapp-facebook/unity-webapps-facebook/assets/avatar_image.jpg'
500Binary files webapp-facebook/unity-webapps-facebook/assets/avatar_image.jpg 1970-01-01 00:00:00 +0000 and webapp-facebook/unity-webapps-facebook/assets/avatar_image.jpg 2014-06-20 21:39:29 +0000 differ
501=== added file 'webapp-facebook/unity-webapps-facebook/assets/background_full@27.png'
502Binary files webapp-facebook/unity-webapps-facebook/assets/background_full@27.png 1970-01-01 00:00:00 +0000 and webapp-facebook/unity-webapps-facebook/assets/background_full@27.png 2014-06-20 21:39:29 +0000 differ
503=== added file 'webapp-facebook/unity-webapps-facebook/assets/icon_location.png'
504Binary files webapp-facebook/unity-webapps-facebook/assets/icon_location.png 1970-01-01 00:00:00 +0000 and webapp-facebook/unity-webapps-facebook/assets/icon_location.png 2014-06-20 21:39:29 +0000 differ
505=== added file 'webapp-facebook/unity-webapps-facebook/facebook.user.js'
506--- webapp-facebook/unity-webapps-facebook/facebook.user.js 1970-01-01 00:00:00 +0000
507+++ webapp-facebook/unity-webapps-facebook/facebook.user.js 2014-06-20 21:39:29 +0000
508@@ -0,0 +1,51 @@
509+var api = external.getUnityObject('1.0');
510+var hub = api.ContentHub;
511+var activeTransfer;
512+
513+function _shareRequested(transfer) {
514+ activeTransfer = transfer;
515+ transfer.items(function(items) {
516+ api.launchEmbeddedUI("HubSharer", upload, {"fileToShare": items[0]});
517+ });
518+};
519+
520+hub.onShareRequested(_shareRequested);
521+
522+function upload(res, uploadCompletedCallback) {
523+ var results = JSON.parse(res);
524+ if (results.status == "cancelled")
525+ activeTransfer.setState(hub.ContentTransfer.State.Aborted);
526+
527+ var xhr = new XMLHttpRequest();
528+ xhr.open( 'POST', 'https://graph.facebook.com/me/photos?access_token=' + results.accessToken, true );
529+ xhr.onload = xhr.onerror = function() {
530+ if ( xhr.status == 200 ) {
531+ uploadCompletedCallback(true);
532+ window.location.reload();
533+ } else {
534+ uploadCompletedCallback(false);
535+ }
536+ };
537+
538+ var contentType = results.fileToShare.split(',')[0].split(':')[1];
539+ var b64data = results.fileToShare.split(',')[1];
540+
541+ var byteCharacters = atob(b64data);
542+ var byteNumbers = new Array(byteCharacters.length);
543+ for (var i = 0; i < byteCharacters.length; i++) {
544+ byteNumbers[i] = byteCharacters.charCodeAt(i);
545+ }
546+ var byteArray = new Uint8Array(byteNumbers);
547+
548+ var div = document.createElement('div');
549+ div.innerHTML = '<form enctype="multipart/form-data" method="post" id="uploadForm"><textarea id="message" name="message"></textarea></form>';
550+ document.getElementsByTagName('body')[0].appendChild(div);
551+
552+ var blob = new Blob([byteArray], {type: contentType});
553+
554+ var uploadForm = document.forms.namedItem("uploadForm");
555+ var formData = new FormData(uploadForm);
556+ formData.append('source', blob);
557+ formData.append('message', results.message);
558+ xhr.send(formData);
559+}
560
561=== added file 'webapp-facebook/unity-webapps-facebook/manifest.json'
562--- webapp-facebook/unity-webapps-facebook/manifest.json 1970-01-01 00:00:00 +0000
563+++ webapp-facebook/unity-webapps-facebook/manifest.json 2014-06-20 21:39:29 +0000
564@@ -0,0 +1,7 @@
565+{
566+ "name": "facebook",
567+ "includes": ["https://*.facebook.com/*"],
568+ "homepage": "https://m.facebook.com/",
569+ "domain": "facebook.com",
570+ "scripts": ["facebook.user.js"]
571+}
572
573=== modified file 'webapp-facebook/webapp-facebook.desktop'
574--- webapp-facebook/webapp-facebook.desktop 2014-06-20 13:54:52 +0000
575+++ webapp-facebook/webapp-facebook.desktop 2014-06-20 21:39:29 +0000
576@@ -1,7 +1,7 @@
577 [Desktop Entry]
578 Type=Application
579 Terminal=false
580-Exec=webapp-container --enable-back-forward --popup-redirection-url-prefix=http://lm.facebook.com/l.php?u= --webappUrlPatterns=https?://*.facebook.com/* https://m.facebook.com/
581+Exec=webapp-container --enable-back-forward --popup-redirection-url-prefix=http://lm.facebook.com/l.php?u= --webapp='ZmFjZWJvb2s=' --webappModelSearchPath=. --webappUrlPatterns=https?://*.facebook.com/* https://m.facebook.com/
582 Name=Facebook
583 Icon=./facebook.png
584 X-Ubuntu-Touch=true
585
586=== modified file 'webapp-facebook/webapp-facebook.json'
587--- webapp-facebook/webapp-facebook.json 2014-04-10 21:52:56 +0000
588+++ webapp-facebook/webapp-facebook.json 2014-06-20 21:39:29 +0000
589@@ -2,11 +2,12 @@
590 "template": "ubuntu-webapp",
591 "policy_groups": [
592 "networking",
593+ "accounts",
594 "audio",
595 "video",
596 "webview",
597 "location",
598 "content_exchange"
599 ],
600- "policy_version": 1.1
601+ "policy_version": 1.2
602 }
603
604=== renamed file 'webapp-facebook/facebook-webapp.service' => 'webapp-facebook/webapp-facebook.service'

Subscribers

People subscribed via source and target branches

to all changes: