diff --git a/scripts/langindex.json b/scripts/langindex.json index 4e3c2d93d..f3702f753 100644 --- a/scripts/langindex.json +++ b/scripts/langindex.json @@ -487,6 +487,7 @@ "addon.mod_forum.cannotadddiscussionall": "forum", "addon.mod_forum.cannotcreatediscussion": "forum", "addon.mod_forum.couldnotadd": "forum", + "addon.mod_forum.cutoffdatereached": "forum", "addon.mod_forum.discussion": "forum", "addon.mod_forum.discussionlocked": "forum", "addon.mod_forum.discussionpinned": "forum", @@ -521,6 +522,8 @@ "addon.mod_forum.reply": "forum", "addon.mod_forum.replyplaceholder": "forum", "addon.mod_forum.subject": "forum", + "addon.mod_forum.thisforumhasduedate": "forum", + "addon.mod_forum.thisforumisdue": "forum", "addon.mod_forum.unpindiscussion": "forum", "addon.mod_forum.unread": "forum", "addon.mod_forum.unreadpostsnumber": "forum", diff --git a/src/addon/mod/forum/components/index/addon-mod-forum-index.html b/src/addon/mod/forum/components/index/addon-mod-forum-index.html index 3bb9fee79..497f32f02 100644 --- a/src/addon/mod/forum/components/index/addon-mod-forum-index.html +++ b/src/addon/mod/forum/components/index/addon-mod-forum-index.html @@ -25,6 +25,11 @@ {{ 'core.hasdatatosync' | translate:{$a: moduleName} }} + + + {{ availabilityMessage }} + + diff --git a/src/addon/mod/forum/components/index/index.ts b/src/addon/mod/forum/components/index/index.ts index b3c8769e7..60ee32288 100644 --- a/src/addon/mod/forum/components/index/index.ts +++ b/src/addon/mod/forum/components/index/index.ts @@ -49,6 +49,7 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom offlineDiscussions = []; selectedDiscussion = 0; // Disucssion ID or negative timecreated if it's an offline discussion. addDiscussionText = this.translate.instant('addon.mod_forum.addanewdiscussion'); + availabilityMessage: string; protected syncEventName = AddonModForumSyncProvider.AUTO_SYNCED; protected page = 0; @@ -168,6 +169,7 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom if (typeof forum.istracked != 'undefined') { this.trackPosts = forum.istracked; } + this.availabilityMessage = this.forumHelper.getAvailabilityMessage(forum); this.dataRetrieved.emit(forum); diff --git a/src/addon/mod/forum/lang/en.json b/src/addon/mod/forum/lang/en.json index 7305a22b7..04f70e158 100644 --- a/src/addon/mod/forum/lang/en.json +++ b/src/addon/mod/forum/lang/en.json @@ -8,6 +8,7 @@ "cannotadddiscussionall": "You do not have permission to add a new discussion topic for all participants.", "cannotcreatediscussion": "Could not create new discussion", "couldnotadd": "Could not add your post due to an unknown error", + "cutoffdatereached": "The cut-off date for posting to this forum is reached so you can no longer post to it.", "discussion": "Discussion", "discussionlocked": "This discussion has been locked so you can no longer reply to it.", "discussionpinned": "Pinned", @@ -42,6 +43,8 @@ "reply": "Reply", "replyplaceholder": "Write your reply...", "subject": "Subject", + "thisforumhasduedate": "The due date for posting to this forum is {{$a}}.", + "thisforumisdue": "The due date for posting to this forum was {{$a}}.", "unpindiscussion": "Unpin this discussion", "unread": "Unread", "unreadpostsnumber": "{{$a}} unread posts" diff --git a/src/addon/mod/forum/pages/discussion/discussion.html b/src/addon/mod/forum/pages/discussion/discussion.html index 73ca29418..b569fb0d1 100644 --- a/src/addon/mod/forum/pages/discussion/discussion.html +++ b/src/addon/mod/forum/pages/discussion/discussion.html @@ -32,8 +32,13 @@ {{ 'core.hasdatatosync' | translate:{$a: discussionStr} }} - - {{ 'addon.mod_forum.discussionlocked' | translate }} + + + {{ availabilityMessage }} + + + + {{ 'addon.mod_forum.discussionlocked' | translate }} diff --git a/src/addon/mod/forum/pages/discussion/discussion.ts b/src/addon/mod/forum/pages/discussion/discussion.ts index 50bff42b8..9d0a44fee 100644 --- a/src/addon/mod/forum/pages/discussion/discussion.ts +++ b/src/addon/mod/forum/pages/discussion/discussion.ts @@ -77,6 +77,7 @@ export class AddonModForumDiscussionPage implements OnDestroy { component = AddonModForumProvider.COMPONENT; cmId: number; canPin = false; + availabilityMessage: string; protected forumId: number; protected postId: number; @@ -311,6 +312,7 @@ export class AddonModForumDiscussionPage implements OnDestroy { this.forumId = forum.id; this.cmId = forum.cmid; this.forum = forum; + this.availabilityMessage = this.forumHelper.getAvailabilityMessage(forum); const promises = []; @@ -460,6 +462,7 @@ export class AddonModForumDiscussionPage implements OnDestroy { this.syncIcon = 'spinner'; const promises = [ + this.forumProvider.invalidateForumData(this.courseId), this.forumProvider.invalidateDiscussionPosts(this.discussionId), this.forumProvider.invalidateAccessInformation(this.forumId) ]; diff --git a/src/addon/mod/forum/providers/helper.ts b/src/addon/mod/forum/providers/helper.ts index eeeb4a0f7..3e5928bde 100644 --- a/src/addon/mod/forum/providers/helper.ts +++ b/src/addon/mod/forum/providers/helper.ts @@ -13,9 +13,11 @@ // limitations under the License. import { Injectable } from '@angular/core'; +import { TranslateService } from '@ngx-translate/core'; import { CoreFileProvider } from '@providers/file'; import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader'; import { CoreSitesProvider } from '@providers/sites'; +import { CoreTimeUtilsProvider } from '@providers/utils/time'; import { CoreUserProvider } from '@core/user/providers/user'; import { AddonModForumProvider } from './forum'; import { AddonModForumOfflineProvider } from './offline'; @@ -25,9 +27,11 @@ import { AddonModForumOfflineProvider } from './offline'; */ @Injectable() export class AddonModForumHelperProvider { - constructor(private fileProvider: CoreFileProvider, + constructor(private translate: TranslateService, + private fileProvider: CoreFileProvider, private sitesProvider: CoreSitesProvider, private uploaderProvider: CoreFileUploaderProvider, + private timeUtils: CoreTimeUtilsProvider, private userProvider: CoreUserProvider, private forumProvider: AddonModForumProvider, private forumOffline: AddonModForumOfflineProvider) {} @@ -122,6 +126,28 @@ export class AddonModForumHelperProvider { }); } + /** + * Returns the availability message of the given forum. + * + * @param {any} forum Forum instance. + * @return {string} Message or null if the forum has no cut-off or due date. + */ + getAvailabilityMessage(forum: any): string { + if (this.isCutoffDateReached(forum)) { + return this.translate.instant('addon.mod_forum.cutoffdatereached'); + } else if (this.isDueDateReached(forum)) { + const dueDate = this.timeUtils.userDate(forum.duedate * 1000); + + return this.translate.instant('addon.mod_forum.thisforumisdue', {$a: dueDate}); + } else if (forum.duedate > 0) { + const dueDate = this.timeUtils.userDate(forum.duedate * 1000); + + return this.translate.instant('addon.mod_forum.thisforumhasduedate', {$a: dueDate}); + } else { + return null; + } + } + /** * Get a forum discussion by id. * @@ -207,6 +233,30 @@ export class AddonModForumHelperProvider { return this.uploaderProvider.areFileListDifferent(post.files, original.files); } + /** + * Is the cutoff date for the forum reached? + * + * @param {any} forum Forum instance. + * @return {boolean} + */ + isCutoffDateReached(forum: any): boolean { + const now = Date.now() / 1000; + + return forum.cutoffdate > 0 && forum.cutoffdate < now; + } + + /** + * Is the due date for the forum reached? + * + * @param {any} forum Forum instance. + * @return {boolean} + */ + isDueDateReached(forum: any): boolean { + const now = Date.now() / 1000; + + return forum.duedate > 0 && forum.duedate < now; + } + /** * Given a list of files (either online files or local files), store the local files in a local folder * to be submitted later. diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json index 12840934a..40e85aa93 100644 --- a/src/assets/lang/en.json +++ b/src/assets/lang/en.json @@ -487,6 +487,7 @@ "addon.mod_forum.cannotadddiscussionall": "You do not have permission to add a new discussion topic for all participants.", "addon.mod_forum.cannotcreatediscussion": "Could not create new discussion", "addon.mod_forum.couldnotadd": "Could not add your post due to an unknown error", + "addon.mod_forum.cutoffdatereached": "The cut-off date for posting to this forum is reached so you can no longer post to it.", "addon.mod_forum.discussion": "Discussion", "addon.mod_forum.discussionlocked": "This discussion has been locked so you can no longer reply to it.", "addon.mod_forum.discussionpinned": "Pinned", @@ -521,6 +522,8 @@ "addon.mod_forum.reply": "Reply", "addon.mod_forum.replyplaceholder": "Write your reply...", "addon.mod_forum.subject": "Subject", + "addon.mod_forum.thisforumhasduedate": "The due date for posting to this forum is {{$a}}.", + "addon.mod_forum.thisforumisdue": "The due date for posting to this forum was {{$a}}.", "addon.mod_forum.unpindiscussion": "Unpin this discussion", "addon.mod_forum.unread": "Unread", "addon.mod_forum.unreadpostsnumber": "{{$a}} unread posts", @@ -1263,10 +1266,12 @@ "core.course.activitynotyetviewablesiteupgradeneeded": "Your organisation's Moodle installation needs to be updated.", "core.course.allsections": "All sections", "core.course.askadmintosupport": "Contact the site administrator and tell them you want to use this activity with the Moodle Mobile app.", + "core.course.availablespace": " You currently have about {{available}} free space.", "core.course.confirmdeletemodulefiles": "Are you sure you want to delete these files?", - "core.course.confirmdownload": "You are about to download {{size}}. Are you sure you want to continue?", - "core.course.confirmdownloadunknownsize": "It was not possible to calculate the size of the download. Are you sure you want to continue?", - "core.course.confirmpartialdownloadsize": "You are about to download at least {{size}}. Are you sure you want to continue?", + "core.course.confirmdownload": "You are about to download {{size}}.{{availableSpace}} Are you sure you want to continue?", + "core.course.confirmdownloadunknownsize": "It was not possible to calculate the size of the download.{{availableSpace}} Are you sure you want to continue?", + "core.course.confirmlimiteddownload": "You are not currently connected to WiFi. ", + "core.course.confirmpartialdownloadsize": "You are about to download at least {{size}}.{{availableSpace}} Are you sure you want to continue?", "core.course.contents": "Contents", "core.course.couldnotloadsectioncontent": "Could not load the section content. Please try again later.", "core.course.couldnotloadsections": "Could not load the sections. Please try again later.", @@ -1277,6 +1282,8 @@ "core.course.errorgetmodule": "Error getting activity data.", "core.course.hiddenfromstudents": "Hidden from students", "core.course.hiddenoncoursepage": "Available but not shown on course page", + "core.course.insufficientavailablequota": "Your device could not allocate space to save this download. It may be reserving space for app and system updates. Please clear some storage space first.", + "core.course.insufficientavailablespace": "You are trying to download {{size}}. This will leave your device with insufficient space to operate normally. Please clear some storage space first.", "core.course.manualcompletionnotsynced": "Manual completion not synchronised.", "core.course.nocontentavailable": "No content available at the moment.", "core.course.overriddennotice": "Your final grade from this activity was manually adjusted.",