Skip to content

Commit d7ae264

Browse files
committed
Merge pull request #292 from dpalou/MOBILE-1297
Mobile 1297
2 parents 4509d35 + 5174deb commit d7ae264

File tree

32 files changed

+2211
-997
lines changed

32 files changed

+2211
-997
lines changed

www/addons/mod_book/main.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ angular.module('mm.addons.mod_book', ['mm.core'])
3636

3737
})
3838

39-
.config(function($mmCourseDelegateProvider) {
39+
.config(function($mmCourseDelegateProvider, $mmCoursePrefetchDelegateProvider) {
4040
$mmCourseDelegateProvider.registerContentHandler('mmaModBook', 'book', '$mmaModBookCourseContentHandler');
41+
$mmCoursePrefetchDelegateProvider.registerPrefetchHandler('mmaModBook', 'book', '$mmaModBookPrefetchHandler');
4142
});

www/addons/mod_book/services/book.js

Lines changed: 55 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -36,19 +36,8 @@ angular.module('mm.addons.mod_book')
3636
* @return {Promise} Promise resolved when all content is downloaded. Data returned is not reliable.
3737
*/
3838
self.downloadAllContent = function(module) {
39-
var promises = [],
40-
siteid = $mmSite.getId();
41-
42-
angular.forEach(module.contents, function(content) {
43-
var url = content.fileurl,
44-
timemodified = content.timemodified;
45-
if (content.type !== 'file') {
46-
return;
47-
}
48-
promises.push($mmFilepool.downloadUrl(siteid, url, false, mmaModBookComponent, module.id, timemodified));
49-
});
50-
51-
return $q.all(promises);
39+
var files = self.getDownloadableFiles(module);
40+
return $mmFilepool.downloadPackage($mmSite.getId(), files, mmaModBookComponent, module.id);
5241
};
5342

5443
/**
@@ -67,7 +56,7 @@ angular.module('mm.addons.mod_book')
6756

6857
angular.forEach(module.contents, function(content) {
6958
var url = content.fileurl;
70-
if (content.type !== 'file') {
59+
if (!self.isFileDownloadable(content)) {
7160
return;
7261
}
7362
promises.push($mmFilepool.isFileDownloadingByUrl(siteid, url).then(function() {
@@ -97,7 +86,7 @@ angular.module('mm.addons.mod_book')
9786
var promises = [];
9887
angular.forEach(module.contents, function(content) {
9988
var url = content.fileurl;
100-
if (content.type !== 'file') {
89+
if (!self.isFileDownloadable(content)) {
10190
return;
10291
}
10392
promises.push($mmFilepool.getFileEventNameByUrl($mmSite.getId(), url));
@@ -107,6 +96,26 @@ angular.module('mm.addons.mod_book')
10796
});
10897
};
10998

99+
/**
100+
* Returns a list of files that can be downloaded.
101+
*
102+
* @module mm.addons.mod_book
103+
* @ngdoc method
104+
* @name $mmaModBook#getDownloadableFiles
105+
* @param {Object} module The module object returned by WS.
106+
* @return {Object[]} List of files.
107+
*/
108+
self.getDownloadableFiles = function(module) {
109+
var files = [];
110+
111+
angular.forEach(module.contents, function(content) {
112+
if (self.isFileDownloadable(content)) {
113+
files.push(content);
114+
}
115+
});
116+
117+
return files;
118+
};
110119

111120
/**
112121
* Get the book toc as an array.
@@ -228,7 +237,7 @@ angular.module('mm.addons.mod_book')
228237

229238
// Extract the information about paths from the module contents.
230239
angular.forEach(contents, function(content) {
231-
if (content.type == 'file') {
240+
if (self.isFileDownloadable(content)) {
232241
var key,
233242
url = content.fileurl;
234243

@@ -304,6 +313,33 @@ angular.module('mm.addons.mod_book')
304313
return $mmFilepool.invalidateFilesByComponent($mmSite.getId(), mmaModBookComponent, moduleId);
305314
};
306315

316+
/**
317+
* Check if a file is downloadable. The file param must have a 'type' attribute like in core_course_get_contents response.
318+
*
319+
* @module mm.addons.mod_book
320+
* @ngdoc method
321+
* @name $mmaModBook#isFileDownloadable
322+
* @param {Object} file File to check.
323+
* @return {Boolean} True if downloadable, false otherwise.
324+
*/
325+
self.isFileDownloadable = function(file) {
326+
return file.type === 'file';
327+
};
328+
329+
/**
330+
* Return whether or not the plugin is enabled.
331+
*
332+
* @module mm.addons.mod_book
333+
* @ngdoc method
334+
* @name $mmaModBook#isPluginEnabled
335+
* @return {Boolean} True if plugin is enabled, false otherwise.
336+
*/
337+
self.isPluginEnabled = function() {
338+
var version = $mmSite.getInfo().version;
339+
// Require Moodle 2.9.
340+
return version && (parseInt(version) >= 2015051100) && $mmSite.canDownloadFiles();
341+
};
342+
307343
/**
308344
* Report a book as being viewed.
309345
*
@@ -330,17 +366,11 @@ angular.module('mm.addons.mod_book')
330366
* @ngdoc method
331367
* @name $mmaModBook#prefetchContent
332368
* @param {Object} module The module object returned by WS.
333-
* @return {Void}
369+
* @return {Promise} Promise resolved when all content is downloaded. Data returned is not reliable.
334370
*/
335371
self.prefetchContent = function(module) {
336-
angular.forEach(module.contents, function(content) {
337-
var url;
338-
if (content.type !== 'file') {
339-
return;
340-
}
341-
url = content.fileurl;
342-
$mmFilepool.addToQueueByUrl($mmSite.getId(), url, mmaModBookComponent, module.id);
343-
});
372+
var files = self.getDownloadableFiles(module);
373+
return $mmFilepool.prefetchPackage($mmSite.getId(), files, mmaModBookComponent, module.id);
344374
};
345375

346376
return self;

www/addons/mod_book/services/course_content_handler.js

Lines changed: 35 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,10 @@ angular.module('mm.addons.mod_book')
2121
* @ngdoc service
2222
* @name $mmaModBookCourseContentHandler
2323
*/
24-
.factory('$mmaModBookCourseContentHandler', function($mmCourse, $mmaModBook, $mmFilepool, $mmEvents, $state, $mmSite, $mmUtil,
25-
mmCoreEventQueueEmpty) {
24+
.factory('$mmaModBookCourseContentHandler', function($mmCourse, $mmaModBook, $mmEvents, $state, $mmSite, $mmUtil, $mmFilepool,
25+
$mmCoursePrefetchDelegate, mmCoreDownloading, mmCoreNotDownloaded, mmCoreOutdated, mmCoreDownloaded,
26+
mmCoreEventPackageStatusChanged, mmaModBookComponent) {
27+
2628
var self = {};
2729

2830
/**
@@ -34,9 +36,7 @@ angular.module('mm.addons.mod_book')
3436
* @return {Boolean}
3537
*/
3638
self.isEnabled = function() {
37-
var version = $mmSite.getInfo().version;
38-
// Require Moodle 2.9.
39-
return version && (parseInt(version) >= 2015051100) && $mmSite.canDownloadFiles();
39+
return $mmaModBook.isPluginEnabled();
4040
};
4141

4242
/**
@@ -53,107 +53,18 @@ angular.module('mm.addons.mod_book')
5353
return function($scope) {
5454
var downloadBtn,
5555
refreshBtn,
56-
observers = {},
57-
queueObserver,
58-
previousState,
59-
siteid = $mmSite.getId(),
60-
revision = $mmCourse.getRevisionFromContents(module.contents),
61-
timemodified = $mmCourse.getTimemodifiedFromContents(module.contents);
62-
63-
// Add queue observer to clear observers when filepool queue is empty. Needed because sometimes when "restoring"
64-
// downloading the spinner was shown forever, probably because a file download finished before observer was set.
65-
function addQueueObserver() {
66-
queueObserver = $mmEvents.on(mmCoreEventQueueEmpty, function() {
67-
// Queue is empty. Clear observers.
68-
if (queueObserver) {
69-
queueObserver.off();
70-
}
71-
if (Object.keys(observers).length) {
72-
clearObservers();
73-
setDownloaded();
74-
}
75-
delete queueObserver;
76-
});
77-
}
78-
79-
// Add observers to monitor file downloads.
80-
function addObservers(eventNames, isOpeningModule) {
81-
angular.forEach(eventNames, function(e) {
82-
if (typeof observers[e] == 'undefined') {
83-
observers[e] = $mmEvents.on(e, function(data) {
84-
if (data.success) {
85-
// Download success. Disable this observer and check if all files have been downloaded.
86-
if (typeof observers[e] !== 'undefined') {
87-
observers[e].off();
88-
delete observers[e];
89-
}
90-
if (Object.keys(observers).length < 1) {
91-
setDownloaded();
92-
}
93-
} else if (data.success === false) {
94-
// A download failed. Clear observers, show error message and set previous state.
95-
clearObservers();
96-
$scope.spinner = false;
97-
$mmCourse.storeModuleStatus(siteid, module.id, previousState, revision, timemodified);
98-
if (previousState === $mmFilepool.FILENOTDOWNLOADED) {
99-
downloadBtn.hidden = false;
100-
} else {
101-
refreshBtn.hidden = false;
102-
}
103-
// Don't show error message if state left or the module is being opened.
104-
if (!$scope.$$destroyed && !isOpeningModule) {
105-
$mmUtil.showErrorModal('mm.core.errordownloading', true);
106-
}
107-
}
108-
109-
});
110-
}
111-
});
112-
}
113-
114-
// Disable file download observers.
115-
function clearObservers() {
116-
angular.forEach(observers, function(observer) {
117-
observer.off();
118-
});
119-
observers = {};
120-
}
121-
122-
// Set module as 'downloaded', hiding icons and storing its state.
123-
function setDownloaded() {
124-
$scope.spinner = false;
125-
downloadBtn.hidden = true;
126-
refreshBtn.hidden = false; // Always show refresh button because revision and timemodified are not reliable.
127-
// Store module as downloaded.
128-
$mmCourse.storeModuleStatus(siteid, module.id, $mmFilepool.FILEDOWNLOADED, revision, timemodified);
129-
}
130-
131-
// Show downloading spinner and hide other icons.
132-
function showDownloading() {
133-
downloadBtn.hidden = true;
134-
refreshBtn.hidden = true;
135-
$scope.spinner = true;
136-
}
56+
revision = $mmFilepool.getRevisionFromFileList(module.contents),
57+
timemodified = $mmFilepool.getTimemodifiedFromFileList(module.contents);
13758

13859
downloadBtn = {
13960
hidden: true,
14061
icon: 'ion-ios-cloud-download',
14162
label: 'mm.core.download',
14263
action: function(e) {
143-
var eventNames;
144-
14564
e.preventDefault();
14665
e.stopPropagation();
147-
148-
showDownloading();
149-
150-
$mmaModBook.getFileEventNames(module).then(function(eventNames) {
151-
previousState = $mmFilepool.FILENOTDOWNLOADED;
152-
addObservers(eventNames, false);
153-
$mmaModBook.prefetchContent(module);
154-
// Store module as dowloading.
155-
$mmCourse.storeModuleStatus(siteid, module.id, $mmFilepool.FILEDOWNLOADING, revision, timemodified);
156-
addQueueObserver();
66+
$mmaModBook.prefetchContent(module).catch(function() {
67+
$mmUtil.showErrorModal('mm.core.errordownloading', true);
15768
});
15869
}
15970
};
@@ -166,16 +77,9 @@ angular.module('mm.addons.mod_book')
16677
e.preventDefault();
16778
e.stopPropagation();
16879

169-
showDownloading();
170-
171-
$mmaModBook.invalidateContent(module.id).then(function() {
172-
$mmaModBook.getFileEventNames(module).then(function(eventNames) {
173-
previousState = $mmFilepool.FILEOUTDATED;
174-
addObservers(eventNames, false);
175-
$mmaModBook.prefetchContent(module);
176-
// Store module as dowloading.
177-
$mmCourse.storeModuleStatus(siteid, module.id, $mmFilepool.FILEDOWNLOADING, revision, timemodified);
178-
addQueueObserver();
80+
$mmaModBook.invalidateContent(module.id).finally(function() {
81+
$mmaModBook.prefetchContent(module).catch(function() {
82+
$mmUtil.showErrorModal('mm.core.errordownloading', true);
17983
});
18084
});
18185
}
@@ -187,46 +91,33 @@ angular.module('mm.addons.mod_book')
18791
$scope.spinner = false;
18892

18993
$scope.action = function(e) {
190-
// Refresh or download icon shown. Let's add observers to monitor download.
191-
previousState = downloadBtn.hidden ? $mmFilepool.FILEOUTDATED : $mmFilepool.FILENOTDOWNLOADED;
192-
$mmaModBook.getFileEventNames(module).then(function(eventNames) {
193-
addObservers(eventNames, true);
194-
});
195-
$mmCourse.storeModuleStatus(siteid, module.id, $mmFilepool.FILEDOWNLOADING, revision, timemodified);
196-
showDownloading();
94+
e.preventDefault();
95+
e.stopPropagation();
19796
$state.go('site.mod_book', {module: module, courseid: courseid});
19897
};
19998

200-
// Check current status to decide which icon should be shown.
201-
$mmCourse.getModuleStatus(siteid, module.id, revision, timemodified).then(function(status) {
202-
if (status == $mmFilepool.FILENOTDOWNLOADED) {
203-
downloadBtn.hidden = false;
204-
} else if (status == $mmFilepool.FILEDOWNLOADING) {
205-
$scope.spinner = true;
206-
$mmaModBook.getDownloadingFilesEventNames(module).then(function(eventNames) {
207-
if (eventNames.length) {
208-
$mmCourse.getModulePreviousStatus(siteid, module.id).then(function(previous) {
209-
previousState = previous;
210-
});
211-
addObservers(eventNames, false);
212-
addQueueObserver();
213-
} else {
214-
// Weird case, state downloading but no files being downloaded. Set state to previousState.
215-
$mmCourse.getModulePreviousStatus(siteid, module.id).then(function(previous) {
216-
$scope.spinner = false;
217-
if (previous === $mmFilepool.FILENOTDOWNLOADED) {
218-
downloadBtn.hidden = false;
219-
} else {
220-
refreshBtn.hidden = false;
221-
}
222-
$mmCourse.storeModuleStatus(siteid, module.id, previous, revision, timemodified);
223-
});
224-
}
225-
});
226-
} else {
227-
// Show refresh button also if FILEDOWNLOADED because revision and timemodified are not reliable.
228-
refreshBtn.hidden = false;
99+
// Show buttons according to module status.
100+
function showStatus(status) {
101+
if (status) {
102+
$scope.spinner = status === mmCoreDownloading;
103+
downloadBtn.hidden = status !== mmCoreNotDownloaded;
104+
// Always show refresh button if a book is downloaded because revision and timemodified aren't reliable.
105+
refreshBtn.hidden = status !== mmCoreOutdated && status !== mmCoreDownloaded;
229106
}
107+
}
108+
109+
// Listen for changes on this module status.
110+
var statusObserver = $mmEvents.on(mmCoreEventPackageStatusChanged, function(data) {
111+
if (data.siteid === $mmSite.getId() && data.componentId === module.id && data.component === mmaModBookComponent) {
112+
showStatus(data.status);
113+
}
114+
});
115+
116+
// Get current status to decide which icon should be shown.
117+
$mmCoursePrefetchDelegate.getModuleStatus(module, revision, timemodified).then(showStatus);
118+
119+
$scope.$on('$destroy', function() {
120+
statusObserver && statusObserver.off && statusObserver.off();
230121
});
231122
};
232123
};

0 commit comments

Comments
 (0)