From 8cdca2ebd9f516d082db61fec66ec1a65adb2484 Mon Sep 17 00:00:00 2001 From: Albert Gasset Date: Tue, 30 Apr 2019 12:57:44 +0200 Subject: [PATCH 1/2] MOBILE-2989 forum: Add ability to star and pin discussions --- scripts/langindex.json | 7 ++ .../index/addon-mod-forum-index.html | 6 +- .../mod/forum/components/index/index.scss | 3 + .../components/post/addon-mod-forum-post.html | 6 +- src/addon/mod/forum/components/post/post.scss | 5 ++ src/addon/mod/forum/lang/en.json | 7 ++ .../forum/pages/discussion/discussion.html | 4 ++ .../mod/forum/pages/discussion/discussion.ts | 64 +++++++++++++++++++ src/addon/mod/forum/providers/forum.ts | 40 ++++++++++++ src/assets/lang/en.json | 7 ++ .../course-progress/course-progress.scss | 2 - src/theme/variables.scss | 1 + 12 files changed, 148 insertions(+), 4 deletions(-) create mode 100644 src/addon/mod/forum/components/post/post.scss diff --git a/scripts/langindex.json b/scripts/langindex.json index d2658bf07..f6ce38df0 100644 --- a/scripts/langindex.json +++ b/scripts/langindex.json @@ -478,6 +478,7 @@ "addon.mod_forum.addanewdiscussion": "forum", "addon.mod_forum.addanewquestion": "forum", "addon.mod_forum.addanewtopic": "forum", + "addon.mod_forum.addtofavourites": "forum", "addon.mod_forum.advanced": "forum", "addon.mod_forum.cannotadddiscussion": "forum", "addon.mod_forum.cannotadddiscussionall": "forum", @@ -492,9 +493,11 @@ "addon.mod_forum.erroremptysubject": "forum", "addon.mod_forum.errorgetforum": "local_moodlemobileapp", "addon.mod_forum.errorgetgroups": "local_moodlemobileapp", + "addon.mod_forum.favouriteupdated": "forum", "addon.mod_forum.forumnodiscussionsyet": "local_moodlemobileapp", "addon.mod_forum.group": "local_moodlemobileapp", "addon.mod_forum.locked": "forum", + "addon.mod_forum.lockupdated": "forum", "addon.mod_forum.message": "forum", "addon.mod_forum.modeflatnewestfirst": "forum", "addon.mod_forum.modeflatoldestfirst": "forum", @@ -503,15 +506,19 @@ "addon.mod_forum.notlocked": "forum", "addon.mod_forum.numdiscussions": "local_moodlemobileapp", "addon.mod_forum.numreplies": "local_moodlemobileapp", + "addon.mod_forum.pindiscussion": "forum", + "addon.mod_forum.pinupdated": "forum", "addon.mod_forum.postisprivatereply": "forum", "addon.mod_forum.posttoforum": "forum", "addon.mod_forum.privatereply": "forum", "addon.mod_forum.re": "forum", "addon.mod_forum.refreshdiscussions": "local_moodlemobileapp", "addon.mod_forum.refreshposts": "local_moodlemobileapp", + "addon.mod_forum.removefromfavourites": "forum", "addon.mod_forum.reply": "forum", "addon.mod_forum.replyplaceholder": "forum", "addon.mod_forum.subject": "forum", + "addon.mod_forum.unpindiscussion": "forum", "addon.mod_forum.unread": "forum", "addon.mod_forum.unreadpostsnumber": "forum", "addon.mod_glossary.addentry": "glossary", 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 47b6037c1..3bb9fee79 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 @@ -45,7 +45,11 @@ -

+

+ + + +

{{discussion.created | coreDateDayOrTime}} diff --git a/src/addon/mod/forum/components/index/index.scss b/src/addon/mod/forum/components/index/index.scss index 5234ac16e..09429a4e4 100644 --- a/src/addon/mod/forum/components/index/index.scss +++ b/src/addon/mod/forum/components/index/index.scss @@ -2,4 +2,7 @@ ion-app.app-root addon-mod-forum-index { .addon-forum-discussion-selected { border-top: 5px solid $core-splitview-selected; } + .addon-forum-star { + color: $core-star-color; + } } diff --git a/src/addon/mod/forum/components/post/addon-mod-forum-post.html b/src/addon/mod/forum/components/post/addon-mod-forum-post.html index a1d0e09d9..8918cadb5 100644 --- a/src/addon/mod/forum/components/post/addon-mod-forum-post.html +++ b/src/addon/mod/forum/components/post/addon-mod-forum-post.html @@ -1,7 +1,11 @@ -

+

+ + + +

