diff --git a/scripts/langindex.json b/scripts/langindex.json
index 1afd0fd4a..0cbd6b03a 100644
--- a/scripts/langindex.json
+++ b/scripts/langindex.json
@@ -483,6 +483,12 @@
"addon.mod_forum.addanewtopic": "forum",
"addon.mod_forum.addtofavourites": "forum",
"addon.mod_forum.advanced": "forum",
+ "addon.mod_forum.bycreateddesc": "local_moodlemobileapp",
+ "addon.mod_forum.bycreatedasc": "local_moodlemobileapp",
+ "addon.mod_forum.bylastpostdesc": "local_moodlemobileapp",
+ "addon.mod_forum.bylastpostasc": "local_moodlemobileapp",
+ "addon.mod_forum.byrepliesdesc": "local_moodlemobileapp",
+ "addon.mod_forum.byrepliesasc": "local_moodlemobileapp",
"addon.mod_forum.cannotadddiscussion": "forum",
"addon.mod_forum.cannotadddiscussionall": "forum",
"addon.mod_forum.cannotcreatediscussion": "forum",
@@ -1734,6 +1740,7 @@
"core.sizemb": "moodle",
"core.sizetb": "local_moodlemobileapp",
"core.sorry": "local_moodlemobileapp",
+ "core.sort": "moodle",
"core.sortby": "moodle",
"core.start": "grouptool",
"core.strftimedate": "langconfig",
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 f0f1fa603..9d93ce8b0 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
@@ -8,6 +8,7 @@
+
@@ -30,6 +31,21 @@
{{ availabilityMessage }}
+
+
+
+
+
+
+
+
+
+
0">
@@ -86,14 +102,6 @@
-
-
-
-
-
-
diff --git a/src/addon/mod/forum/components/index/index.scss b/src/addon/mod/forum/components/index/index.scss
index 09429a4e4..733686a59 100644
--- a/src/addon/mod/forum/components/index/index.scss
+++ b/src/addon/mod/forum/components/index/index.scss
@@ -2,7 +2,15 @@ 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;
}
+
+ button.core-button-select .core-section-selector-text {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ line-height: 2em;
+ white-space: nowrap;
+ }
}
diff --git a/src/addon/mod/forum/components/index/index.ts b/src/addon/mod/forum/components/index/index.ts
index 762df73f4..6b8a5994c 100644
--- a/src/addon/mod/forum/components/index/index.ts
+++ b/src/addon/mod/forum/components/index/index.ts
@@ -13,7 +13,7 @@
// limitations under the License.
import { Component, Optional, Injector, ViewChild } from '@angular/core';
-import { Content, NavController } from 'ionic-angular';
+import { Content, ModalController, NavController } from 'ionic-angular';
import { CoreSplitViewComponent } from '@components/split-view/split-view';
import { CoreCourseModuleMainActivityComponent } from '@core/course/classes/main-activity-component';
import { CoreCourseModulePrefetchDelegate } from '@core/course/providers/module-prefetch-delegate';
@@ -52,6 +52,11 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
addDiscussionText = this.translate.instant('addon.mod_forum.addanewdiscussion');
availabilityMessage: string;
+ sortingAvailable: boolean;
+ sortOrders = [];
+ selectedSortOrder = null;
+ sortOrderSelectorExpanded = false;
+
protected syncEventName = AddonModForumSyncProvider.AUTO_SYNCED;
protected page = 0;
protected trackPosts = false;
@@ -69,6 +74,7 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
constructor(injector: Injector,
@Optional() protected content: Content,
protected navCtrl: NavController,
+ protected modalCtrl: ModalController,
protected groupsProvider: CoreGroupsProvider,
protected userProvider: CoreUserProvider,
protected forumProvider: AddonModForumProvider,
@@ -79,6 +85,9 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
protected prefetchHandler: AddonModForumPrefetchHandler,
protected ratingOffline: CoreRatingOfflineProvider) {
super(injector);
+
+ this.sortingAvailable = this.forumProvider.isDiscussionListSortingAvailable();
+ this.sortOrders = this.forumProvider.getAvailableSortOrders();
}
/**
@@ -162,7 +171,9 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
protected fetchContent(refresh: boolean = false, sync: boolean = false, showErrors: boolean = false): Promise {
this.loadMoreError = false;
- return this.forumProvider.getForum(this.courseId, this.module.id).then((forum) => {
+ const promises = [];
+
+ promises.push(this.forumProvider.getForum(this.courseId, this.module.id).then((forum) => {
this.forum = forum;
this.description = forum.intro || this.description;
@@ -212,7 +223,11 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
this.canAddDiscussion = this.forum.cancreatediscussions && !cutoffDateReached;
}),
]);
- }).then(() => {
+ }));
+
+ promises.push(this.fetchSortOrderPreference());
+
+ return Promise.all(promises).then(() => {
return Promise.all([
this.fetchOfflineDiscussion(),
this.fetchDiscussions(refresh),
@@ -291,7 +306,7 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
this.page = 0;
}
- return this.forumProvider.getDiscussions(this.forum.id, this.page).then((response) => {
+ return this.forumProvider.getDiscussions(this.forum.id, this.selectedSortOrder.value, this.page).then((response) => {
let promise;
if (this.usesGroups) {
promise = this.forumProvider.formatDiscussionsGroups(this.forum.cmid, response.discussions);
@@ -366,6 +381,27 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
});
}
+ /**
+ * Convenience function to fetch the sort order preference.
+ *
+ * @return {Promise} Promise resolved when done.
+ */
+ protected fetchSortOrderPreference(): Promise {
+ let promise;
+ if (this.sortingAvailable) {
+ promise = this.userProvider.getUserPreference(AddonModForumProvider.PREFERENCE_SORTORDER).then((value) => {
+ return value ? parseInt(value, 10) : null;
+ });
+ } else {
+ // Use default.
+ promise = Promise.resolve(null);
+ }
+
+ return promise.then((value) => {
+ this.selectedSortOrder = this.sortOrders.find((sortOrder) => sortOrder.value === value) || this.sortOrders[0];
+ });
+ }
+
/**
* Perform the invalidate content function.
*
@@ -382,6 +418,10 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
promises.push(this.forumProvider.invalidateAccessInformation(this.forum.id));
}
+ if (this.sortingAvailable) {
+ promises.push(this.userProvider.invalidateUserPreference(AddonModForumProvider.PREFERENCE_SORTORDER));
+ }
+
return Promise.all(promises);
}
@@ -484,6 +524,37 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
this.selectedDiscussion = 0;
}
+ /**
+ * Display the sort order selector modal.
+ *
+ * @param {MouseEvent} event Event.
+ */
+ showSortOrderSelector(event: MouseEvent): void {
+ if (!this.sortingAvailable) {
+ return;
+ }
+
+ const params = { sortOrders: this.sortOrders, selected: this.selectedSortOrder.value };
+ const modal = this.modalCtrl.create('AddonModForumSortOrderSelectorPage', params);
+ modal.onDidDismiss((sortOrder) => {
+ this.sortOrderSelectorExpanded = false;
+
+ if (sortOrder && sortOrder.value != this.selectedSortOrder.value) {
+ this.selectedSortOrder = sortOrder;
+ this.page = 0;
+ this.userProvider.setUserPreference(AddonModForumProvider.PREFERENCE_SORTORDER, sortOrder.value.toFixed(0))
+ .then(() => {
+ this.showLoadingAndFetch();
+ }).catch((error) => {
+ this.domUtils.showErrorModalDefault(error, 'Error updating preference.');
+ });
+ }
+ });
+
+ modal.present({ev: event});
+ this.sortOrderSelectorExpanded = true;
+ }
+
/**
* Component being destroyed.
*/
diff --git a/src/addon/mod/forum/lang/en.json b/src/addon/mod/forum/lang/en.json
index 04f70e158..0b0181230 100644
--- a/src/addon/mod/forum/lang/en.json
+++ b/src/addon/mod/forum/lang/en.json
@@ -4,6 +4,12 @@
"addanewtopic": "Add a new topic",
"addtofavourites": "Star this discussion",
"advanced": "Advanced",
+ "bycreateddesc": "By creation date in descending order",
+ "bycreatedasc": "By creation date in ascending order",
+ "bylastpostdesc": "By last post in descending order",
+ "bylastpostasc": "By last post in ascending order",
+ "byrepliesdesc": "By number of replies in descending order",
+ "byrepliesasc": "By number of replies in ascending order",
"cannotadddiscussion": "Adding discussions to this forum requires group membership.",
"cannotadddiscussionall": "You do not have permission to add a new discussion topic for all participants.",
"cannotcreatediscussion": "Could not create new discussion",
diff --git a/src/addon/mod/forum/pages/sort-order-selector/sort-order-selector.html b/src/addon/mod/forum/pages/sort-order-selector/sort-order-selector.html
new file mode 100644
index 000000000..a3411deea
--- /dev/null
+++ b/src/addon/mod/forum/pages/sort-order-selector/sort-order-selector.html
@@ -0,0 +1,19 @@
+
+
+ {{ 'core.sort' | translate }}
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/addon/mod/forum/pages/sort-order-selector/sort-order-selector.module.ts b/src/addon/mod/forum/pages/sort-order-selector/sort-order-selector.module.ts
new file mode 100644
index 000000000..9a10ae395
--- /dev/null
+++ b/src/addon/mod/forum/pages/sort-order-selector/sort-order-selector.module.ts
@@ -0,0 +1,33 @@
+// (C) Copyright 2015 Martin Dougiamas
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { NgModule } from '@angular/core';
+import { IonicPageModule } from 'ionic-angular';
+import { TranslateModule } from '@ngx-translate/core';
+import { CoreComponentsModule } from '@components/components.module';
+import { CoreDirectivesModule } from '@directives/directives.module';
+import { AddonModForumSortOrderSelectorPage } from './sort-order-selector';
+
+@NgModule({
+ declarations: [
+ AddonModForumSortOrderSelectorPage,
+ ],
+ imports: [
+ CoreComponentsModule,
+ CoreDirectivesModule,
+ IonicPageModule.forChild(AddonModForumSortOrderSelectorPage),
+ TranslateModule.forChild()
+ ],
+})
+export class AddonModForumSortOrderSelectorPagePageModule {}
diff --git a/src/addon/mod/forum/pages/sort-order-selector/sort-order-selector.ts b/src/addon/mod/forum/pages/sort-order-selector/sort-order-selector.ts
new file mode 100644
index 000000000..0d83646a6
--- /dev/null
+++ b/src/addon/mod/forum/pages/sort-order-selector/sort-order-selector.ts
@@ -0,0 +1,51 @@
+// (C) Copyright 2015 Martin Dougiamas
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+
+import { Component } from '@angular/core';
+import { IonicPage, NavParams, ViewController } from 'ionic-angular';
+
+/**
+ * Page that displays the sort selector.
+ */
+@IonicPage({ segment: 'addon-mod-forum-sort-order-selector' })
+@Component({
+ selector: 'page-addon-mod-forum-sort-order-selector',
+ templateUrl: 'sort-order-selector.html',
+})
+export class AddonModForumSortOrderSelectorPage {
+
+ sortOrders = [];
+ selected: number;
+
+ constructor(navParams: NavParams, private viewCtrl: ViewController) {
+ this.sortOrders = navParams.get('sortOrders');
+ this.selected = navParams.get('selected');
+ }
+
+ /**
+ * Close the modal.
+ */
+ closeModal(): void {
+ this.viewCtrl.dismiss();
+ }
+
+ /**
+ * Select a sort order.
+ *
+ * @param {any} sortOrder Selected sort order.
+ */
+ selectSortOrder(sortOrder: any): void {
+ this.viewCtrl.dismiss(sortOrder);
+ }
+}
diff --git a/src/addon/mod/forum/providers/forum.ts b/src/addon/mod/forum/providers/forum.ts
index 4a8429e4a..cb78875be 100644
--- a/src/addon/mod/forum/providers/forum.ts
+++ b/src/addon/mod/forum/providers/forum.ts
@@ -14,7 +14,7 @@
import { Injectable } from '@angular/core';
import { TranslateService } from '@ngx-translate/core';
-import { CoreSite } from '@classes/site';
+import { CoreSite, CoreSiteWSPreSets } from '@classes/site';
import { CoreAppProvider } from '@providers/app';
import { CoreFilepoolProvider } from '@providers/filepool';
import { CoreGroupsProvider } from '@providers/groups';
@@ -38,6 +38,14 @@ export class AddonModForumProvider {
static CHANGE_DISCUSSION_EVENT = 'addon_mod_forum_lock_discussion';
static MARK_READ_EVENT = 'addon_mod_forum_mark_read';
+ static PREFERENCE_SORTORDER = 'forum_discussionlistsortorder';
+ static SORTORDER_LASTPOST_DESC = 1;
+ static SORTORDER_LASTPOST_ASC = 2;
+ static SORTORDER_CREATED_DESC = 3;
+ static SORTORDER_CREATED_ASC = 4;
+ static SORTORDER_REPLIES_DESC = 5;
+ static SORTORDER_REPLIES_ASC = 6;
+
protected ROOT_CACHE_KEY = 'mmaModForum:';
constructor(private appProvider: CoreAppProvider,
@@ -105,10 +113,17 @@ export class AddonModForumProvider {
* Get cache key for forum discussions list WS calls.
*
* @param {number} forumId Forum ID.
- * @return {string} Cache key.
+ * @param {number} sortOrder Sort order.
+ * @return {string} Cache key.
*/
- protected getDiscussionsListCacheKey(forumId: number): string {
- return this.ROOT_CACHE_KEY + 'discussions:' + forumId;
+ protected getDiscussionsListCacheKey(forumId: number, sortOrder: number): string {
+ let key = this.ROOT_CACHE_KEY + 'discussions:' + forumId;
+
+ if (sortOrder != AddonModForumProvider.SORTORDER_LASTPOST_DESC) {
+ key += ':' + sortOrder;
+ }
+
+ return key;
}
/**
@@ -452,10 +467,64 @@ export class AddonModForumProvider {
});
}
+ /**
+ * Return whether discussion lists can be sorted.
+ *
+ * @param {CoreSite} [site] Site. If not defined, current site.
+ * @return {boolean} True if discussion lists can be sorted.
+ */
+ isDiscussionListSortingAvailable(site?: CoreSite): boolean {
+ site = site || this.sitesProvider.getCurrentSite();
+
+ return site.isVersionGreaterEqualThan('3.7');
+ }
+
+ /**
+ * Return the list of available sort orders.
+ *
+ * @return {{label: string, value: number}[]} List of sort orders.
+ */
+ getAvailableSortOrders(): {label: string, value: number}[] {
+ const sortOrders = [
+ {
+ label: 'addon.mod_forum.bylastpostdesc',
+ value: AddonModForumProvider.SORTORDER_LASTPOST_DESC
+ },
+ ];
+
+ if (this.isDiscussionListSortingAvailable()) {
+ sortOrders.push(
+ {
+ label: 'addon.mod_forum.bylastpostasc',
+ value: AddonModForumProvider.SORTORDER_LASTPOST_ASC
+ },
+ {
+ label: 'addon.mod_forum.bycreateddesc',
+ value: AddonModForumProvider.SORTORDER_CREATED_DESC
+ },
+ {
+ label: 'addon.mod_forum.bycreatedasc',
+ value: AddonModForumProvider.SORTORDER_CREATED_ASC
+ },
+ {
+ label: 'addon.mod_forum.byrepliesdesc',
+ value: AddonModForumProvider.SORTORDER_REPLIES_DESC
+ },
+ {
+ label: 'addon.mod_forum.byrepliesasc',
+ value: AddonModForumProvider.SORTORDER_REPLIES_ASC
+ }
+ );
+ }
+
+ return sortOrders;
+ }
+
/**
* Get forum discussions.
*
* @param {number} forumId Forum ID.
+ * @param {number} [sortOrder] Sort order.
* @param {number} [page=0] Page.
* @param {boolean} [forceCache] True to always get the value from cache. false otherwise.
* @param {string} [siteId] Site ID. If not defined, current site.
@@ -463,23 +532,59 @@ export class AddonModForumProvider {
* - discussions: List of discussions.
* - canLoadMore: True if there may be more discussions to load.
*/
- getDiscussions(forumId: number, page: number = 0, forceCache?: boolean, siteId?: string): Promise {
+ getDiscussions(forumId: number, sortOrder?: number, page: number = 0, forceCache?: boolean, siteId?: string): Promise {
+ sortOrder = sortOrder || AddonModForumProvider.SORTORDER_LASTPOST_DESC;
+
return this.sitesProvider.getSite(siteId).then((site) => {
- const params = {
+ let method = 'mod_forum_get_forum_discussions_paginated';
+ const params: any = {
forumid: forumId,
- sortby: 'timemodified',
- sortdirection: 'DESC',
page: page,
perpage: AddonModForumProvider.DISCUSSIONS_PER_PAGE
};
- const preSets: any = {
- cacheKey: this.getDiscussionsListCacheKey(forumId)
+
+ if (site.wsAvailable('mod_forum_get_forum_discussions')) {
+ // Since Moodle 3.7.
+ method = 'mod_forum_get_forum_discussions';
+ params.sortorder = sortOrder;
+ } else {
+ if (sortOrder == AddonModForumProvider.SORTORDER_LASTPOST_DESC) {
+ params.sortby = 'timemodified';
+ params.sortdirection = 'DESC';
+ } else {
+ // Sorting not supported with the old WS method.
+ return Promise.reject(null);
+ }
+ }
+ const preSets: CoreSiteWSPreSets = {
+ cacheKey: this.getDiscussionsListCacheKey(forumId, sortOrder)
};
if (forceCache) {
preSets.omitExpires = true;
}
- return site.read('mod_forum_get_forum_discussions_paginated', params, preSets).then((response) => {
+ return site.read(method, params, preSets).catch((error) => {
+ // Try to get the data from cache stored with the old WS method.
+ if (!this.appProvider.isOnline() && method == 'mod_forum_get_forum_discussion' &&
+ sortOrder == AddonModForumProvider.SORTORDER_LASTPOST_DESC) {
+
+ const params = {
+ forumid: forumId,
+ page: page,
+ perpage: AddonModForumProvider.DISCUSSIONS_PER_PAGE,
+ sortby: 'timemodified',
+ sortdirection: 'DESC'
+ };
+ const preSets: CoreSiteWSPreSets = {
+ cacheKey: this.getDiscussionsListCacheKey(forumId, sortOrder),
+ omitExpires: true
+ };
+
+ return site.read('mod_forum_get_forum_discussions_paginated', params, preSets);
+ }
+
+ return Promise.reject(error);
+ }).then((response) => {
if (response) {
this.storeUserData(response.discussions);
@@ -499,7 +604,8 @@ export class AddonModForumProvider {
* If a page fails, the discussions until that page will be returned along with a flag indicating an error occurred.
*
* @param {number} forumId Forum ID.
- * @param {boolean} forceCache True to always get the value from cache, false otherwise.
+ * @param {number} [sortOrder] Sort order.
+ * @param {boolean} [forceCache] True to always get the value from cache, false otherwise.
* @param {number} [numPages] Number of pages to get. If not defined, all pages.
* @param {number} [startPage] Page to start. If not defined, first page.
* @param {string} [siteId] Site ID. If not defined, current site.
@@ -507,8 +613,8 @@ export class AddonModForumProvider {
* - discussions: List of discussions.
* - error: True if an error occurred, false otherwise.
*/
- getDiscussionsInPages(forumId: number, forceCache?: boolean, numPages?: number, startPage?: number, siteId?: string)
- : Promise {
+ getDiscussionsInPages(forumId: number, sortOrder?: number, forceCache?: boolean, numPages?: number, startPage?: number,
+ siteId?: string): Promise {
if (typeof numPages == 'undefined') {
numPages = -1;
}
@@ -525,7 +631,7 @@ export class AddonModForumProvider {
const getPage = (page: number): Promise => {
// Get page discussions.
- return this.getDiscussions(forumId, page, forceCache, siteId).then((response) => {
+ return this.getDiscussions(forumId, sortOrder, page, forceCache, siteId).then((response) => {
result.discussions = result.discussions.concat(response.discussions);
numPages--;
@@ -569,22 +675,32 @@ export class AddonModForumProvider {
invalidateContent(moduleId: number, courseId: number): Promise {
// Get the forum first, we need the forum ID.
return this.getForum(courseId, moduleId).then((forum) => {
- // We need to get the list of discussions to be able to invalidate their posts.
- return this.getDiscussionsInPages(forum.id, true).then((response) => {
- // Now invalidate the WS calls.
- const promises = [];
+ const promises = [];
- promises.push(this.invalidateForumData(courseId));
- promises.push(this.invalidateDiscussionsList(forum.id));
- promises.push(this.invalidateCanAddDiscussion(forum.id));
- promises.push(this.invalidateAccessInformation(forum.id));
+ promises.push(this.invalidateForumData(courseId));
+ promises.push(this.invalidateDiscussionsList(forum.id));
+ promises.push(this.invalidateCanAddDiscussion(forum.id));
+ promises.push(this.invalidateAccessInformation(forum.id));
- response.discussions.forEach((discussion) => {
- promises.push(this.invalidateDiscussionPosts(discussion.discussion));
- });
+ this.getAvailableSortOrders().forEach((sortOrder) => {
+ // We need to get the list of discussions to be able to invalidate their posts.
+ promises.push(this.getDiscussionsInPages(forum.id, sortOrder.value, true).then((response) => {
+ // Now invalidate the WS calls.
+ const promises = [];
- return this.utils.allPromises(promises);
+ response.discussions.forEach((discussion) => {
+ promises.push(this.invalidateDiscussionPosts(discussion.discussion));
+ });
+
+ return this.utils.allPromises(promises);
+ }));
});
+
+ if (this.isDiscussionListSortingAvailable()) {
+ promises.push(this.userProvider.invalidateUserPreference(AddonModForumProvider.PREFERENCE_SORTORDER));
+ }
+
+ return this.utils.allPromises(promises);
});
}
@@ -623,7 +739,9 @@ export class AddonModForumProvider {
*/
invalidateDiscussionsList(forumId: number, siteId?: string): Promise {
return this.sitesProvider.getSite(siteId).then((site) => {
- return site.invalidateWsCacheForKey(this.getDiscussionsListCacheKey(forumId));
+ return this.utils.allPromises(this.getAvailableSortOrders().map((sortOrder) => {
+ return site.invalidateWsCacheForKey(this.getDiscussionsListCacheKey(forumId, sortOrder.value));
+ }));
});
}
diff --git a/src/addon/mod/forum/providers/helper.ts b/src/addon/mod/forum/providers/helper.ts
index 3e5928bde..5c568c911 100644
--- a/src/addon/mod/forum/providers/helper.ts
+++ b/src/addon/mod/forum/providers/helper.ts
@@ -162,7 +162,7 @@ export class AddonModForumHelperProvider {
siteId = siteId || this.sitesProvider.getCurrentSiteId();
const findDiscussion = (page: number): Promise => {
- return this.forumProvider.getDiscussions(forumId, page, false, siteId).then((response) => {
+ return this.forumProvider.getDiscussions(forumId, undefined, page, false, siteId).then((response) => {
if (response.discussions && response.discussions.length > 0) {
const discussion = response.discussions.find((discussion) => discussion.id == discussionId);
if (discussion) {
diff --git a/src/addon/mod/forum/providers/prefetch-handler.ts b/src/addon/mod/forum/providers/prefetch-handler.ts
index ec799c6b2..ab8461414 100644
--- a/src/addon/mod/forum/providers/prefetch-handler.ts
+++ b/src/addon/mod/forum/providers/prefetch-handler.ts
@@ -25,7 +25,7 @@ import { CoreGroupsProvider } from '@providers/groups';
import { CoreUserProvider } from '@core/user/providers/user';
import { AddonModForumProvider } from './forum';
import { AddonModForumSyncProvider } from './sync';
-import { CoreRatingProvider } from '@core/rating/providers/rating';
+import { CoreRatingProvider, CoreRatingInfo } from '@core/rating/providers/rating';
/**
* Handler to prefetch forums.
@@ -107,26 +107,36 @@ export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHand
* @return {Promise} Promise resolved with array of posts.
*/
protected getPostsForPrefetch(forum: any): Promise {
- // Get discussions in first 2 pages.
- return this.forumProvider.getDiscussionsInPages(forum.id, false, 2).then((response) => {
- if (response.error) {
- return Promise.reject(null);
- }
+ const posts = {};
+ const ratingInfos: CoreRatingInfo[] = [];
- const promises = [];
- let posts = [];
+ const promises = this.forumProvider.getAvailableSortOrders().map((sortOrder) => {
+ // Get discussions in first 2 pages.
+ return this.forumProvider.getDiscussionsInPages(forum.id, sortOrder.value, false, 2).then((response) => {
+ if (response.error) {
+ return Promise.reject(null);
+ }
- response.discussions.forEach((discussion) => {
- promises.push(this.forumProvider.getDiscussionPosts(discussion.discussion).then((response) => {
- posts = posts.concat(response.posts);
+ const promises = [];
- return this.ratingProvider.prefetchRatings('module', forum.cmid, forum.scale, forum.course,
- response.ratinginfo);
- }));
+ response.discussions.forEach((discussion) => {
+ promises.push(this.forumProvider.getDiscussionPosts(discussion.discussion).then((response) => {
+ response.posts.forEach((post) => {
+ posts[post.id] = post;
+ });
+ ratingInfos.push(response.ratinginfo);
+ }));
+ });
+
+ return Promise.all(promises);
});
+ });
- return Promise.all(promises).then(() => {
- return posts;
+ return Promise.all(promises).then(() => {
+ const ratingInfo = this.ratingProvider.mergeRatingInfos(ratingInfos);
+
+ return this.ratingProvider.prefetchRatings('module', forum.cmid, forum.scale, forum.course, ratingInfo).then(() => {
+ return this.utils.objectToArray(posts);
});
});
}
@@ -210,6 +220,11 @@ export class AddonModForumPrefetchHandler extends CoreCourseActivityPrefetchHand
// Prefetch access information.
promises.push(this.forumProvider.getAccessInformation(forum.id));
+ // Prefetch sort order preference.
+ if (this.forumProvider.isDiscussionListSortingAvailable()) {
+ promises.push(this.userProvider.getUserPreference(AddonModForumProvider.PREFERENCE_SORTORDER));
+ }
+
return Promise.all(promises);
});
}
diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json
index 7cbba2a50..83315fe76 100644
--- a/src/assets/lang/en.json
+++ b/src/assets/lang/en.json
@@ -483,6 +483,12 @@
"addon.mod_forum.addanewtopic": "Add a new topic",
"addon.mod_forum.addtofavourites": "Star this discussion",
"addon.mod_forum.advanced": "Advanced",
+ "addon.mod_forum.bycreatedasc": "By creation date in ascending order",
+ "addon.mod_forum.bycreateddesc": "By creation date in descending order",
+ "addon.mod_forum.bylastpostasc": "By last post in ascending order",
+ "addon.mod_forum.bylastpostdesc": "By last post in descending order",
+ "addon.mod_forum.byrepliesasc": "By number of replies in ascending order",
+ "addon.mod_forum.byrepliesdesc": "By number of replies in descending order",
"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.",
"addon.mod_forum.cannotcreatediscussion": "Could not create new discussion",
@@ -1734,6 +1740,7 @@
"core.sizemb": "MB",
"core.sizetb": "TB",
"core.sorry": "Sorry...",
+ "core.sort": "Sort",
"core.sortby": "Sort by",
"core.start": "Start",
"core.strftimedate": "%d %B %Y",
diff --git a/src/lang/en.json b/src/lang/en.json
index 0fb6bb5bd..64042e606 100644
--- a/src/lang/en.json
+++ b/src/lang/en.json
@@ -223,6 +223,7 @@
"sizemb": "MB",
"sizetb": "TB",
"sorry": "Sorry...",
+ "sort": "Sort",
"sortby": "Sort by",
"start": "Start",
"strftimedate": "%d %B %Y",