diff --git a/src/addon/mod/forum/components/post-options-menu/addon-forum-post-options-menu.html b/src/addon/mod/forum/components/post-options-menu/addon-forum-post-options-menu.html index 9b7e34dd6..d66529bc8 100644 --- a/src/addon/mod/forum/components/post-options-menu/addon-forum-post-options-menu.html +++ b/src/addon/mod/forum/components/post-options-menu/addon-forum-post-options-menu.html @@ -1,12 +1,12 @@ - +

{{ 'addon.mod_forum.edit' | translate }}

- + -

{{ 'addon.mod_forum.delete' | translate }}

-

{{ 'core.discard' | translate }}

+

{{ 'addon.mod_forum.delete' | translate }}

+

{{ 'core.discard' | translate }}

{{ 'core.numwords' | translate: {'$a': wordCount} }}

diff --git a/src/addon/mod/forum/components/post-options-menu/post-options-menu.ts b/src/addon/mod/forum/components/post-options-menu/post-options-menu.ts index 7ddaf862f..8b9f2c69c 100644 --- a/src/addon/mod/forum/components/post-options-menu/post-options-menu.ts +++ b/src/addon/mod/forum/components/post-options-menu/post-options-menu.ts @@ -12,12 +12,14 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit, NgZone } from '@angular/core'; import { NavParams, ViewController } from 'ionic-angular'; import { CoreDomUtilsProvider } from '@providers/utils/dom'; import { CoreSitesProvider, CoreSitesReadingStrategy } from '@providers/sites'; import { CoreSite } from '@classes/site'; import { AddonModForumProvider } from '../../providers/forum'; +import { CoreApp } from '@providers/app'; +import { Network } from '@ionic-native/network'; /** * This component is meant to display a popover with the post options. @@ -34,10 +36,15 @@ export class AddonForumPostOptionsMenuComponent implements OnInit { canDelete = false; loaded = false; url: string; + isOnline: boolean; + offlinePost: boolean; protected cmId: number; + protected onlineObserver: any; constructor(navParams: NavParams, + network: Network, + zone: NgZone, protected viewCtrl: ViewController, protected domUtils: CoreDomUtilsProvider, protected forumProvider: AddonModForumProvider, @@ -45,20 +52,28 @@ export class AddonForumPostOptionsMenuComponent implements OnInit { this.post = navParams.get('post'); this.forumId = navParams.get('forumId'); this.cmId = navParams.get('cmId'); + + this.isOnline = CoreApp.instance.isOnline(); + this.onlineObserver = network.onchange().subscribe(() => { + // Execute the callback in the Angular zone, so change detection doesn't stop working. + zone.run(() => { + this.isOnline = CoreApp.instance.isOnline(); + }); + }); } /** * Component being initialized. */ async ngOnInit(): Promise { - if (this.post.id) { + if (this.post.id > 0) { const site: CoreSite = this.sitesProvider.getCurrentSite(); this.url = site.createSiteUrl('/mod/forum/discuss.php', {d: this.post.discussionid}, 'p' + this.post.id); + this.offlinePost = false; } else { // Offline post, you can edit or discard the post. - this.canEdit = true; - this.canDelete = true; this.loaded = true; + this.offlinePost = true; return; } @@ -98,7 +113,7 @@ export class AddonForumPostOptionsMenuComponent implements OnInit { * Delete a post. */ deletePost(): void { - if (this.post.id) { + if (!this.offlinePost) { this.viewCtrl.dismiss({action: 'delete'}); } else { this.viewCtrl.dismiss({action: 'deleteoffline'}); @@ -109,10 +124,17 @@ export class AddonForumPostOptionsMenuComponent implements OnInit { * Edit a post. */ editPost(): void { - if (this.post.id) { + if (!this.offlinePost) { this.viewCtrl.dismiss({action: 'edit'}); } else { this.viewCtrl.dismiss({action: 'editoffline'}); } } + + /** + * Component destroyed. + */ + ngOnDestroy(): void { + this.onlineObserver && this.onlineObserver.unsubscribe(); + } } 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 c1a08da81..6a620c98e 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 @@ -50,14 +50,14 @@ - + -
+ {{ 'addon.mod_forum.subject' | translate }} diff --git a/src/addon/mod/forum/components/post/post.ts b/src/addon/mod/forum/components/post/post.ts index 48d0fc8e4..f9402ece9 100644 --- a/src/addon/mod/forum/components/post/post.ts +++ b/src/addon/mod/forum/components/post/post.ts @@ -93,7 +93,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges * Component being initialized. */ ngOnInit(): void { - this.uniqueId = this.post.id ? 'reply' + this.post.id : 'edit' + this.post.parentid; + this.uniqueId = this.post.id > 0 ? 'reply' + this.post.id : 'edit' + this.post.parentid; const reTranslated = this.translate.instant('addon.mod_forum.re'); this.displaySubject = !this.parentSubject || @@ -102,7 +102,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges this.defaultReplySubject = this.post.replysubject || ((this.post.subject.startsWith('Re: ') || this.post.subject.startsWith(reTranslated)) ? this.post.subject : `${reTranslated} ${this.post.subject}`); - this.optionsMenuEnabled = !this.post.id || (this.forumProvider.isGetDiscussionPostAvailable() && + this.optionsMenuEnabled = this.post.id < 0 || (this.forumProvider.isGetDiscussionPostAvailable() && (this.forumProvider.isDeletePostAvailable() || this.forumProvider.isUpdatePostAvailable())); } diff --git a/src/addon/mod/forum/pages/discussion/discussion.ts b/src/addon/mod/forum/pages/discussion/discussion.ts index cee6fa087..14d83c207 100644 --- a/src/addon/mod/forum/pages/discussion/discussion.ts +++ b/src/addon/mod/forum/pages/discussion/discussion.ts @@ -360,7 +360,7 @@ export class AddonModForumDiscussionPage implements OnDestroy { 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; + posts[reply.parentid].capabilities.reply = false; })); }); diff --git a/src/addon/mod/forum/providers/forum.ts b/src/addon/mod/forum/providers/forum.ts index cdb8b6b5b..4118db0f1 100644 --- a/src/addon/mod/forum/providers/forum.ts +++ b/src/addon/mod/forum/providers/forum.ts @@ -589,8 +589,13 @@ export class AddonModForumProvider { sortDiscussionPosts(posts: any[], direction: string): void { // @todo: Check children when sorting. posts.sort((a, b) => { - a = parseInt(a.created, 10); - b = parseInt(b.created, 10); + a = parseInt(a.timecreated, 10) || 0; + b = parseInt(b.timecreated, 10) || 0; + if (a == 0 || b == 0) { + // Leave 0 at the end. + return b - a; + } + if (direction == 'ASC') { return a - b; } else { diff --git a/src/addon/mod/forum/providers/helper.ts b/src/addon/mod/forum/providers/helper.ts index a3d72dccd..63aa04019 100644 --- a/src/addon/mod/forum/providers/helper.ts +++ b/src/addon/mod/forum/providers/helper.ts @@ -161,24 +161,23 @@ export class AddonModForumHelperProvider { */ convertOfflineReplyToOnline(offlineReply: any, siteId?: string): Promise { const reply: any = { - attachments: [], - canreply: false, - children: [], - created: offlineReply.timecreated, - discussion: offlineReply.discussionid, - id: false, - mailed: 0, - mailnow: 0, - message: offlineReply.message, - messageformat: 1, - messagetrust: 0, - modified: false, - parent: offlineReply.postid, - postread: false, + id: -offlineReply.timecreated, + discussionid: offlineReply.discussionid, + parentid: offlineReply.postid, + hasparent: !!offlineReply.postid, + author: { + id: offlineReply.userid, + }, + timecreated: false, subject: offlineReply.subject, - totalscore: 0, - userid: offlineReply.userid, - isprivatereply: offlineReply.options && offlineReply.options.private + message: offlineReply.message, + attachments: [], + capabilities: { + reply: false, + }, + unread: false, + isprivatereply: offlineReply.options && offlineReply.options.private, + tags: null }, promises = []; @@ -187,7 +186,7 @@ export class AddonModForumHelperProvider { reply.attachments = offlineReply.options.attachmentsid.online || []; if (offlineReply.options.attachmentsid.offline) { - promises.push(this.getReplyStoredFiles(offlineReply.forumid, reply.parent, siteId, reply.userid) + promises.push(this.getReplyStoredFiles(offlineReply.forumid, reply.parentid, siteId, offlineReply.userid) .then((files) => { reply.attachments = reply.attachments.concat(files); })); @@ -196,8 +195,8 @@ export class AddonModForumHelperProvider { // Get user data. promises.push(this.userProvider.getProfile(offlineReply.userid, offlineReply.courseid, true).then((user) => { - reply.userfullname = user.fullname; - reply.userpictureurl = user.profileimageurl; + reply.author.fullname = user.fullname; + reply.author.urls = { profileimage: user.profileimageurl }; }).catch(() => { // Ignore errors. })); diff --git a/src/providers/utils/utils.ts b/src/providers/utils/utils.ts index 8b87c1b93..f1a582a11 100644 --- a/src/providers/utils/utils.ts +++ b/src/providers/utils/utils.ts @@ -581,6 +581,10 @@ export class CoreUtilsProvider { parent = node[parentFieldName]; node.children = []; + if (!id || !parent) { + this.logger.error(`Node with incorrect ${idFieldName}:${id} or ${parentFieldName}:${parent} found on formatTree`); + } + // Use map to look-up the parents. map[id] = index; if (parent != rootParentId) { @@ -597,12 +601,16 @@ export class CoreUtilsProvider { mapDepth[id] = mapDepth[parent]; // Change the parent to be the one that is two levels up the hierarchy. node.parent = parentOfParent; + } else { + this.logger.error(`Node parent of parent:${parentOfParent} not found on formatTree`); } } else { parentNode.children.push(node); // Increase the depth level. mapDepth[id] = mapDepth[parent] + 1; } + } else { + this.logger.error(`Node parent:${parent} not found on formatTree`); } } else { tree.push(node);