{{ 'core.notsent' | translate }} diff --git a/src/addon/mod/forum/components/post/post.scss b/src/addon/mod/forum/components/post/post.scss new file mode 100644 index 000000000..43358381e --- /dev/null +++ b/src/addon/mod/forum/components/post/post.scss @@ -0,0 +1,5 @@ +ion-app.app-root addon-mod-forum-post { + .addon-forum-star { + color: $core-star-color; + } +} diff --git a/src/addon/mod/forum/lang/en.json b/src/addon/mod/forum/lang/en.json index ea720c2ff..7305a22b7 100644 --- a/src/addon/mod/forum/lang/en.json +++ b/src/addon/mod/forum/lang/en.json @@ -2,6 +2,7 @@ "addanewdiscussion": "Add a new discussion topic", "addanewquestion": "Add a new question", "addanewtopic": "Add a new topic", + "addtofavourites": "Star this discussion", "advanced": "Advanced", "cannotadddiscussion": "Adding discussions to this forum requires group membership.", "cannotadddiscussionall": "You do not have permission to add a new discussion topic for all participants.", @@ -16,9 +17,11 @@ "erroremptysubject": "Post subject cannot be empty.", "errorgetforum": "Error getting forum data.", "errorgetgroups": "Error getting group settings.", + "favouriteupdated": "Your star option has been updated.", "forumnodiscussionsyet": "There are no discussions yet in this forum.", "group": "Group", "locked": "Locked", + "lockupdated": "The lock option has been updated.", "message": "Message", "modeflatnewestfirst": "Display replies flat, with newest first", "modeflatoldestfirst": "Display replies flat, with oldest first", @@ -27,15 +30,19 @@ "notlocked": "Lock", "numdiscussions": "{{numdiscussions}} discussions", "numreplies": "{{numreplies}} replies", + "pindiscussion": "Pin this discussion", + "pinupdated": "The pin option has been updated.", "postisprivatereply": "This post was made privately and is not visible to all users.", "posttoforum": "Post to forum", "privatereply": "Reply privately", "re": "Re:", "refreshdiscussions": "Refresh discussions", "refreshposts": "Refresh posts", + "removefromfavourites": "Unstar this discussion", "reply": "Reply", "replyplaceholder": "Write your reply...", "subject": "Subject", + "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 434ac76e2..73ca29418 100644 --- a/src/addon/mod/forum/pages/discussion/discussion.html +++ b/src/addon/mod/forum/pages/discussion/discussion.html @@ -15,6 +15,10 @@ + + + + diff --git a/src/addon/mod/forum/pages/discussion/discussion.ts b/src/addon/mod/forum/pages/discussion/discussion.ts index 8b3a81a42..0f076b58b 100644 --- a/src/addon/mod/forum/pages/discussion/discussion.ts +++ b/src/addon/mod/forum/pages/discussion/discussion.ts @@ -76,6 +76,7 @@ export class AddonModForumDiscussionPage implements OnDestroy { discussionStr = ''; component = AddonModForumProvider.COMPONENT; cmId: number; + canPin = false; protected forumId: number; protected postId: number; @@ -349,6 +350,13 @@ export class AddonModForumDiscussionPage implements OnDestroy { this.posts = posts; this.ratingInfo = ratingInfo; }); + }).then(() => { + // Use the canAddDiscussion WS to check if the user can pin discussions. + return this.forumProvider.canAddDiscussionToAll(this.forumId).then((response) => { + this.canPin = !!response.canpindiscussions; + }).catch(() => { + this.canPin = false; + }); }).then(() => { return this.ratingOffline.hasRatings('mod_forum', 'post', 'module', this.cmId, this.discussionId).then((hasRatings) => { this.hasOfflineRatings = hasRatings; @@ -491,6 +499,62 @@ export class AddonModForumDiscussionPage implements OnDestroy { locked: this.discussion.locked }; this.eventsProvider.trigger(AddonModForumProvider.CHANGE_DISCUSSION_EVENT, data, this.sitesProvider.getCurrentSiteId()); + + this.domUtils.showToast('addon.mod_forum.lockupdated', true); + }).catch((error) => { + this.domUtils.showErrorModal(error); + }).finally(() => { + modal.dismiss(); + }); + } + + /** + * Pin or unpin the discussion. + * + * @param {boolean} pinned True to pin the discussion, false to unpin it. + */ + setPinState(pinned: boolean): void { + const modal = this.domUtils.showModalLoading('core.sending', true); + + this.forumProvider.setPinState(this.discussionId, pinned).then(() => { + this.discussion.pinned = pinned; + + const data = { + forumId: this.forumId, + discussionId: this.discussionId, + cmId: this.cmId, + pinned: this.discussion.pinned + }; + this.eventsProvider.trigger(AddonModForumProvider.CHANGE_DISCUSSION_EVENT, data, this.sitesProvider.getCurrentSiteId()); + + this.domUtils.showToast('addon.mod_forum.pinupdated', true); + }).catch((error) => { + this.domUtils.showErrorModal(error); + }).finally(() => { + modal.dismiss(); + }); + } + + /** + * Star or unstar the discussion. + * + * @param {boolean} starred True to star the discussion, false to unstar it. + */ + toggleFavouriteState(starred: boolean): void { + const modal = this.domUtils.showModalLoading('core.sending', true); + + this.forumProvider.toggleFavouriteState(this.discussionId, starred).then(() => { + this.discussion.starred = starred; + + const data = { + forumId: this.forumId, + discussionId: this.discussionId, + cmId: this.cmId, + starred: this.discussion.starred + }; + this.eventsProvider.trigger(AddonModForumProvider.CHANGE_DISCUSSION_EVENT, data, this.sitesProvider.getCurrentSiteId()); + + this.domUtils.showToast('addon.mod_forum.favouriteupdated', true); }).catch((error) => { this.domUtils.showErrorModal(error); }).finally(() => { diff --git a/src/addon/mod/forum/providers/forum.ts b/src/addon/mod/forum/providers/forum.ts index 520ed72c5..91f1d2dad 100644 --- a/src/addon/mod/forum/providers/forum.ts +++ b/src/addon/mod/forum/providers/forum.ts @@ -784,6 +784,46 @@ export class AddonModForumProvider { }); } + /** + * Pin or unpin a discussion. + * + * @param {number} discussionId Discussion id. + * @param {boolean} locked True to pin, false to unpin. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resvoled when done. + * @since 3.7 + */ + setPinState(discussionId: number, pinned: boolean, siteId?: string): Promise { + return this.sitesProvider.getSite(siteId).then((site) => { + const params = { + discussionid: discussionId, + targetstate: pinned ? 1 : 0 + }; + + return site.write('mod_forum_set_pin_state', params); + }); + } + + /** + * Star or unstar a discussion. + * + * @param {number} discussionId Discussion id. + * @param {boolean} starred True to star, false to unstar. + * @param {string} [siteId] Site ID. If not defined, current site. + * @return {Promise} Promise resvoled when done. + * @since 3.7 + */ + toggleFavouriteState(discussionId: number, starred: boolean, siteId?: string): Promise { + return this.sitesProvider.getSite(siteId).then((site) => { + const params = { + discussionid: discussionId, + targetstate: starred ? 1 : 0 + }; + + return site.write('mod_forum_toggle_favourite_state', params); + }); + } + /** * Store the users data from a discussions/posts list. * diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json index 5cbef339b..90e9eb8f4 100644 --- a/src/assets/lang/en.json +++ b/src/assets/lang/en.json @@ -478,6 +478,7 @@ "addon.mod_forum.addanewdiscussion": "Add a new discussion topic", "addon.mod_forum.addanewquestion": "Add a new question", "addon.mod_forum.addanewtopic": "Add a new topic", + "addon.mod_forum.addtofavourites": "Star this discussion", "addon.mod_forum.advanced": "Advanced", "addon.mod_forum.cannotadddiscussion": "Adding discussions to this forum requires group membership.", "addon.mod_forum.cannotadddiscussionall": "You do not have permission to add a new discussion topic for all participants.", @@ -492,9 +493,11 @@ "addon.mod_forum.erroremptysubject": "Post subject cannot be empty.", "addon.mod_forum.errorgetforum": "Error getting forum data.", "addon.mod_forum.errorgetgroups": "Error getting group settings.", + "addon.mod_forum.favouriteupdated": "Your star option has been updated.", "addon.mod_forum.forumnodiscussionsyet": "There are no discussions yet in this forum.", "addon.mod_forum.group": "Group", "addon.mod_forum.locked": "Locked", + "addon.mod_forum.lockupdated": "The lock option has been updated.", "addon.mod_forum.message": "Message", "addon.mod_forum.modeflatnewestfirst": "Display replies flat, with newest first", "addon.mod_forum.modeflatoldestfirst": "Display replies flat, with oldest first", @@ -503,15 +506,19 @@ "addon.mod_forum.notlocked": "Lock", "addon.mod_forum.numdiscussions": "{{numdiscussions}} discussions", "addon.mod_forum.numreplies": "{{numreplies}} replies", + "addon.mod_forum.pindiscussion": "Pin this discussion", + "addon.mod_forum.pinupdated": "The pin option has been updated.", "addon.mod_forum.postisprivatereply": "This post was made privately and is not visible to all users.", "addon.mod_forum.posttoforum": "Post to forum", "addon.mod_forum.privatereply": "Reply privately", "addon.mod_forum.re": "Re:", "addon.mod_forum.refreshdiscussions": "Refresh discussions", "addon.mod_forum.refreshposts": "Refresh posts", + "addon.mod_forum.removefromfavourites": "Unstar this discussion", "addon.mod_forum.reply": "Reply", "addon.mod_forum.replyplaceholder": "Write your reply...", "addon.mod_forum.subject": "Subject", + "addon.mod_forum.unpindiscussion": "Unpin this discussion", "addon.mod_forum.unread": "Unread", "addon.mod_forum.unreadpostsnumber": "{{$a}} unread posts", "addon.mod_glossary.addentry": "Add a new entry", diff --git a/src/core/courses/components/course-progress/course-progress.scss b/src/core/courses/components/course-progress/course-progress.scss index fe3712586..471a710bf 100644 --- a/src/core/courses/components/course-progress/course-progress.scss +++ b/src/core/courses/components/course-progress/course-progress.scss @@ -1,5 +1,3 @@ -$core-star-color: $core-color !default; - ion-app.app-root core-courses-course-progress { ion-card.card { display: flex; diff --git a/src/theme/variables.scss b/src/theme/variables.scss index 3cedb3059..be50dc556 100644 --- a/src/theme/variables.scss +++ b/src/theme/variables.scss @@ -126,6 +126,7 @@ $popover-width: 280px !default; $item-divider-background: $gray-lighter !default; $item-divider-color: $black !default; +$core-star-color: $core-color !default; // Moodle Mobile variables // -------------------------------------------------- From ad6d5019f1d55435067161d6b532547cc00f4eb9 Mon Sep 17 00:00:00 2001 From: Albert Gasset Date: Thu, 2 May 2019 10:42:46 +0200 Subject: [PATCH 2/2] MOBILE-2989 forum: Check whether the set pin state WS is available --- src/addon/mod/forum/pages/discussion/discussion.ts | 14 +++++++++----- src/addon/mod/forum/providers/forum.ts | 14 ++++++++++++++ 2 files changed, 23 insertions(+), 5 deletions(-) diff --git a/src/addon/mod/forum/pages/discussion/discussion.ts b/src/addon/mod/forum/pages/discussion/discussion.ts index 0f076b58b..50bff42b8 100644 --- a/src/addon/mod/forum/pages/discussion/discussion.ts +++ b/src/addon/mod/forum/pages/discussion/discussion.ts @@ -351,12 +351,16 @@ export class AddonModForumDiscussionPage implements OnDestroy { this.ratingInfo = ratingInfo; }); }).then(() => { - // Use the canAddDiscussion WS to check if the user can pin discussions. - return this.forumProvider.canAddDiscussionToAll(this.forumId).then((response) => { - this.canPin = !!response.canpindiscussions; - }).catch(() => { + if (this.forumProvider.isSetPinStateAvailableForSite()) { + // Use the canAddDiscussion WS to check if the user can pin discussions. + return this.forumProvider.canAddDiscussionToAll(this.forumId).then((response) => { + this.canPin = !!response.canpindiscussions; + }).catch(() => { + this.canPin = false; + }); + } else { this.canPin = false; - }); + } }).then(() => { return this.ratingOffline.hasRatings('mod_forum', 'post', 'module', this.cmId, this.discussionId).then((hasRatings) => { this.hasOfflineRatings = hasRatings; diff --git a/src/addon/mod/forum/providers/forum.ts b/src/addon/mod/forum/providers/forum.ts index 91f1d2dad..6bd80e7bd 100644 --- a/src/addon/mod/forum/providers/forum.ts +++ b/src/addon/mod/forum/providers/forum.ts @@ -14,6 +14,7 @@ import { Injectable } from '@angular/core'; import { TranslateService } from '@ngx-translate/core'; +import { CoreSite } from '@classes/site'; import { CoreAppProvider } from '@providers/app'; import { CoreFilepoolProvider } from '@providers/filepool'; import { CoreGroupsProvider } from '@providers/groups'; @@ -784,6 +785,19 @@ export class AddonModForumProvider { }); } + /** + * Returns whether the set pin state WS is available. + * + * @param {CoreSite} [site] Site. If not defined, current site. + * @return {boolean} Whether it's available. + * @since 3.7 + */ + isSetPinStateAvailableForSite(site?: CoreSite): boolean { + site = site || this.sitesProvider.getCurrentSite(); + + return this.sitesProvider.wsAvailableInCurrentSite('mod_forum_set_pin_state'); + } + /** * Pin or unpin a discussion. *