Merge lp:~abreu-alexandre/unity-webapps-qml/new-content-hub-api into lp:unity-webapps-qml
- new-content-hub-api
- Merge into trunk
Status: | Merged |
---|---|
Approved by: | Alberto Mardegan |
Approved revision: | 101 |
Merged at revision: | 98 |
Proposed branch: | lp:~abreu-alexandre/unity-webapps-qml/new-content-hub-api |
Merge into: | lp:unity-webapps-qml |
Diff against target: |
1352 lines (+828/-191) 6 files modified
examples/api-bindings/content-hub/www/js/app.js (+30/-53) examples/api-bindings/content-peer-picker/main.qml.in (+32/-0) examples/api-bindings/content-peer-picker/www/index.html (+33/-0) examples/api-bindings/content-peer-picker/www/js/app.js (+104/-0) src/Ubuntu/UnityWebApps/UnityWebAppsBackendComponents.js (+342/-66) src/Ubuntu/UnityWebApps/bindings/content-hub/client/content-hub.js (+287/-72) |
To merge this branch: | bzr merge lp:~abreu-alexandre/unity-webapps-qml/new-content-hub-api |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Alberto Mardegan (community) | Approve | ||
PS Jenkins bot (community) | continuous-integration | Approve | |
WebApps | Pending | ||
Review via email: mp+211165@code.launchpad.net |
Commit message
Add support for the new content hub api
Description of the change
Add support for the new content hub api.
You need https:/
- Testing the feature
-------
you have the examples/
- content-hub: example of an import application. It lists the potential sources for images,
- content-
APP_ID=
- content-hub-picker: example of an application that uses the Content Peer Picker UI,
- Automated/unit tests
-------
Another branch will land that adds integration tests for all API components, which is why
no tests have been added/updated,
PS Jenkins bot (ps-jenkins) wrote : | # |
Alberto Mardegan (mardy) wrote : | # |
L646: + if (this._
I guess you wanted "if (!..."
L670: Isn't it possible to avoid building the code this way, and use backendDelegate
L673-678 (but also later): I'd put the ";" at the end of the line, rather than at the beginning. Otherwise if the first filter is not set and the second one is, you'd end up with code like "ContentPeerModel { ; handler: ..."
L952: I guess the result of the expression must be a boolean, so maybe write it as
this.
I didn't test it yet, will do that soon.
Alberto Mardegan (mardy) wrote : | # |
I tested it, and the examples work.
- 101. By Alexandre Abreu
-
fixes
Alexandre Abreu (abreu-alexandre) wrote : | # |
> L646: + if (this._
> I guess you wanted "if (!..."
right, done
> L670: Isn't it possible to avoid building the code this way, and use
> backendDelegate
> guess you had your reasons not to do it this way, please explain :-) )
sure, the issue is w/ the plugin specific types that are not js builtins.
Things work find w/ the backend.create[..] when you have builtin types but
it is not really meant to specify custom type params like ContentType.
Those have to be handled specifically, hence the lousy creation steps,
>
> L673-678 (but also later): I'd put the ";" at the end of the line, rather than
> at the beginning. Otherwise if the first filter is not set and the second one
> is, you'd end up with code like "ContentPeerModel { ; handler: ..."
right, done
> L952: I guess the result of the expression must be a boolean, so maybe write
> it as
> this._isDefaultPeer = content && content.
done
PS Jenkins bot (ps-jenkins) wrote : | # |
PASSED: Continuous integration, rev:101
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild:
http://
Preview Diff
1 | === modified file 'examples/api-bindings/content-hub/www/js/app.js' |
2 | --- examples/api-bindings/content-hub/www/js/app.js 2014-02-11 09:18:34 +0000 |
3 | +++ examples/api-bindings/content-hub/www/js/app.js 2014-03-18 13:59:59 +0000 |
4 | @@ -6,32 +6,18 @@ |
5 | var pictureContentType = hub.ContentType.Pictures; |
6 | |
7 | var sourcePeers = {}; |
8 | - hub.knownSourcesForType( |
9 | - pictureContentType |
10 | + hub.getPeers( |
11 | + {contentType: hub.ContentType.Pictures} |
12 | , function (peers) { |
13 | + if ( ! peers.length) |
14 | + return; |
15 | + |
16 | for (var j = 0; j < peers.length; ++j) { |
17 | addPeerElement(peers[j].appId(), peers[j].name()); |
18 | sourcePeers[peers[j].appId()] = peers[j]; |
19 | } |
20 | - |
21 | - console.log('peers defaultSourceForType: ' + peers) |
22 | - |
23 | - hub.defaultSourceForType( |
24 | - pictureContentType |
25 | - , function(peer) { |
26 | - if (peer) { |
27 | - addPeerElement(peer.appId(), peer.name()); |
28 | - sourcePeers[peer.appId()] = peer; |
29 | - } |
30 | - |
31 | - if (Object.keys(sourcePeers).length === 0) { |
32 | - nopeers(); |
33 | - return; |
34 | - } |
35 | - document.getElementById('importdiv').style.display = 'block'; |
36 | - document.getElementById('lowLevelImportdiv').style.display = 'block'; |
37 | - } |
38 | - ); |
39 | + document.getElementById('importdiv').style.display = 'block'; |
40 | + document.getElementById('lowLevelImportdiv').style.display = 'block'; |
41 | }); |
42 | |
43 | document.getElementById('import').addEventListener('click', doSimpleApiImport); |
44 | @@ -132,7 +118,7 @@ |
45 | |
46 | hub.api.importContent(pictureContentType |
47 | , peer |
48 | - , {importToLocalStore: true} |
49 | + , {scope: hub.ContentScope.App} |
50 | , function(items) { |
51 | for (var i = 0; i < items.length; ++i) { |
52 | addResult(items[i]); |
53 | @@ -159,40 +145,31 @@ |
54 | return; |
55 | } |
56 | |
57 | - hub.importContentForPeer( |
58 | - pictureContentType, |
59 | - peer, |
60 | - function(transfer) { |
61 | - |
62 | - hub.defaultStoreForType(pictureContentType, function(store) { |
63 | - transfer.setStore(store, function() { |
64 | - |
65 | - transfer.start(function(state) { |
66 | - if (transferState.Aborted === state) { |
67 | - transfer.finalize(); |
68 | - peer.destroy(); |
69 | - transfer.destroy(); |
70 | - aborted(); |
71 | - return; |
72 | - } |
73 | - |
74 | - if (transferState.Charged === state) { |
75 | - transfer.items(function(items) { |
76 | - for (var i = 0; i < items.length; ++i) { |
77 | - addResult(items[i]); |
78 | - } |
79 | - transfer.finalize(); |
80 | - peer.destroy(); |
81 | - transfer.destroy(); |
82 | - }); |
83 | - } |
84 | + hub.getStore(hub.ContentScope.App, function(store) { |
85 | + peer.requestForStore(store, function(transfer) { |
86 | + transfer.start(function(state) { |
87 | + if (transferState.Aborted === state) { |
88 | + transfer.finalize(); |
89 | + peer.destroy(); |
90 | + transfer.destroy(); |
91 | + aborted(); |
92 | + return; |
93 | + } |
94 | + |
95 | + if (transferState.Charged === state) { |
96 | + transfer.items(function(items) { |
97 | + for (var i = 0; i < items.length; ++i) { |
98 | + addResult(items[i]); |
99 | + } |
100 | + transfer.finalize(); |
101 | + peer.destroy(); |
102 | + transfer.destroy(); |
103 | }); |
104 | - }); |
105 | - |
106 | + } |
107 | }); |
108 | |
109 | - } |
110 | - ); |
111 | + }); |
112 | + }); |
113 | }; |
114 | }; |
115 | |
116 | |
117 | === added directory 'examples/api-bindings/content-peer-picker' |
118 | === added file 'examples/api-bindings/content-peer-picker/main.qml.in' |
119 | --- examples/api-bindings/content-peer-picker/main.qml.in 1970-01-01 00:00:00 +0000 |
120 | +++ examples/api-bindings/content-peer-picker/main.qml.in 2014-03-18 13:59:59 +0000 |
121 | @@ -0,0 +1,32 @@ |
122 | +import QtQuick 2.0 |
123 | +import QtWebKit 3.0 |
124 | +import QtWebKit.experimental 1.0 |
125 | +import Ubuntu.Components 0.1 |
126 | +import Ubuntu.UnityWebApps 0.1 |
127 | + |
128 | +MainView { |
129 | + id: root |
130 | + focus: true |
131 | + applicationName: \"helloworld\" |
132 | + |
133 | + width: units.gu(100) |
134 | + height: units.gu(100) |
135 | + |
136 | + WebView { |
137 | + id: webview |
138 | + anchors.fill: parent |
139 | + url: \"file://$$OUT_PWD/content-hub/www/index.html\" |
140 | + |
141 | + experimental.preferences.navigatorQtObjectEnabled: true |
142 | + experimental.preferences.developerExtrasEnabled: true |
143 | + |
144 | + function getUnityWebappsProxies() { |
145 | + return UnityWebAppsUtils.makeProxiesForQtWebViewBindee(webview); |
146 | + } |
147 | + |
148 | + UnityWebApps { |
149 | + id: webapps |
150 | + bindee: webview |
151 | + } |
152 | + } |
153 | +} |
154 | |
155 | === added directory 'examples/api-bindings/content-peer-picker/www' |
156 | === added file 'examples/api-bindings/content-peer-picker/www/index.html' |
157 | --- examples/api-bindings/content-peer-picker/www/index.html 1970-01-01 00:00:00 +0000 |
158 | +++ examples/api-bindings/content-peer-picker/www/index.html 2014-03-18 13:59:59 +0000 |
159 | @@ -0,0 +1,33 @@ |
160 | +<html> |
161 | + |
162 | + <head> |
163 | + <title>Content Hub: Content Peer Picker example</title> |
164 | + <script src="./js/app.js"></script> |
165 | + </head> |
166 | + |
167 | + <style> |
168 | + |
169 | + .selected { background-color: red; } |
170 | + |
171 | + </style> |
172 | + |
173 | + <body> |
174 | + <div> |
175 | + Start Content Peer picking to import content: <input type="button" id="pick"></input> |
176 | + </div> |
177 | + |
178 | + <div> |
179 | + Selected peer: |
180 | + <div id="selected-peer"> |
181 | + </div> |
182 | + </div> |
183 | + |
184 | + <div> |
185 | + Imported Image: |
186 | + <div id="results"> |
187 | + </div> |
188 | + </div> |
189 | + |
190 | + </body> |
191 | + |
192 | +</html> |
193 | |
194 | === added directory 'examples/api-bindings/content-peer-picker/www/js' |
195 | === added file 'examples/api-bindings/content-peer-picker/www/js/app.js' |
196 | --- examples/api-bindings/content-peer-picker/www/js/app.js 1970-01-01 00:00:00 +0000 |
197 | +++ examples/api-bindings/content-peer-picker/www/js/app.js 2014-03-18 13:59:59 +0000 |
198 | @@ -0,0 +1,104 @@ |
199 | +window.onload = function() { |
200 | + var api = external.getUnityObject('1.0'); |
201 | + var hub = api.ContentHub; |
202 | + |
203 | + var transferState = hub.ContentTransfer.State; |
204 | + var pictureContentType = hub.ContentType.Pictures; |
205 | + |
206 | + document.getElementById('pick').addEventListener('click', doContentPeerPicking); |
207 | + function doContentPeerPicking() { |
208 | + hub.launchContentPeerPicker( |
209 | + { |
210 | + contentType: hub.ContentType.Pictures, |
211 | + handler: hub.ContentHandler.Source, |
212 | + }, |
213 | + function(peer) { |
214 | + if ( ! peer) { |
215 | + nopeers(); |
216 | + return; |
217 | + } |
218 | + addPeerElement(peer.appId(), peer.name()); |
219 | + doSimpleApiImport(peer); |
220 | + }, |
221 | + function() { |
222 | + aborted(); |
223 | + }); |
224 | + }; |
225 | + |
226 | + function addPeerElement(appId, name) { |
227 | + var selectedpeer = document.querySelector('#selected-peer'); |
228 | + var span = document.createElement('span'); |
229 | + |
230 | + var text = document.createTextNode('appId: ' + appId + ', name: ' + name) |
231 | + span.appendChild(text); |
232 | + selectedpeer.appendChild(span); |
233 | + }; |
234 | + |
235 | + var results = []; |
236 | + function addResult(item) { |
237 | + results.push({name: item.name, url: item.url}); |
238 | + renderResults(results); |
239 | + }; |
240 | + |
241 | + function displayImages(images) { |
242 | + var res = document.getElementById('results'); |
243 | + for (var i = 0; i < images.length; ++i) { |
244 | + var img = document.createElement('img'); |
245 | + |
246 | + img.setAttribute('src', images[i].url); |
247 | + img.setAttribute('height', '100px'); |
248 | + img.setAttribute('width', '100px'); |
249 | + |
250 | + if (images[i].name && images[i].name.length !== 0) |
251 | + img.setAttribute('alt', images[i].name); |
252 | + |
253 | + res.appendChild(img); |
254 | + } |
255 | + }; |
256 | + |
257 | + function aborted() { |
258 | + setResults('Transfer aborted'); |
259 | + }; |
260 | + |
261 | + function nopeers() { |
262 | + setResults('No peers found'); |
263 | + }; |
264 | + |
265 | + function setResults(results) { |
266 | + var resultEl = document.getElementById('results'); |
267 | + resultEl.innerHTML = results; |
268 | + }; |
269 | + |
270 | + function formatResults(results) { |
271 | + var content = '<ul>'; |
272 | + for (var i = 0; i < results.length; ++i) { |
273 | + content += '<li>' |
274 | + + results[i].name |
275 | + + ', ' |
276 | + + results[i].url |
277 | + + '</li>'; |
278 | + } |
279 | + content += '</ul>'; |
280 | + return content; |
281 | + }; |
282 | + |
283 | + function renderResults(results) { |
284 | + setResults(formatResults(results)); |
285 | + displayImages(results); |
286 | + }; |
287 | + |
288 | + function doSimpleApiImport(peer) { |
289 | + hub.api.importContent(pictureContentType |
290 | + , peer |
291 | + , {scope: hub.ContentScope.App} |
292 | + , function(items) { |
293 | + for (var i = 0; i < items.length; ++i) { |
294 | + addResult(items[i]); |
295 | + } |
296 | + } |
297 | + , function() { |
298 | + aborted(); |
299 | + }); |
300 | + }; |
301 | +}; |
302 | + |
303 | |
304 | === modified file 'src/Ubuntu/UnityWebApps/UnityWebAppsBackendComponents.js' |
305 | --- src/Ubuntu/UnityWebApps/UnityWebAppsBackendComponents.js 2014-02-26 13:21:37 +0000 |
306 | +++ src/Ubuntu/UnityWebApps/UnityWebAppsBackendComponents.js 2014-03-18 13:59:59 +0000 |
307 | @@ -201,6 +201,14 @@ |
308 | return {object: this._objects[id], id: id}; |
309 | }, |
310 | |
311 | + parent: function() { |
312 | + return this._parent; |
313 | + }, |
314 | + |
315 | + parentView: function() { |
316 | + return this._parent ? this._parent.bindee : null; |
317 | + }, |
318 | + |
319 | isObjectProxyInfo: function(info) { |
320 | return 'type' in info && |
321 | info.type === 'object-proxy' && |
322 | @@ -1308,14 +1316,32 @@ |
323 | // TODO find a better way |
324 | function _nameToContentType(name) { |
325 | var contentTypePerName = { |
326 | + "All": ContentHubBridge.ContentType.All, |
327 | + "Unknown": ContentHubBridge.ContentType.Unknown, |
328 | "Pictures": ContentHubBridge.ContentType.Pictures, |
329 | - "Documents": ContentHubBridge.ContentType.Pictures, |
330 | - "Music": ContentHubBridge.ContentType.Pictures, |
331 | + "Documents": ContentHubBridge.ContentType.Documents, |
332 | + "Music": ContentHubBridge.ContentType.Music, |
333 | + "Contacts": ContentHubBridge.ContentType.Contacts, |
334 | }; |
335 | return name in contentTypePerName ? |
336 | contentTypePerName[name] |
337 | : ContentHubBridge.ContentType.Unknown; |
338 | }; |
339 | + function _contentTypeToName(state) { |
340 | + if (state === ContentHubBridge.ContentType.All) |
341 | + return "All"; |
342 | + else if (state === ContentHubBridge.ContentType.Unknown) |
343 | + return "Unknown"; |
344 | + else if (state === ContentHubBridge.ContentType.Pictures) |
345 | + return "Pictures"; |
346 | + else if (state === ContentHubBridge.ContentType.Documents) |
347 | + return "Documents"; |
348 | + else if (state === ContentHubBridge.ContentType.Music) |
349 | + return "Music"; |
350 | + else if (state === ContentHubBridge.ContentType.Contacts) |
351 | + return "Contacts"; |
352 | + return "Unknown"; |
353 | + }; |
354 | |
355 | function _nameToContentTransferSelection(name) { |
356 | var contentTypePerName = { |
357 | @@ -1334,10 +1360,31 @@ |
358 | return "Single"; |
359 | }; |
360 | |
361 | + function _nameToContentHandler(name) { |
362 | + var contentHandlerPerName = { |
363 | + "Source": ContentHubBridge.ContentHandler.Source, |
364 | + "Destination": ContentHubBridge.ContentHandler.Destination, |
365 | + "Share": ContentHubBridge.ContentHandler.Share, |
366 | + }; |
367 | + return name in contentHandlerPerName ? |
368 | + contentHandlerPerName[name] |
369 | + : ContentHubBridge.ContentHandler.Source; |
370 | + }; |
371 | + function _contentHandlerToName(state) { |
372 | + if (state === ContentHubBridge.ContentHandler.Source) |
373 | + return "Source"; |
374 | + else if (state === ContentHubBridge.ContentHandler.Destination) |
375 | + return "Destination"; |
376 | + else if (state === ContentHubBridge.ContentHandler.Share) |
377 | + return "Share"; |
378 | + return "Source"; |
379 | + }; |
380 | + |
381 | function _nameToContentTransferDirection(name) { |
382 | var contentTypePerName = { |
383 | "Import": ContentHubBridge.ContentTransfer.Import, |
384 | "Export": ContentHubBridge.ContentTransfer.Export, |
385 | + "Share": ContentHubBridge.ContentTransfer.Share, |
386 | }; |
387 | return name in contentTypePerName ? |
388 | contentTypePerName[name] |
389 | @@ -1348,9 +1395,31 @@ |
390 | return "Import"; |
391 | else if (state === ContentHubBridge.ContentTransfer.Export) |
392 | return "Export"; |
393 | + else if (state === ContentHubBridge.ContentTransfer.Share) |
394 | + return "Share"; |
395 | return "Import"; |
396 | }; |
397 | |
398 | + function _nameToContentScope(name) { |
399 | + var contentScopePerName = { |
400 | + "System": ContentHubBridge.ContentScope.System, |
401 | + "User": ContentHubBridge.ContentScope.User, |
402 | + "App": ContentHubBridge.ContentScope.App, |
403 | + }; |
404 | + return name in contentScopePerName ? |
405 | + contentScopePerName[name] |
406 | + : ContentHubBridge.ContentScope.App; |
407 | + }; |
408 | + function _contentScopeToName(state) { |
409 | + if (state === ContentHubBridge.ContentScope.System) |
410 | + return "System"; |
411 | + else if (state === ContentHubBridge.ContentScope.User) |
412 | + return "User"; |
413 | + else if (state === ContentHubBridge.ContentScope.App) |
414 | + return "App"; |
415 | + return "App"; |
416 | + }; |
417 | + |
418 | function _nameToContentTransferState(name) { |
419 | var contentTransferStatePerName = { |
420 | "Created": ContentHubBridge.ContentTransfer.Created, |
421 | @@ -1426,6 +1495,8 @@ |
422 | content: { |
423 | store: self._object.store, |
424 | state: self._object.state, |
425 | + selectionType: self._object.selectionType, |
426 | + direction: self._object.direction, |
427 | } |
428 | } |
429 | }, |
430 | @@ -1461,6 +1532,15 @@ |
431 | if (callback && typeof(callback) === 'function') |
432 | callback(); |
433 | }, |
434 | + onStateChanged: function(callback) { |
435 | + if (!callback || typeof(callback) !== 'function') |
436 | + return; |
437 | + this._validate(); |
438 | + var self = this; |
439 | + this._object.onStateChanged.connect(function() { |
440 | + callback(_contentTransferStateToName(self._object.state)); |
441 | + }); |
442 | + }, |
443 | |
444 | selectionType: function(callback) { |
445 | this._validate(); |
446 | @@ -1504,16 +1584,11 @@ |
447 | item.object.name = items[i].name; |
448 | item.object.url = items[i].url; |
449 | |
450 | - console.debug('setItems: adding item ' + item.object.name.toString() |
451 | - + ', ' + item.object.url.toString()); |
452 | - |
453 | contentItems.push(item.object); |
454 | } |
455 | |
456 | this._object.items = contentItems; |
457 | |
458 | - console.debug('setItems: grand total of ' + this._object.items.length + ' added'); |
459 | - |
460 | if (callback && typeof(callback) === 'function') |
461 | callback(); |
462 | }, |
463 | @@ -1593,12 +1668,24 @@ |
464 | |
465 | content: { |
466 | uri: self._object.uri, |
467 | + scope: _contentScopeToName(self._object.scope), |
468 | } |
469 | } |
470 | }, |
471 | |
472 | // properties |
473 | |
474 | + scope: function(callback) { |
475 | + this._validate(); |
476 | + callback(_contentScopeToName(this._object.scope)); |
477 | + }, |
478 | + setScope: function(scope, callback) { |
479 | + this._validate(); |
480 | + this._object.scope = _nameToContentScope(scope); |
481 | + if (callback && typeof(callback) === 'function') |
482 | + callback(); |
483 | + }, |
484 | + |
485 | //immutable |
486 | uri: function(callback) { |
487 | this._validate(); |
488 | @@ -1648,23 +1735,165 @@ |
489 | content: { |
490 | appId: self._object.appId, |
491 | name: self._object.name, |
492 | + handler: self._object.handler, |
493 | + contentType: self._object.contentType, |
494 | + selectionType: self._object.selectionType, |
495 | + isDefaultPeer: self._object.isDefaultPeer, |
496 | }, |
497 | } |
498 | }, |
499 | |
500 | // properties |
501 | |
502 | - // immutable |
503 | appId: function(callback) { |
504 | this._validate(); |
505 | callback(this._object.appId); |
506 | }, |
507 | + setAppId: function(appId, callback) { |
508 | + this._validate(); |
509 | + this._object.appId = appId; |
510 | + if (callback && typeof(callback) === 'function') |
511 | + callback(); |
512 | + }, |
513 | + |
514 | + handler: function(callback) { |
515 | + this._validate(); |
516 | + callback(_contentHandlerToName(this._object.handler)); |
517 | + }, |
518 | + setHandler: function(handler, callback) { |
519 | + this._validate(); |
520 | + this._object.handler = _nameToContentHandler(handler); |
521 | + if (callback && typeof(callback) === 'function') |
522 | + callback(); |
523 | + }, |
524 | + |
525 | + contentType: function(callback) { |
526 | + this._validate(); |
527 | + callback(_contentTypeToName(this._object.contentType)); |
528 | + }, |
529 | + setContentType: function(contentType, callback) { |
530 | + this._validate(); |
531 | + this._object.contentType = _nameToContentType(contentType); |
532 | + if (callback && typeof(callback) === 'function') |
533 | + callback(); |
534 | + }, |
535 | + |
536 | + selectionType: function(callback) { |
537 | + this._validate(); |
538 | + callback(_contentTransferSelectionToName(this._object.selectionType)); |
539 | + }, |
540 | + setSelectionType: function(selectionType, callback) { |
541 | + this._validate(); |
542 | + this._object.selectionType = _nameToContentTransferSelection(selectionType); |
543 | + if (callback && typeof(callback) === 'function') |
544 | + callback(); |
545 | + }, |
546 | |
547 | // immutable |
548 | name: function(callback) { |
549 | this._validate(); |
550 | callback(this._object.name); |
551 | }, |
552 | + |
553 | + isDefaultPeer: function(callback) { |
554 | + this._validate(); |
555 | + callback(this._object.isDefaultPeer); |
556 | + }, |
557 | + |
558 | + // methods |
559 | + |
560 | + request: function(callback) { |
561 | + this._validate(); |
562 | + var transfer = new ContentTransfer(this._object.request()); |
563 | + |
564 | + if (callback && typeof(callback) === 'function') |
565 | + callback(transfer.serialize()); |
566 | + }, |
567 | + |
568 | + requestForStore: function(store, callback) { |
569 | + if ( ! store) { |
570 | + callback(null); |
571 | + return; |
572 | + } |
573 | + |
574 | + if (! backendDelegate.isObjectProxyInfo(store)) { |
575 | + console.debug('requestForStore: invalid store object proxy') |
576 | + callback("Invalid store"); |
577 | + return; |
578 | + } |
579 | + |
580 | + var _store = backendDelegate.objectFromId(store.objectid); |
581 | + if ( ! _store) { |
582 | + callback("Invalid store object (NULL)"); |
583 | + return; |
584 | + } |
585 | + this._validate(); |
586 | + |
587 | + var transfer = new ContentTransfer(this._object.request(_store)); |
588 | + if (callback && typeof(callback) === 'function') |
589 | + callback(transfer.serialize()); |
590 | + }, |
591 | + |
592 | + // internal |
593 | + |
594 | + internal: { |
595 | + request: function(self) { |
596 | + return self._object.request(); |
597 | + } |
598 | + } |
599 | + }; |
600 | + |
601 | + function ContentPeerModel(filterParams) { |
602 | + var result = backendDelegate.createQmlObject( |
603 | + PLUGIN_URI, VERSION, 'ContentPeerModel', filterParams); |
604 | + this._id = result.id; |
605 | + this._object = result.object; |
606 | + |
607 | + this._modelAdaptor = backendDelegate.createModelAdaptorFor(this._object); |
608 | + this._roles = this._modelAdaptor.roles(); |
609 | + }; |
610 | + ContentPeerModel.prototype = { |
611 | + _validate: function() { |
612 | + if (! this._object) |
613 | + throw new TypeError("Invalid object null"); |
614 | + }, |
615 | + |
616 | + destroy: function() { |
617 | + if (! this._object) |
618 | + return; |
619 | + this._object.destroy(); |
620 | + this._modelAdaptor.destroy(); |
621 | + backendDelegate.deleteId(this._id); |
622 | + }, |
623 | + |
624 | + // properties |
625 | + setContentType: function(contentType, callback) { |
626 | + this._validate(); |
627 | + this._object.contentType = contentType; |
628 | + if (callback) |
629 | + callback(); |
630 | + }, |
631 | + |
632 | + setHandler: function(handler, callback) { |
633 | + this._validate(); |
634 | + this._object.handler = handler; |
635 | + if (callback) |
636 | + callback(); |
637 | + }, |
638 | + |
639 | + peers: function() { |
640 | + this._validate(); |
641 | + return this._object.peers; |
642 | + }, |
643 | + |
644 | + // QAbtractListModel prototype |
645 | + count: function(callback) { |
646 | + if (!this._modelAdaptor) { |
647 | + callback(-1); |
648 | + return; |
649 | + } |
650 | + callback(this._modelAdaptor.rowCount()); |
651 | + }, |
652 | }; |
653 | |
654 | function _constructorFromName(className) { |
655 | @@ -1679,33 +1908,95 @@ |
656 | } |
657 | |
658 | return { |
659 | - defaultSourceForType: function(type, callback) { |
660 | - var _type = _nameToContentType(type); |
661 | - var peer = _contenthub.defaultSourceForType(_type) |
662 | - var source = new ContentPeer(peer); |
663 | - callback(source.serialize()); |
664 | + getPeers: function(filters, callback) { |
665 | + if ( ! filters){ |
666 | + callback(null); |
667 | + return; |
668 | + } |
669 | + |
670 | + var statement = "import QtQuick 2.0; import Ubuntu.Content 0.1; ContentPeerModel {"; |
671 | + var filterParams = {}; |
672 | + if (filters.contentType) { |
673 | + statement += " contentType: ContentType." + filters.contentType + ";"; |
674 | + } |
675 | + if (filters.handler) { |
676 | + statement += " handler: ContentHandler." + filters.handler + ";"; |
677 | + } |
678 | + statement += " }"; |
679 | + |
680 | + var peerModel = Qt.createQmlObject(statement, backendDelegate.parent()); |
681 | + var onPeersFound = function() { |
682 | + var peers = peerModel.peers; |
683 | + |
684 | + var wrappedPeers = []; |
685 | + for (var i = 0; i < peers.length; ++i) { |
686 | + var wrappedPeer = new ContentPeer(peers[i]); |
687 | + wrappedPeers.push(wrappedPeer.serialize()); |
688 | + } |
689 | + peerModel.onFindPeersCompleted.disconnect(onPeersFound); |
690 | + callback(wrappedPeers); |
691 | + }; |
692 | + peerModel.onFindPeersCompleted.connect(onPeersFound); |
693 | }, |
694 | |
695 | - defaultStoreForType: function(type, callback) { |
696 | - var store = new ContentStore(_contenthub.defaultStoreForType(_nameToContentType(type))); |
697 | + getStore: function(scope, callback) { |
698 | + if ( ! scope){ |
699 | + callback(null); |
700 | + return; |
701 | + } |
702 | + var store = new ContentStore(); |
703 | + store.setScope(scope); |
704 | callback(store.serialize()); |
705 | }, |
706 | |
707 | - importContent: function(type, callback) { |
708 | - var transfer = new ContentTransfer(_contenthub.importContent(_nameToContentType(type))); |
709 | - callback(transfer.serialize()); |
710 | - }, |
711 | - |
712 | - knownSourcesForType: function(type, callback) { |
713 | - var peers = _contenthub.knownSourcesForType(_nameToContentType(type)); |
714 | - var wrappedPeers = []; |
715 | - |
716 | - for (var i = 0; i < peers.length; ++i) { |
717 | - var wrappedPeer = new ContentPeer(peers[i]); |
718 | - wrappedPeers.push(wrappedPeer.serialize()); |
719 | - } |
720 | - |
721 | - callback(wrappedPeers); |
722 | + launchContentPeerPicker: function(filters, onPeerSelected, onCancelPressed) { |
723 | + if ( ! filters){ |
724 | + callback(null); |
725 | + return; |
726 | + } |
727 | + |
728 | + var parentItem = backendDelegate.parentView(); |
729 | + if ( ! parentItem || ! parentItem.visible || ! parentItem.height || ! parentItem.width) { |
730 | + console.debug("Cannot launch the content peer picker UI, invalid parent item: " + parentItem); |
731 | + onCancelPressed(); |
732 | + return; |
733 | + } |
734 | + |
735 | + var statement = "import QtQuick 2.0; import Ubuntu.Content 0.1; ContentPeerPicker {"; |
736 | + var filterParams = {}; |
737 | + if (filters.contentType) { |
738 | + statement += " contentType: ContentType." + filters.contentType + ""; |
739 | + } |
740 | + if (filters.handler) { |
741 | + statement += "; handler: ContentHandler." + filters.handler + ""; |
742 | + } |
743 | + if (filters.showTitle) { |
744 | + statement += "; showTitle: " + filters.showTitle === false ? "false" : "true"; |
745 | + } |
746 | + statement += "; visible: true; }"; |
747 | + |
748 | + if (parentItem.parent) |
749 | + parentItem.visible = false; |
750 | + var contentPeerPicker = Qt.createQmlObject(statement, |
751 | + parentItem.parent ? parentItem.parent : parentItem); |
752 | + function _onPeerSelected() { |
753 | + var peer = new ContentPeer(contentPeerPicker.peer); |
754 | + contentPeerPicker.visible = false; |
755 | + parentItem.visible = true; |
756 | + onPeerSelected(peer.serialize()); |
757 | + contentPeerPicker.onPeerSelected.disconnect(_onPeerSelected); |
758 | + contentPeerPicker.destroy(); |
759 | + } |
760 | + function _onCancelPressed() { |
761 | + contentPeerPicker.visible = false; |
762 | + parentItem.visible = true; |
763 | + onCancelPressed(); |
764 | + contentPeerPicker.onPeerSelected.disconnect(_onCancelPressed); |
765 | + contentPeerPicker.destroy(); |
766 | + } |
767 | + |
768 | + contentPeerPicker.onPeerSelected.connect(_onPeerSelected); |
769 | + contentPeerPicker.onCancelPressed.connect(_onCancelPressed); |
770 | }, |
771 | |
772 | apiImportContent: function(type, peer, transferOptions, onSuccess, onFailure) { |
773 | @@ -1714,59 +2005,44 @@ |
774 | onError("Invalid peer"); |
775 | return; |
776 | } |
777 | + |
778 | var _type = _nameToContentType(type); |
779 | var _peer = backendDelegate.objectFromId(peer.objectid); |
780 | if ( ! _peer) { |
781 | onError("Invalid peer object (NULL)"); |
782 | return; |
783 | } |
784 | + var _transfer = null; |
785 | + if (transferOptions.scope) { |
786 | + var store = new ContentStore(); |
787 | + store.setScope(transferOptions.scope); |
788 | + _transfer = _peer.request(store._object); |
789 | + } |
790 | + else { |
791 | + _transfer = _peer.request(); |
792 | + } |
793 | |
794 | - var transfer = _contenthub.importContent(_type, _peer); |
795 | - console.log('*** Transfer object: ' + transfer + '') |
796 | if (transferOptions.multipleFiles) { |
797 | - transfer.selectionType = ContentHubBridge.ContentTransfer.Multiple; |
798 | + _transfer.selectionType = ContentHubBridge.ContentTransfer.Multiple; |
799 | } |
800 | else { |
801 | - transfer.selectionType = ContentHubBridge.ContentTransfer.Single; |
802 | - } |
803 | - |
804 | - if (transferOptions.importToLocalStore) { |
805 | - var store = _contenthub.defaultStoreForType(_type); |
806 | - transfer.setStore(store); |
807 | - } |
808 | - |
809 | - var _transfer = new ContentTransfer(transfer) |
810 | - transfer.stateChanged.connect(function() { |
811 | - console.log('** Transfer state change: ' + transfer + ', state: ' + _contentTransferStateToName(transfer.state)); |
812 | - if (transfer.state === ContentHubBridge.ContentTransfer.Aborted) { |
813 | + _transfer.selectionType = ContentHubBridge.ContentTransfer.Single; |
814 | + } |
815 | + |
816 | + var transfer = new ContentTransfer(_transfer) |
817 | + _transfer.stateChanged.connect(function() { |
818 | + if (_transfer.state === ContentHubBridge.ContentTransfer.Aborted) { |
819 | onFailure("Aborted"); |
820 | return; |
821 | } |
822 | - else if (transfer.state === ContentHubBridge.ContentTransfer.Charged) { |
823 | - console.log('*** Transfer complete: got: ' + transfer.items.length + ' items (' + transfer + ')') |
824 | - for (var i = 0; i < transfer.items.length; ++i) { |
825 | - console.log('** item ' + i + ' : ' + transfer.items[i].url); |
826 | - } |
827 | - |
828 | - var d = _transfer.internal.serializeItems(transfer); |
829 | + else if (_transfer.state === ContentHubBridge.ContentTransfer.Charged) { |
830 | + var d = transfer.internal.serializeItems(_transfer); |
831 | onSuccess(d); |
832 | - transfer.finalize(); |
833 | + _transfer.finalize(); |
834 | return; |
835 | } |
836 | }); |
837 | - transfer.start(); |
838 | - }, |
839 | - |
840 | - importContentForPeer: function(type, peerProxy, callback) { |
841 | - if (! backendDelegate.isObjectProxyInfo(peerProxy)) { |
842 | - console.debug('importContentForPeer: invalid peer object proxy') |
843 | - callback(); |
844 | - return; |
845 | - } |
846 | - var peer = backendDelegate.objectFromId(peerProxy.objectid); |
847 | - var transfer = new ContentTransfer(_contenthub.importContent(_nameToContentType(type), peer)); |
848 | - |
849 | - callback(transfer.serialize()); |
850 | + _transfer.start(); |
851 | }, |
852 | |
853 | onExportRequested: function(callback) { |
854 | |
855 | === modified file 'src/Ubuntu/UnityWebApps/bindings/content-hub/client/content-hub.js' |
856 | --- src/Ubuntu/UnityWebApps/bindings/content-hub/client/content-hub.js 2014-03-04 20:40:16 +0000 |
857 | +++ src/Ubuntu/UnityWebApps/bindings/content-hub/client/content-hub.js 2014-03-18 13:59:59 +0000 |
858 | @@ -42,6 +42,10 @@ |
859 | ? content.store : null; |
860 | this._state = content && content.state |
861 | ? content.state : null; |
862 | + this._selectionType = content && content.selectionType |
863 | + ? content.selectionType : null; |
864 | + this._direction = content && content.direction |
865 | + ? content.direction : null; |
866 | }; |
867 | ContentTransfer.prototype = { |
868 | // object methods |
869 | @@ -77,7 +81,7 @@ |
870 | * |
871 | * @method setStore |
872 | * @param store {ContentStore} |
873 | - * @param callback (optional) {Function()} |
874 | + * @param callback (optional) {Function()} called when the store has been updated |
875 | */ |
876 | setStore: function(store, callback) { |
877 | this._proxy.call('setStore', [store.serialize(), callback]); |
878 | @@ -108,6 +112,15 @@ |
879 | setState: function(state, callback) { |
880 | this._proxy.call('setState', [state, callback]); |
881 | }, |
882 | + /** |
883 | + * Notifies the listener when the state of the transfer changes. |
884 | + * |
885 | + * @method onStateChanged |
886 | + * @param callback {Function(ContentTransfer.State)} |
887 | + */ |
888 | + onStateChanged: function(callback) { |
889 | + this._proxy.call('onStateChanged', [callback]); |
890 | + }, |
891 | |
892 | /** |
893 | * Retrieves the current selection type. |
894 | @@ -116,7 +129,11 @@ |
895 | * @param callback {Function(ContentTransfer.SelectionType)} |
896 | */ |
897 | selectionType: function(callback) { |
898 | - this._proxy.call('selectionType', [], callback); |
899 | + if (callback && typeof(callback) === 'function') { |
900 | + this._proxy.call('selectionType', [], callback); |
901 | + return; |
902 | + } |
903 | + return this._selectionType; |
904 | }, |
905 | /** |
906 | * Sets the selection type (single or multiple). |
907 | @@ -126,17 +143,24 @@ |
908 | * @param callback {Function()} called when the state has been updated |
909 | */ |
910 | setSelectionType: function(selectionType, callback) { |
911 | + this._selectionType = selectionType; |
912 | this._proxy.call('setSelectionType', [selectionType, callback]); |
913 | }, |
914 | |
915 | /** |
916 | * Retrieves the current transfer direction. |
917 | * |
918 | + * If the callback parameter is not set, the current "local" value is retrieved. |
919 | + * |
920 | * @method direction |
921 | - * @param callback {Function(ContentTransfer.Direction)} |
922 | + * @param callback (optional) {Function(ContentTransfer.Direction)} |
923 | */ |
924 | direction: function(callback) { |
925 | - this._proxy.call('direction', [], callback); |
926 | + if (callback && typeof(callback) === 'function') { |
927 | + this._proxy.call('direction', [], callback); |
928 | + return; |
929 | + } |
930 | + return this._direction; |
931 | }, |
932 | /** |
933 | * Sets the transfer direction (import or export). |
934 | @@ -146,6 +170,7 @@ |
935 | * @param callback {Function()} called when the state has been updated |
936 | */ |
937 | setDirection: function(direction, callback) { |
938 | + this._direction = direction; |
939 | this._proxy.call('setDirection', [direction, callback]); |
940 | }, |
941 | |
942 | @@ -231,6 +256,13 @@ |
943 | ? content.appId : null; |
944 | this._name = content && content.name |
945 | ? content.name : null; |
946 | + this._handler = content && content.handler |
947 | + ? content.handler : null; |
948 | + this._contentType = content && content.contentType |
949 | + ? content.contentType : null; |
950 | + this._selectionType = content && content.selectionType |
951 | + ? content.selectionType : null; |
952 | + this._isDefaultPeer = content && content.isDefaultPeer; |
953 | }; |
954 | ContentPeer.prototype = { |
955 | // object methods |
956 | @@ -246,14 +278,13 @@ |
957 | |
958 | // properties |
959 | |
960 | - // immutable |
961 | - |
962 | /** |
963 | * Retrieves the app Id of the associated peer. |
964 | * |
965 | * If the callback parameter is not set, the current "local" value is retrieved. |
966 | * |
967 | * @method appId |
968 | + * @return {String} Application Id for this peer |
969 | * @param callback (optional) {Function(String)} |
970 | */ |
971 | appId: function(callback) { |
972 | @@ -263,8 +294,97 @@ |
973 | } |
974 | return this._appId; |
975 | }, |
976 | - |
977 | - // immutable |
978 | + /** |
979 | + * Sets the app Id of the associated peer. |
980 | + * |
981 | + * @method setAppId |
982 | + * @param appId {String} |
983 | + * @param callback {Function()} called when the appId has been updated |
984 | + */ |
985 | + setAppId: function(appId, callback) { |
986 | + this._proxy.call('setAppId', [appId, callback]); |
987 | + }, |
988 | + |
989 | + /** |
990 | + * Retrieves the specific ContentHandler for this peer. |
991 | + * |
992 | + * If the callback parameter is not set, the current "local" value is retrieved. |
993 | + * |
994 | + * @method handler |
995 | + * @return {String} ContentHandler for this peer |
996 | + * @param callback (optional) {Function(String)} |
997 | + */ |
998 | + handler: function(callback) { |
999 | + if (callback && typeof(callback) === 'function') { |
1000 | + this._proxy.call('handler', [], callback); |
1001 | + return; |
1002 | + } |
1003 | + return this._handler; |
1004 | + }, |
1005 | + /** |
1006 | + * Sets specific ContentHandler for this peer. |
1007 | + * |
1008 | + * @method setHandler |
1009 | + * @param handler {ContentHandler} |
1010 | + * @param callback {Function()} called when the appId has been updated |
1011 | + */ |
1012 | + setHandler: function(handler, callback) { |
1013 | + this._proxy.call('setHandler', [handler, callback]); |
1014 | + }, |
1015 | + |
1016 | + /** |
1017 | + * Retrieves the specific ContentType for this peer. |
1018 | + * |
1019 | + * If the callback parameter is not set, the current "local" value is retrieved. |
1020 | + * |
1021 | + * @method contentType |
1022 | + * @return {String} ContentType for this peer |
1023 | + * @param callback (optional) {Function(String)} |
1024 | + */ |
1025 | + contentType: function(callback) { |
1026 | + if (callback && typeof(callback) === 'function') { |
1027 | + this._proxy.call('contentType', [], callback); |
1028 | + return; |
1029 | + } |
1030 | + return this._contentType; |
1031 | + }, |
1032 | + /** |
1033 | + * Sets specific ContentType for this peer. |
1034 | + * |
1035 | + * @method setContentType |
1036 | + * @param contentType {ContentType} |
1037 | + * @param callback {Function()} called when the content type has been updated |
1038 | + */ |
1039 | + setContentType: function(contentType, callback) { |
1040 | + this._proxy.call('setContentType', [contentType, callback]); |
1041 | + }, |
1042 | + |
1043 | + /** |
1044 | + * Retrieves the specific SelectionType for this peer. |
1045 | + * |
1046 | + * If the callback parameter is not set, the current "local" value is retrieved. |
1047 | + * |
1048 | + * @method selectionType |
1049 | + * @return {String} ContentTransfer.SelectionType for this peer |
1050 | + * @param callback (optional) {Function(String)} |
1051 | + */ |
1052 | + selectionType: function(callback) { |
1053 | + if (callback && typeof(callback) === 'function') { |
1054 | + this._proxy.call('selectionType', [], callback); |
1055 | + return; |
1056 | + } |
1057 | + return this._selectionType; |
1058 | + }, |
1059 | + /** |
1060 | + * Sets specific SelectionType for this peer. |
1061 | + * |
1062 | + * @method setSelectionType |
1063 | + * @param selectionType {ContentTransfer.SelectionType} |
1064 | + * @param callback {Function()} called when the content type has been updated |
1065 | + */ |
1066 | + setSelectionType: function(selectionType, callback) { |
1067 | + this._proxy.call('setSelectionType', [selectionType, callback]); |
1068 | + }, |
1069 | |
1070 | /** |
1071 | * Retrieves the name of the associated peer. |
1072 | @@ -282,6 +402,45 @@ |
1073 | return this._name; |
1074 | }, |
1075 | |
1076 | + /** |
1077 | + * Returns true if the peer is a default one, false otherwise. |
1078 | + * |
1079 | + * If the callback parameter is not set, the current "local" value is retrieved. |
1080 | + * |
1081 | + * @method isDefaultPeer |
1082 | + * @param callback (optional) {Function(Bool)} |
1083 | + */ |
1084 | + isDefaultPeer: function(callback) { |
1085 | + if (callback && typeof(callback) === 'function') { |
1086 | + this._proxy.call('isDefaultPeer', [], callback); |
1087 | + return; |
1088 | + } |
1089 | + return this._isDefaultPeer; |
1090 | + }, |
1091 | + |
1092 | + // methods |
1093 | + |
1094 | + /** |
1095 | + * Request to import data from this ContentPeer. |
1096 | + * |
1097 | + * @method request |
1098 | + * @param callback {Function(ContentTransfer)} Called with the resulting content transfer |
1099 | + */ |
1100 | + request: function(callback) { |
1101 | + this._proxy.call('request', [], callback); |
1102 | + }, |
1103 | + |
1104 | + /** |
1105 | + * Request to import data from this ContentPeer and use a ContentStore for permanent storage. |
1106 | + * |
1107 | + * @method requestForStore |
1108 | + * @param store {ContentStore} Store used as a permanent storage |
1109 | + * @param callback {Function(ContentTransfer)} Called with the resulting content transfer |
1110 | + */ |
1111 | + requestForStore: function(store, callback) { |
1112 | + this._proxy.call('requestForStore', [store.serialize()], callback); |
1113 | + }, |
1114 | + |
1115 | // extras |
1116 | |
1117 | /** |
1118 | @@ -321,6 +480,8 @@ |
1119 | |
1120 | this._uri = content && content.uri |
1121 | ? content.uri : null; |
1122 | + this._scope = content && content.scope |
1123 | + ? content.scope : null; |
1124 | }; |
1125 | ContentStore.prototype = { |
1126 | // object methods |
1127 | @@ -343,6 +504,7 @@ |
1128 | * If the callback parameter is not set, the current "local" value is retrieved. |
1129 | * |
1130 | * @method uri |
1131 | + * @return {String} current uri |
1132 | * @param callback (optional) {Function(String)} |
1133 | */ |
1134 | uri: function(callback) { |
1135 | @@ -353,6 +515,33 @@ |
1136 | return this._uri; |
1137 | }, |
1138 | |
1139 | + /** |
1140 | + * Retrieves the current scope. |
1141 | + * |
1142 | + * If the callback parameter is not set, the current "local" value is retrieved. |
1143 | + * |
1144 | + * @method scope |
1145 | + * @return {ContentScope} current scope |
1146 | + * @param callback (optional) {Function(ContentScope)} |
1147 | + */ |
1148 | + scope: function(callback) { |
1149 | + if (callback && typeof(callback) === 'function') { |
1150 | + this._proxy.call('scope', [], callback); |
1151 | + return; |
1152 | + } |
1153 | + return this._scope; |
1154 | + }, |
1155 | + /** |
1156 | + * Sets the current scope. |
1157 | + * |
1158 | + * @method setScope |
1159 | + * @param scope {ContentScope} |
1160 | + * @param callback {Function()} called when the scope has been updated |
1161 | + */ |
1162 | + setScope: function(scope, callback) { |
1163 | + this._proxy.call('setScope', [scope, callback]); |
1164 | + }, |
1165 | + |
1166 | // extras |
1167 | |
1168 | /** |
1169 | @@ -394,7 +583,9 @@ |
1170 | Documents |
1171 | |
1172 | Music |
1173 | - |
1174 | + |
1175 | + Contacts |
1176 | + |
1177 | @static |
1178 | @property ContentType {String} |
1179 | |
1180 | @@ -406,9 +597,52 @@ |
1181 | var pictureContentType = hub.ContentType.Pictures; |
1182 | */ |
1183 | ContentType: { |
1184 | + All: "All", |
1185 | + Unknown: "Unknown", |
1186 | Pictures: "Pictures", |
1187 | Documents: "Documents", |
1188 | - Music: "Music" |
1189 | + Music: "Music", |
1190 | + Contacts: "Contacts", |
1191 | + }, |
1192 | + |
1193 | + /** |
1194 | + ContentHandler is an enumeration of well known content handlers. |
1195 | + |
1196 | + Values: |
1197 | + |
1198 | + Source |
1199 | + |
1200 | + Destination |
1201 | + |
1202 | + Share |
1203 | + |
1204 | + @static |
1205 | + @property ContentHandler {String} |
1206 | + */ |
1207 | + ContentHandler: { |
1208 | + Source: "Source", |
1209 | + Destination: "Destination", |
1210 | + Share: "Share", |
1211 | + }, |
1212 | + |
1213 | + /** |
1214 | + ContentScope is an enumeration of well known scope types. |
1215 | + |
1216 | + Values: |
1217 | + |
1218 | + System |
1219 | + |
1220 | + User |
1221 | + |
1222 | + App |
1223 | + |
1224 | + @static |
1225 | + @property ContentScope {String} |
1226 | + */ |
1227 | + ContentScope: { |
1228 | + System: "System", |
1229 | + User: "User", |
1230 | + App: "App", |
1231 | }, |
1232 | |
1233 | ContentTransfer: { |
1234 | @@ -527,67 +761,46 @@ |
1235 | /** |
1236 | * Creates a ContentPeer object for the given source type. |
1237 | * |
1238 | - * @method defaultSourceForType |
1239 | - * @param type {ContentType} Content type. |
1240 | - * @param callback {Function (ContentPeer)} Function called with the created ContentPeer. |
1241 | - */ |
1242 | - defaultSourceForType: function(type, callback) { |
1243 | - backendBridge.call('ContentHub.defaultSourceForType', |
1244 | - [type], |
1245 | - callback); |
1246 | - }, |
1247 | - |
1248 | - /** |
1249 | - * Creates a ContentStore object for the given content type. |
1250 | - * |
1251 | - * @method defaultStoreForType |
1252 | - * @param type {ContentType} Content type. |
1253 | - * @param callback {Function (ContentStore)} Function called with the created ContentStore. |
1254 | - */ |
1255 | - defaultStoreForType: function(type, callback) { |
1256 | - backendBridge.call('ContentHub.defaultStoreForType', |
1257 | - [type], |
1258 | - callback); |
1259 | - }, |
1260 | - |
1261 | - /** |
1262 | - * Returns all possible peers for the given ContentType. |
1263 | - * |
1264 | - * @method knownSourcesForType |
1265 | - * @param type {ContentType} Content type. |
1266 | - * @param callback {Function (Array of ContentPeer)} Function called with the possible ContentPeers. |
1267 | - */ |
1268 | - knownSourcesForType: function(type, callback) { |
1269 | - backendBridge.call('ContentHub.knownSourcesForType', |
1270 | - [type], |
1271 | - callback); |
1272 | - }, |
1273 | - |
1274 | - /** |
1275 | - * Creates a ContentTransfer object for the given content type. |
1276 | - * |
1277 | - * @method importContent |
1278 | - * @param type {ContentType} Content type. |
1279 | - * @param callback {Function(ContentTransfer)} Function called with the created ContentTransfer. |
1280 | - */ |
1281 | - importContent: function(type, callback) { |
1282 | - backendBridge.call('ContentHub.importContent', |
1283 | - [type], |
1284 | - callback); |
1285 | - }, |
1286 | - |
1287 | - /** |
1288 | - * Creates a ContentTransfer object for the given ContentPeer. |
1289 | - * |
1290 | - * @method importContentForPeer |
1291 | - * @param type {ContentType} Content type. |
1292 | - * @param peer {ContentPeer} Content peer. |
1293 | - * @param callback {Function(ContentTransfer)} Function called with the created ContentTransfer. |
1294 | - */ |
1295 | - importContentForPeer: function(type, peer, callback) { |
1296 | - backendBridge.call('ContentHub.importContentForPeer', |
1297 | - [type, peer.serialize()], |
1298 | - callback); |
1299 | + * @method getPeers |
1300 | + * @param filters {Object} A dictionary of parameters to filter the result. The filtering keys are: |
1301 | + * - contentType: desired ContentType |
1302 | + * - handler: desired ContentHandler |
1303 | + * |
1304 | + * @param callback {Function(List of ContentPeer objects)} Callback that receives the result or null |
1305 | + */ |
1306 | + getPeers: function(filter, callback) { |
1307 | + backendBridge.call('ContentHub.getPeers', |
1308 | + [filter], |
1309 | + callback); |
1310 | + }, |
1311 | + |
1312 | + /** |
1313 | + * Creates a ContentStore object for the given scope type. |
1314 | + * |
1315 | + * @method getStore |
1316 | + * @param scope {ContentScope} The content scope for the store |
1317 | + * @param callback {Function(ContentStore)} Callback that receives the result or null |
1318 | + */ |
1319 | + getStore: function(scope, callback) { |
1320 | + backendBridge.call('ContentHub.getStore', |
1321 | + [scope], |
1322 | + callback); |
1323 | + }, |
1324 | + |
1325 | + /** |
1326 | + * Launches the content peer picker ui that allows the user to select a peer. |
1327 | + * |
1328 | + * @method launchContentPeerPicker |
1329 | + * @param filters {Object} A dictionary of parameters to filter the result. The filtering keys are: |
1330 | + * - contentType: desired ContentType |
1331 | + * - handler: desired ContentHandler |
1332 | + * - showTitle: boolean value indicating if the title should be visible |
1333 | + * @param onPeerSelected {Function(ContentPeer)} Called when the user has selected a peer |
1334 | + * @param onCancelPressed {Function()} Called when the user has pressed cancel |
1335 | + */ |
1336 | + launchContentPeerPicker: function(filters, onPeerSelected, onCancelPressed) { |
1337 | + backendBridge.call('ContentHub.launchContentPeerPicker', |
1338 | + [filters, onPeerSelected, onCancelPressed]); |
1339 | }, |
1340 | |
1341 | /** |
1342 | @@ -631,7 +844,9 @@ |
1343 | * @method api.importContent |
1344 | * @param type {ContentType} type of the content to import |
1345 | * @param peer {ContentPeer} peer whos content should be imported |
1346 | - * @param transferOptions {Object {multipleFiles: {Bool}, importToLocalStore: {Bool}} } the set of options for the transfer |
1347 | + * @param transferOptions {Object} a dictionary of transfer options. The options are the following: |
1348 | + * - multipleFiles {Bool}: specified if a transfer should involve multiple files or not |
1349 | + * - scope {ContentScope}: specifies the location where the transferred files should be copied to |
1350 | * @param onError {Function(reason:)} called when the transfer has failed |
1351 | * @param onSuccess {Function(Array of {ContentItem})} called when the transfer has been a success and items are available |
1352 | */ |
PASSED: Continuous integration, rev:100 jenkins. qa.ubuntu. com/job/ unity-webapps- qml-ci/ 90/ jenkins. qa.ubuntu. com/job/ unity-webapps- qml-trusty- amd64-ci/ 38 jenkins. qa.ubuntu. com/job/ unity-webapps- qml-trusty- armhf-ci/ 38
http://
Executed test runs:
SUCCESS: http://
SUCCESS: http://
Click here to trigger a rebuild: s-jenkins. ubuntu- ci:8080/ job/unity- webapps- qml-ci/ 90/rebuild
http://