Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions upgrade.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ information provided here is intended especially for developers.
* Now mmUser#formatRoleList is returning a String instead of a Promise.
* The event mmCoreEventSessionExpired now receives an object instead of a string. Also, mmLoginLaunchSiteURL and mmLoginLaunchPassport have been deprecated, please use mmLoginLaunchData instead.
* Handlers registered in $mmFileUploaderDelegate now must implement a getData function instead of getController. This is because now file picker uses action sheet instead of a new view.
* The function $mmaModForumOffline#convertOfflineReplyToOnline is now in $mmaModForumHelper.
* New Phonegap plugin installed. Please run:
ionic plugin add cordova-universal-clipboard
or
Expand Down
100 changes: 5 additions & 95 deletions www/addons/mod/assign/services/helper.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ angular.module('mm.addons.mod_assign')
* @ngdoc service
* @name $mmaModAssignHelper
*/
.factory('$mmaModAssignHelper', function($mmUtil, $mmaModAssignSubmissionDelegate, $q, $mmSite, $mmFS, $mmFilepool, $mmaModAssign,
.factory('$mmaModAssignHelper', function($mmUtil, $mmaModAssignSubmissionDelegate, $q, $mmSite, $mmFS, $mmaModAssign,
$mmFileUploader, mmaModAssignComponent, $mmaModAssignOffline, $mmaModAssignFeedbackDelegate) {

var self = {};
Expand Down Expand Up @@ -374,47 +374,9 @@ angular.module('mm.addons.mod_assign')
self.storeSubmissionFiles = function(assignId, pluginName, files, userId, siteId) {
siteId = siteId || $mmSite.getId();

var result = {
online: [],
offline: 0
};

if (!files || !files.length) {
return $q.when(result);
}

// Get the folder where to store the files.
return $mmaModAssignOffline.getSubmissionPluginFolder(assignId, pluginName, userId, siteId).then(function(folderPath) {
// Remove unused files from previous submissions.
return $mmFS.removeUnusedFiles(folderPath, files).then(function() {
var promises = [];

angular.forEach(files, function(file) {
if (file.filename && !file.name) {
// It's an online file, add it to the result and ignore it.
result.online.push({
filename: file.filename,
fileurl: file.fileurl
});
return;
} else if (!file.name) {
// Error.
promises.push($q.reject());
} else if (file.fullPath && file.fullPath.indexOf(folderPath) != -1) {
// File already in the submission folder.
result.offline++;
} else {
// Local file, copy it. Use copy instead of move to prevent having a unstable state if
// some copies succeed and others don't.
var destFile = $mmFS.concatenatePaths(folderPath, file.name);
promises.push($mmFS.copyFile(file.toURL(), destFile));
result.offline++;
}
});

return $q.all(promises).then(function() {
return result;
});
});
return $mmFileUploader.storeFilesToUpload(folderPath, files);
});
};

Expand All @@ -431,30 +393,7 @@ angular.module('mm.addons.mod_assign')
* @return {Promise} Promise resolved with the itemId.
*/
self.uploadFile = function(assignId, file, itemId, siteId) {
siteId = siteId || $mmSite.getId();

var promise,
fileName;

if (file.filename && !file.name) {
// It's an online file. We need to download it and re-upload it.
fileName = file.filename;
promise = $mmFilepool.downloadUrl(siteId, file.fileurl, false, mmaModAssignComponent, assignId).then(function(path) {
return $mmFS.getExternalFile(path);
});
} else {
// Local file, we already have the file entry.
fileName = file.name;
promise = $q.when(file);
}

return promise.then(function(fileEntry) {
// Now upload the file.
return $mmFileUploader.uploadGenericFile(fileEntry.toURL(), fileName, fileEntry.type, true, 'draft', itemId, siteId)
.then(function(result) {
return result.itemid;
});
});
return $mmFileUploader.uploadOrReuploadFile(file, itemId, mmaModAssignComponent, assignId, siteId);
};

/**
Expand All @@ -471,36 +410,7 @@ angular.module('mm.addons.mod_assign')
* @return {Promise} Promise resolved with the itemId.
*/
self.uploadFiles = function(assignId, files, siteId) {
siteId = siteId || $mmSite.getId();

if (!files || !files.length) {
// Return fake draft ID.
return $q.when(1);
}

// Upload only the first file first to get a draft id.
return self.uploadFile(assignId, files[0]).then(function(itemId) {
var promises = [],
error;

angular.forEach(files, function(file, index) {
if (index === 0) {
// First file has already been uploaded.
return;
}

promises.push(self.uploadFile(assignId, file, itemId, siteId).catch(function(message) {
error = message;
return $q.reject();
}));
});

return $q.all(promises).then(function() {
return itemId;
}).catch(function() {
return $q.reject(error);
});
});
return $mmFileUploader.uploadOrReuploadFiles(files, mmaModAssignComponent, assignId, siteId);
};

/**
Expand Down
122 changes: 68 additions & 54 deletions www/addons/mod/forum/controllers/discussion.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,29 +23,34 @@ angular.module('mm.addons.mod_forum')
*/
.controller('mmaModForumDiscussionCtrl', function($q, $scope, $stateParams, $mmaModForum, $mmSite, $mmUtil, $translate, $mmEvents,
$ionicScrollDelegate, mmaModForumComponent, mmaModForumReplyDiscussionEvent, $mmaModForumOffline, $mmaModForumSync,
mmaModForumAutomSyncedEvent, mmaModForumManualSyncedEvent, $mmApp, $ionicPlatform, mmCoreEventOnlineStatusChanged) {
mmaModForumAutomSyncedEvent, mmaModForumManualSyncedEvent, $mmApp, $ionicPlatform, mmCoreEventOnlineStatusChanged,
$mmaModForumHelper) {

var discussionId = $stateParams.discussionid,
courseid = $stateParams.cid,
courseId = $stateParams.cid,
forumId = $stateParams.forumid,
cmid = $stateParams.cmid,
scrollView,
syncObserver, syncManualObserver, onlineObserver;

// Block leaving the view, we want to show a confirm to the user if there's unsaved data.
$mmUtil.blockLeaveView($scope, leaveView);

$scope.discussionId = discussionId;
$scope.trackPosts = $stateParams.trackposts;
$scope.component = mmaModForumComponent;
$scope.discussionStr = $translate.instant('discussion');
$scope.componentId = cmid;
$scope.courseid = courseid;
$scope.courseId = courseId;
$scope.refreshPostsIcon = 'spinner';
$scope.syncIcon = 'spinner';
$scope.newpost = {
$scope.newPost = {
replyingto: undefined,
editing: undefined,
subject: '',
text: '',
isEditing: false
isEditing: false,
files: []
};
$scope.sort = {
icon: 'ion-arrow-up-c',
Expand All @@ -60,12 +65,14 @@ angular.module('mm.addons.mod_forum')
// Receive locked as param since it's returned by getDiscussions. This means that PullToRefresh won't update this value.
$scope.locked = !!$stateParams.locked;

$scope.originalData = {};

// Convenience function to get the forum.
function fetchForum() {
if (courseid && cmid) {
return $mmaModForum.getForum(courseid, cmid);
} else if (courseid && forumId) {
return $mmaModForum.getForumById(courseid, forumId);
if (courseId && cmid) {
return $mmaModForum.getForum(courseId, cmid);
} else if (courseId && forumId) {
return $mmaModForum.getForumById(courseId, forumId);
} else {
// Cannot get the forum.
return $q.reject();
Expand Down Expand Up @@ -95,44 +102,39 @@ angular.module('mm.addons.mod_forum')

}).then(function() {
// Check if there are responses stored in offline.
return $mmaModForumOffline.hasDiscussionReplies(discussionId).then(function(hasOffline) {
$scope.postHasOffline = hasOffline;

if (hasOffline) {
return $mmaModForumOffline.getDiscussionReplies(discussionId).then(function(replies) {
var convertPromises = [];

// Index posts to allow quick access.
var posts = {};
angular.forEach(onlinePosts, function(post) {
posts[post.id] = post;
});

angular.forEach(replies, function(offlineReply) {
// If we don't have forumId and courseId, get it from the post.
if (!forumId) {
forumId = offlineReply.forumid;
}
if (!courseid) {
courseid = offlineReply.courseid;
$scope.courseid = courseid;
}

convertPromises.push($mmaModForumOffline.convertOfflineReplyToOnline(offlineReply)
.then(function(reply) {
offlineReplies.push(reply);

// Disable reply of the parent. Reply in offline to the same post is not allowed, edit instead.
posts[reply.parent].canreply = false;
}));
});

return $q.all(convertPromises).then(function() {
// Convert back to array.
onlinePosts = Object.keys(posts).map(function (key) {return posts[key];});
});
});
}
return $mmaModForumOffline.getDiscussionReplies(discussionId).then(function(replies) {
$scope.postHasOffline = !!replies.length;

var convertPromises = [];

// Index posts to allow quick access.
var posts = {};
angular.forEach(onlinePosts, function(post) {
posts[post.id] = post;
});

angular.forEach(replies, function(offlineReply) {
// If we don't have forumId and courseId, get it from the post.
if (!forumId) {
forumId = offlineReply.forumid;
}
if (!courseId) {
courseId = offlineReply.courseid;
$scope.courseId = courseId;
}

convertPromises.push($mmaModForumHelper.convertOfflineReplyToOnline(offlineReply).then(function(reply) {
offlineReplies.push(reply);

// Disable reply of the parent. Reply in offline to the same post is not allowed, edit instead.
posts[reply.parent].canreply = false;
}));
});

return $q.all(convertPromises).then(function() {
// Convert back to array.
onlinePosts = Object.keys(posts).map(function (key) {return posts[key];});
});
});
});
}).then(function() {
Expand All @@ -149,7 +151,7 @@ angular.module('mm.addons.mod_forum')
$scope.posts = $mmaModForum.sortDiscussionPosts(posts, $scope.sort.direction);
}
$scope.defaultSubject = $translate.instant('mma.mod_forum.re') + ' ' + $scope.discussion.subject;
$scope.newpost.subject = $scope.defaultSubject;
$scope.newPost.subject = $scope.defaultSubject;

// Now try to get the forum.
return fetchForum().then(function(forum) {
Expand All @@ -161,6 +163,7 @@ angular.module('mm.addons.mod_forum')
forumId = forum.id;
cmid = forum.cmid;
$scope.componentId = cmid;
$scope.forum = forum;
}).catch(function() {
// Ignore errors.
});
Expand Down Expand Up @@ -303,6 +306,23 @@ angular.module('mm.addons.mod_forum')
}
});

// Ask to confirm if there are changes.
function leaveView() {
var promise;

if (!$mmaModForumHelper.hasPostDataChanged($scope.newPost, $scope.originalData)) {
promise = $q.when();
} else {
// Show confirmation if some data has been modified.
promise = $mmUtil.showConfirm($translate('mm.core.confirmcanceledit'));
}

return promise.then(function() {
// Delete the local files from the tmp folder.
$mmaModForumHelper.clearTmpFiles($scope.newPost.files);
});
}

function scrollTop() {
if (!scrollView) {
scrollView = $ionicScrollDelegate.$getByHandle('mmaModForumPostsScroll');
Expand All @@ -312,12 +332,6 @@ angular.module('mm.addons.mod_forum')

// New post added.
$scope.postListChanged = function() {
$scope.newpost.replyingto = undefined;
$scope.newpost.editing = undefined;
$scope.newpost.subject = $scope.defaultSubject;
$scope.newpost.text = '';
$scope.newpost.isEditing = false;

notifyPostListChanged();

$scope.discussionLoaded = false;
Expand Down
Loading