MOBILE-2267 forum: Edit forum post
parent
f1a86b2a36
commit
470abc056b
|
@ -389,7 +389,6 @@
|
||||||
"addon.mod_assign.numwords": "moodle",
|
"addon.mod_assign.numwords": "moodle",
|
||||||
"addon.mod_assign.outof": "assign",
|
"addon.mod_assign.outof": "assign",
|
||||||
"addon.mod_assign.overdue": "assign",
|
"addon.mod_assign.overdue": "assign",
|
||||||
"addon.mod_assign.savechanges": "assign",
|
|
||||||
"addon.mod_assign.submission": "assign",
|
"addon.mod_assign.submission": "assign",
|
||||||
"addon.mod_assign.submissioneditable": "assign",
|
"addon.mod_assign.submissioneditable": "assign",
|
||||||
"addon.mod_assign.submissionnoteditable": "assign",
|
"addon.mod_assign.submissionnoteditable": "assign",
|
||||||
|
@ -572,6 +571,7 @@
|
||||||
"addon.mod_forum.cannotadddiscussionall": "forum",
|
"addon.mod_forum.cannotadddiscussionall": "forum",
|
||||||
"addon.mod_forum.cannotcreatediscussion": "forum",
|
"addon.mod_forum.cannotcreatediscussion": "forum",
|
||||||
"addon.mod_forum.couldnotadd": "forum",
|
"addon.mod_forum.couldnotadd": "forum",
|
||||||
|
"addon.mod_forum.couldnotupdate": "forum",
|
||||||
"addon.mod_forum.cutoffdatereached": "forum",
|
"addon.mod_forum.cutoffdatereached": "forum",
|
||||||
"addon.mod_forum.delete": "forum",
|
"addon.mod_forum.delete": "forum",
|
||||||
"addon.mod_forum.deletedpost": "forum",
|
"addon.mod_forum.deletedpost": "forum",
|
||||||
|
@ -625,6 +625,7 @@
|
||||||
"addon.mod_forum.unpindiscussion": "forum",
|
"addon.mod_forum.unpindiscussion": "forum",
|
||||||
"addon.mod_forum.unread": "forum",
|
"addon.mod_forum.unread": "forum",
|
||||||
"addon.mod_forum.unreadpostsnumber": "forum",
|
"addon.mod_forum.unreadpostsnumber": "forum",
|
||||||
|
"addon.mod_forum.yourreply": "forum",
|
||||||
"addon.mod_glossary.addentry": "glossary",
|
"addon.mod_glossary.addentry": "glossary",
|
||||||
"addon.mod_glossary.aliases": "glossary",
|
"addon.mod_glossary.aliases": "glossary",
|
||||||
"addon.mod_glossary.attachment": "glossary",
|
"addon.mod_glossary.attachment": "glossary",
|
||||||
|
@ -1792,6 +1793,7 @@
|
||||||
"core.restricted": "moodle",
|
"core.restricted": "moodle",
|
||||||
"core.retry": "local_moodlemobileapp",
|
"core.retry": "local_moodlemobileapp",
|
||||||
"core.save": "moodle",
|
"core.save": "moodle",
|
||||||
|
"core.savechanges": "assign",
|
||||||
"core.search": "moodle",
|
"core.search": "moodle",
|
||||||
"core.searching": "local_moodlemobileapp",
|
"core.searching": "local_moodlemobileapp",
|
||||||
"core.searchresults": "moodle",
|
"core.searchresults": "moodle",
|
||||||
|
|
|
@ -71,7 +71,6 @@
|
||||||
"numwords": "{{$a}} words",
|
"numwords": "{{$a}} words",
|
||||||
"outof": "{{$a.current}} out of {{$a.total}}",
|
"outof": "{{$a.current}} out of {{$a.total}}",
|
||||||
"overdue": "<font color=\"red\">Assignment is overdue by: {{$a}}</font>",
|
"overdue": "<font color=\"red\">Assignment is overdue by: {{$a}}</font>",
|
||||||
"savechanges": "Save changes",
|
|
||||||
"submissioneditable": "Student can edit this submission",
|
"submissioneditable": "Student can edit this submission",
|
||||||
"submissionnoteditable": "Student cannot edit this submission",
|
"submissionnoteditable": "Student cannot edit this submission",
|
||||||
"submissionnotsupported": "This submission is not supported by the app and may not contain all the information.",
|
"submissionnotsupported": "This submission is not supported by the app and may not contain all the information.",
|
||||||
|
|
|
@ -51,10 +51,12 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="addon-mod-forum-discussion-info">
|
<div class="addon-mod-forum-discussion-info">
|
||||||
<ion-avatar core-user-avatar [user]="discussion" item-start [courseId]="courseId" *ngIf="discussion.userfullname"></ion-avatar>
|
<ion-avatar core-user-avatar [user]="discussion" item-start [courseId]="courseId" *ngIf="discussion.userfullname"></ion-avatar>
|
||||||
|
<div class="addon-mod-forum-discussion-author">
|
||||||
<h3 *ngIf="discussion.userfullname">{{discussion.userfullname}}</h3>
|
<h3 *ngIf="discussion.userfullname">{{discussion.userfullname}}</h3>
|
||||||
<p *ngIf="discussion.groupname"><ion-icon name="people"></ion-icon> {{ discussion.groupname }}</p>
|
<p *ngIf="discussion.groupname"><ion-icon name="people"></ion-icon> {{ discussion.groupname }}</p>
|
||||||
<p><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</p>
|
<p><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
<ng-container *ngFor="let discussion of discussions">
|
<ng-container *ngFor="let discussion of discussions">
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
addon-forum-post-options-menu {
|
||||||
|
core-loading:not(.core-loading-loaded) > .core-loading-container {
|
||||||
|
position: relative !important;
|
||||||
|
padding-top: 10px !important;
|
||||||
|
padding-bottom: 10px !important;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
core-loading > .core-loading-container .core-loading-message {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
|
@ -46,9 +46,9 @@ export class AddonForumPostOptionsMenuComponent implements OnInit {
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
if (this.forumId) {
|
if (this.forumId) {
|
||||||
if (this.post.id) {
|
if (this.post.id) {
|
||||||
this.forumProvider.getDiscussionPost(this.forumId, this.post.discussion, this.post.id).then((post) => {
|
this.forumProvider.getDiscussionPost(this.forumId, this.post.discussion, this.post.id, true).then((post) => {
|
||||||
this.canDelete = post.capabilities.delete && this.forumProvider.isDeletePostAvailable();
|
this.canDelete = post.capabilities.delete && this.forumProvider.isDeletePostAvailable();
|
||||||
this.canEdit = false;
|
this.canEdit = post.capabilities.edit && this.forumProvider.isUpdatePostAvailable();
|
||||||
this.wordCount = post.wordcount;
|
this.wordCount = post.wordcount;
|
||||||
}).catch((error) => {
|
}).catch((error) => {
|
||||||
this.domUtils.showErrorModalDefault(error, 'Error getting discussion post.');
|
this.domUtils.showErrorModalDefault(error, 'Error getting discussion post.');
|
||||||
|
|
|
@ -7,6 +7,9 @@
|
||||||
<core-icon name="fa-star" class="addon-forum-star" *ngIf="post.parent == 0 && !post.pinned && post.starred"></core-icon>
|
<core-icon name="fa-star" class="addon-forum-star" *ngIf="post.parent == 0 && !post.pinned && post.starred"></core-icon>
|
||||||
<core-format-text [text]="post.subject" contextLevel="module" [contextInstanceId]="forum && forum.cmid" [courseId]="courseId"></core-format-text>
|
<core-format-text [text]="post.subject" contextLevel="module" [contextInstanceId]="forum && forum.cmid" [courseId]="courseId"></core-format-text>
|
||||||
</h2>
|
</h2>
|
||||||
|
<ion-note float-end padding-left text-end *ngIf="trackPosts && !post.postread" [attr.aria-label]="'addon.mod_forum.unread' | translate">
|
||||||
|
<core-icon name="fa-circle" color="primary"></core-icon>
|
||||||
|
</ion-note>
|
||||||
<button ion-button icon-only clear color="dark" (click)="showOptionsMenu($event)" *ngIf="optionsMenuEnabled">
|
<button ion-button icon-only clear color="dark" (click)="showOptionsMenu($event)" *ngIf="optionsMenuEnabled">
|
||||||
<core-icon name="more"></core-icon>
|
<core-icon name="more"></core-icon>
|
||||||
</button>
|
</button>
|
||||||
|
@ -19,12 +22,14 @@
|
||||||
<p *ngIf="post.modified">{{post.modified * 1000 | coreFormatDate: "strftimerecentfull"}}</p>
|
<p *ngIf="post.modified">{{post.modified * 1000 | coreFormatDate: "strftimerecentfull"}}</p>
|
||||||
<p *ngIf="!post.modified"><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</p>
|
<p *ngIf="!post.modified"><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
<ng-container *ngIf="!displaySubject">
|
||||||
<ion-note float-end padding-left text-end *ngIf="trackPosts && !post.postread" [attr.aria-label]="'addon.mod_forum.unread' | translate">
|
<ion-note float-end padding-left text-end *ngIf="trackPosts && !post.postread" [attr.aria-label]="'addon.mod_forum.unread' | translate">
|
||||||
<core-icon name="fa-circle" color="primary"></core-icon>
|
<core-icon name="fa-circle" color="primary"></core-icon>
|
||||||
</ion-note>
|
</ion-note>
|
||||||
<button ion-button icon-only clear color="dark" (click)="showOptionsMenu($event)" *ngIf="!displaySubject && optionsMenuEnabled">
|
<button ion-button icon-only clear color="dark" (click)="showOptionsMenu($event)" *ngIf="optionsMenuEnabled">
|
||||||
<core-icon name="more"></core-icon>
|
<core-icon name="more"></core-icon>
|
||||||
</button>
|
</button>
|
||||||
|
</ng-container>
|
||||||
</div>
|
</div>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ion-card-header>
|
</ion-card-header>
|
||||||
|
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
import { Component, Input, Output, Optional, EventEmitter, OnInit, OnDestroy } from '@angular/core';
|
import { Component, Input, Output, Optional, EventEmitter, OnInit, OnDestroy } from '@angular/core';
|
||||||
import { FormControl } from '@angular/forms';
|
import { FormControl } from '@angular/forms';
|
||||||
import { Content, PopoverController } from 'ionic-angular';
|
import { Content, PopoverController, ModalController } from 'ionic-angular';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader';
|
import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader';
|
||||||
import { CoreSyncProvider } from '@providers/sync';
|
import { CoreSyncProvider } from '@providers/sync';
|
||||||
|
@ -75,6 +75,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy {
|
||||||
private tagProvider: CoreTagProvider,
|
private tagProvider: CoreTagProvider,
|
||||||
@Optional() private content: Content,
|
@Optional() private content: Content,
|
||||||
protected popoverCtrl: PopoverController,
|
protected popoverCtrl: PopoverController,
|
||||||
|
protected modalCtrl: ModalController,
|
||||||
protected eventsProvider: CoreEventsProvider,
|
protected eventsProvider: CoreEventsProvider,
|
||||||
protected sitesProvider: CoreSitesProvider) {
|
protected sitesProvider: CoreSitesProvider) {
|
||||||
this.onPostChange = new EventEmitter<void>();
|
this.onPostChange = new EventEmitter<void>();
|
||||||
|
@ -93,7 +94,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy {
|
||||||
this.post.subject != reTranslated + this.defaultSubject);
|
this.post.subject != reTranslated + this.defaultSubject);
|
||||||
|
|
||||||
this.optionsMenuEnabled = !this.post.id || (this.forumProvider.isGetDiscussionPostAvailable() &&
|
this.optionsMenuEnabled = !this.post.id || (this.forumProvider.isGetDiscussionPostAvailable() &&
|
||||||
(this.forumProvider.isDeletePostAvailable()));
|
(this.forumProvider.isDeletePostAvailable() || this.forumProvider.isUpdatePostAvailable()));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -179,7 +180,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy {
|
||||||
if (data && data.action) {
|
if (data && data.action) {
|
||||||
switch (data.action) {
|
switch (data.action) {
|
||||||
case 'edit':
|
case 'edit':
|
||||||
// Not implemented.
|
this.editPost();
|
||||||
break;
|
break;
|
||||||
case 'editoffline':
|
case 'editoffline':
|
||||||
this.editOfflineReply();
|
this.editOfflineReply();
|
||||||
|
@ -200,6 +201,61 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shows a form modal to edit an online post.
|
||||||
|
*/
|
||||||
|
editPost(): void {
|
||||||
|
const modal = this.modalCtrl.create('AddonModForumEditPostPage', {
|
||||||
|
post: this.post,
|
||||||
|
component: this.component,
|
||||||
|
componentId: this.componentId,
|
||||||
|
forum: this.forum
|
||||||
|
});
|
||||||
|
|
||||||
|
modal.present();
|
||||||
|
modal.onDidDismiss((data) => {
|
||||||
|
if (typeof data != 'undefined') {
|
||||||
|
// Add some HTML to the message if needed.
|
||||||
|
const message = this.textUtils.formatHtmlLines(data.message);
|
||||||
|
const files = data.files || [];
|
||||||
|
const sendingModal = this.domUtils.showModalLoading('core.sending', true);
|
||||||
|
let promise;
|
||||||
|
|
||||||
|
// Upload attachments first if any.
|
||||||
|
if (files.length) {
|
||||||
|
promise = this.forumHelper.uploadOrStoreReplyFiles(this.forum.id, this.post.id, files, false);
|
||||||
|
} else {
|
||||||
|
promise = Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
promise.then((attach) => {
|
||||||
|
const options: any = {};
|
||||||
|
|
||||||
|
if (attach) {
|
||||||
|
options.attachmentsid = attach;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Try to send it to server.
|
||||||
|
return this.forumProvider.updatePost(this.post.id, data.subject, message, options);
|
||||||
|
}).then((sent) => {
|
||||||
|
if (sent && this.forum.id) {
|
||||||
|
// Data sent to server, delete stored files (if any).
|
||||||
|
this.forumHelper.deleteReplyStoredFiles(this.forum.id, this.post.id);
|
||||||
|
|
||||||
|
this.onPostChange.emit();
|
||||||
|
this.post.subject = data.subject;
|
||||||
|
this.post.message = message;
|
||||||
|
this.post.attachments = data.files;
|
||||||
|
}
|
||||||
|
}).catch((message) => {
|
||||||
|
this.domUtils.showErrorModalDefault(message, 'addon.mod_forum.couldnotupdate', true);
|
||||||
|
}).finally(() => {
|
||||||
|
sendingModal.dismiss();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set this post as being replied to.
|
* Set this post as being replied to.
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
"cannotadddiscussionall": "You do not have permission to add a new discussion topic for all participants.",
|
"cannotadddiscussionall": "You do not have permission to add a new discussion topic for all participants.",
|
||||||
"cannotcreatediscussion": "Could not create new discussion",
|
"cannotcreatediscussion": "Could not create new discussion",
|
||||||
"couldnotadd": "Could not add your post due to an unknown error",
|
"couldnotadd": "Could not add your post due to an unknown error",
|
||||||
|
"couldnotupdate": "Could not update 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.",
|
"cutoffdatereached": "The cut-off date for posting to this forum is reached so you can no longer post to it.",
|
||||||
"delete": "Delete",
|
"delete": "Delete",
|
||||||
"deletedpost": "The post has been deleted",
|
"deletedpost": "The post has been deleted",
|
||||||
|
@ -60,5 +61,6 @@
|
||||||
"unlockdiscussion": "Unlock this discussion",
|
"unlockdiscussion": "Unlock this discussion",
|
||||||
"unpindiscussion": "Unpin this discussion",
|
"unpindiscussion": "Unpin this discussion",
|
||||||
"unread": "Unread",
|
"unread": "Unread",
|
||||||
"unreadpostsnumber": "{{$a}} unread posts"
|
"unreadpostsnumber": "{{$a}} unread posts",
|
||||||
|
"yourreply": "Your reply"
|
||||||
}
|
}
|
|
@ -0,0 +1,40 @@
|
||||||
|
<ion-header>
|
||||||
|
<ion-navbar core-back-button>
|
||||||
|
<ion-title>{{ 'addon.mod_forum.yourreply' | translate }}</ion-title>
|
||||||
|
<ion-buttons end>
|
||||||
|
<button ion-button icon-only (click)="closeModal()" [attr.aria-label]="'core.close' | translate">
|
||||||
|
<ion-icon name="close"></ion-icon>
|
||||||
|
</button>
|
||||||
|
</ion-buttons>
|
||||||
|
</ion-navbar>
|
||||||
|
</ion-header>
|
||||||
|
<ion-content>
|
||||||
|
<ion-list>
|
||||||
|
<ion-item>
|
||||||
|
<ion-label stacked>{{ 'addon.mod_forum.subject' | translate }}</ion-label>
|
||||||
|
<ion-input type="text" [placeholder]="'addon.mod_forum.subject' | translate" [(ngModel)]="replyData.subject"></ion-input>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item>
|
||||||
|
<ion-label stacked>{{ 'addon.mod_forum.message' | translate }}</ion-label>
|
||||||
|
<core-rich-text-editor item-content [control]="messageControl" (contentChanged)="onMessageChange($event)" [placeholder]="'addon.mod_forum.replyplaceholder' | translate" [name]="'mod_forum_reply_' + replyData.id" [component]="component" [componentId]="componentId"></core-rich-text-editor>
|
||||||
|
</ion-item>
|
||||||
|
<ion-item-divider text-wrap (click)="toggleAdvanced()" class="core-expandable">
|
||||||
|
<core-icon *ngIf="!advanced" name="fa-caret-right" item-start></core-icon>
|
||||||
|
<core-icon *ngIf="advanced" name="fa-caret-down" item-start></core-icon>
|
||||||
|
{{ 'addon.mod_forum.advanced' | translate }}
|
||||||
|
</ion-item-divider>
|
||||||
|
<ng-container *ngIf="advanced">
|
||||||
|
<core-attachments *ngIf="forum.id && forum.maxattachments > 0" [files]="replyData.files" [maxSize]="forum.maxbytes" [maxSubmissions]="forum.maxattachments" [component]="component" [componentId]="forum.cmid" [allowOffline]="true"></core-attachments>
|
||||||
|
</ng-container>
|
||||||
|
<ion-grid>
|
||||||
|
<ion-row>
|
||||||
|
<ion-col>
|
||||||
|
<button ion-button block (click)="reply($event)" [disabled]="replyData.subject == '' || replyData.message == null">{{ 'core.savechanges' | translate }}</button>
|
||||||
|
</ion-col>
|
||||||
|
<ion-col>
|
||||||
|
<button ion-button block color="light" (click)="closeModal()">{{ 'core.cancel' | translate }}</button>
|
||||||
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
</ion-grid>
|
||||||
|
</ion-list>
|
||||||
|
</ion-content>
|
|
@ -0,0 +1,35 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// 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 { AddonModForumComponentsModule } from '../../components/components.module';
|
||||||
|
import { AddonModForumEditPostPage } from './edit-post';
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
declarations: [
|
||||||
|
AddonModForumEditPostPage,
|
||||||
|
],
|
||||||
|
imports: [
|
||||||
|
CoreComponentsModule,
|
||||||
|
CoreDirectivesModule,
|
||||||
|
AddonModForumComponentsModule,
|
||||||
|
IonicPageModule.forChild(AddonModForumEditPostPage),
|
||||||
|
TranslateModule.forChild()
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AddonModForumEditPostPageModule {}
|
|
@ -0,0 +1,141 @@
|
||||||
|
// (C) Copyright 2015 Moodle Pty Ltd.
|
||||||
|
//
|
||||||
|
// 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 { FormControl } from '@angular/forms';
|
||||||
|
import { IonicPage, ViewController, NavParams } from 'ionic-angular';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader';
|
||||||
|
import { CoreDomUtilsProvider } from '@providers/utils/dom';
|
||||||
|
import { AddonModForumProvider } from '../../providers/forum';
|
||||||
|
import { AddonModForumHelperProvider } from '../../providers/helper';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page that displays a form to edit discussion post.
|
||||||
|
*/
|
||||||
|
@IonicPage({ segment: 'addon-mod-edit-post' })
|
||||||
|
@Component({
|
||||||
|
selector: 'addon-mod-forum-edit-post',
|
||||||
|
templateUrl: 'addon-mod-forum-edit-post.html',
|
||||||
|
})
|
||||||
|
export class AddonModForumEditPostPage {
|
||||||
|
component: string; // Component this post belong to.
|
||||||
|
componentId: number; // Component ID.
|
||||||
|
forum: any; // The forum the post belongs to. Required for attachments and offline posts.
|
||||||
|
|
||||||
|
messageControl = new FormControl();
|
||||||
|
advanced = false; // Display all form fields.
|
||||||
|
replyData: any = {};
|
||||||
|
originalData: any = {}; // Object with the original post data. Usually shared between posts.
|
||||||
|
|
||||||
|
protected forceLeave = false; // To allow leaving the page without checking for changes.
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
params: NavParams,
|
||||||
|
protected forumProvider: AddonModForumProvider,
|
||||||
|
protected viewCtrl: ViewController,
|
||||||
|
protected domUtils: CoreDomUtilsProvider,
|
||||||
|
protected uploaderProvider: CoreFileUploaderProvider,
|
||||||
|
protected forumHelper: AddonModForumHelperProvider,
|
||||||
|
protected translate: TranslateService) {
|
||||||
|
|
||||||
|
const post = params.get('post');
|
||||||
|
this.component = params.get('component');
|
||||||
|
this.componentId = params.get('componentId');
|
||||||
|
this.forum = params.get('forum');
|
||||||
|
|
||||||
|
this.replyData.id = post.id;
|
||||||
|
this.replyData.subject = post.subject;
|
||||||
|
this.replyData.message = post.message;
|
||||||
|
this.replyData.files = post.attachments || [];
|
||||||
|
|
||||||
|
// Delete the local files from the tmp folder if any.
|
||||||
|
this.uploaderProvider.clearTmpFiles(this.replyData.files);
|
||||||
|
|
||||||
|
// Update rich text editor.
|
||||||
|
this.messageControl.setValue(this.replyData.message);
|
||||||
|
|
||||||
|
// Update original data.
|
||||||
|
this.originalData.subject = this.replyData.subject;
|
||||||
|
this.originalData.message = this.replyData.message;
|
||||||
|
this.originalData.files = this.replyData.files.slice();
|
||||||
|
|
||||||
|
// Show advanced fields if any of them has not the default value.
|
||||||
|
this.advanced = this.replyData.files.length > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if we can leave the page or not.
|
||||||
|
*
|
||||||
|
* @return Resolved if we can leave it, rejected if not.
|
||||||
|
*/
|
||||||
|
ionViewCanLeave(): boolean | Promise<void> {
|
||||||
|
if (this.forceLeave) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
let promise: any;
|
||||||
|
|
||||||
|
if (this.forumHelper.hasPostDataChanged(this.replyData, this.originalData)) {
|
||||||
|
// Show confirmation if some data has been modified.
|
||||||
|
promise = this.domUtils.showConfirm(this.translate.instant('core.confirmcanceledit'));
|
||||||
|
} else {
|
||||||
|
promise = Promise.resolve();
|
||||||
|
}
|
||||||
|
|
||||||
|
return promise.then(() => {
|
||||||
|
// Delete the local files from the tmp folder.
|
||||||
|
this.uploaderProvider.clearTmpFiles(this.replyData.files);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Message changed.
|
||||||
|
*
|
||||||
|
* @param text The new text.
|
||||||
|
*/
|
||||||
|
onMessageChange(text: string): void {
|
||||||
|
this.replyData.message = text;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Close modal.
|
||||||
|
*
|
||||||
|
* @param data Data to return to the page.
|
||||||
|
*/
|
||||||
|
closeModal(data: any): void {
|
||||||
|
this.viewCtrl.dismiss(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reply to this post.
|
||||||
|
*
|
||||||
|
* @param e Click event.
|
||||||
|
*/
|
||||||
|
reply(e: Event): void {
|
||||||
|
e.preventDefault();
|
||||||
|
e.stopPropagation();
|
||||||
|
|
||||||
|
// Close the modal, sending the input data.
|
||||||
|
this.forceLeave = true;
|
||||||
|
this.closeModal(this.replyData);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show or hide advanced form fields.
|
||||||
|
*/
|
||||||
|
toggleAdvanced(): void {
|
||||||
|
this.advanced = !this.advanced;
|
||||||
|
}
|
||||||
|
}
|
|
@ -317,6 +317,16 @@ export class AddonModForumProvider {
|
||||||
return this.sitesProvider.wsAvailableInCurrentSite('mod_forum_delete_post');
|
return this.sitesProvider.wsAvailableInCurrentSite('mod_forum_delete_post');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether or not updatePost WS available or not.
|
||||||
|
*
|
||||||
|
* @return If WS is avalaible.
|
||||||
|
* @since 3.8
|
||||||
|
*/
|
||||||
|
isUpdatePostAvailable(): boolean {
|
||||||
|
return this.sitesProvider.wsAvailableInCurrentSite('mod_forum_update_discussion_post');
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Format discussions, setting groupname if the discussion group is valid.
|
* Format discussions, setting groupname if the discussion group is valid.
|
||||||
*
|
*
|
||||||
|
@ -385,19 +395,25 @@ export class AddonModForumProvider {
|
||||||
* @param forumId Forum ID.
|
* @param forumId Forum ID.
|
||||||
* @param discussionId Discussion ID.
|
* @param discussionId Discussion ID.
|
||||||
* @param postId Post ID.
|
* @param postId Post ID.
|
||||||
|
* @param ignoreCache True if it should ignore cached data (it will always fail in offline or server down).
|
||||||
* @param siteId Site ID. If not defined, current site.
|
* @param siteId Site ID. If not defined, current site.
|
||||||
* @return Promise resolved when the post is retrieved.
|
* @return Promise resolved when the post is retrieved.
|
||||||
*/
|
*/
|
||||||
getDiscussionPost(forumId: number, discussionId: number, postId: number, siteId?: string): Promise<any> {
|
getDiscussionPost(forumId: number, discussionId: number, postId: number, ignoreCache?: boolean, siteId?: string): Promise<any> {
|
||||||
return this.sitesProvider.getSite(siteId).then((site) => {
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
const params = {
|
const params = {
|
||||||
postid: postId
|
postid: postId
|
||||||
};
|
},
|
||||||
const preSets = {
|
preSets: CoreSiteWSPreSets = {
|
||||||
cacheKey: this.getDiscussionPostDataCacheKey(forumId, discussionId, postId),
|
cacheKey: this.getDiscussionPostDataCacheKey(forumId, discussionId, postId),
|
||||||
updateFrequency: CoreSite.FREQUENCY_RARELY
|
updateFrequency: CoreSite.FREQUENCY_USUALLY
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (ignoreCache) {
|
||||||
|
preSets.getFromCache = false;
|
||||||
|
preSets.emergencyCache = false;
|
||||||
|
}
|
||||||
|
|
||||||
return site.read('mod_forum_get_discussion_post', params, preSets).then((response) => {
|
return site.read('mod_forum_get_discussion_post', params, preSets).then((response) => {
|
||||||
if (response.post) {
|
if (response.post) {
|
||||||
return response.post;
|
return response.post;
|
||||||
|
@ -1050,4 +1066,29 @@ export class AddonModForumProvider {
|
||||||
|
|
||||||
this.userProvider.storeUsers(this.utils.objectToArray(users));
|
this.userProvider.storeUsers(this.utils.objectToArray(users));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update a certain post.
|
||||||
|
*
|
||||||
|
* @param postId ID of the post being edited.
|
||||||
|
* @param subject New post's subject.
|
||||||
|
* @param message New post's message.
|
||||||
|
* @param options Options (subscribe, attachments, ...).
|
||||||
|
* @param siteId Site ID. If not defined, current site.
|
||||||
|
* @return Promise resolved with success boolean when done.
|
||||||
|
*/
|
||||||
|
updatePost(postId: number, subject: string, message: string, options?: any, siteId?: string): Promise<boolean> {
|
||||||
|
return this.sitesProvider.getSite(siteId).then((site) => {
|
||||||
|
const params = {
|
||||||
|
postid: postId,
|
||||||
|
subject: subject,
|
||||||
|
message: message,
|
||||||
|
options: this.utils.objectToArrayOfObjects(options, 'name', 'value')
|
||||||
|
};
|
||||||
|
|
||||||
|
return site.write('mod_forum_update_discussion_post', params).then((response) => {
|
||||||
|
return response && response.status;
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -388,7 +388,6 @@
|
||||||
"addon.mod_assign.numwords": "{{$a}} words",
|
"addon.mod_assign.numwords": "{{$a}} words",
|
||||||
"addon.mod_assign.outof": "{{$a.current}} out of {{$a.total}}",
|
"addon.mod_assign.outof": "{{$a.current}} out of {{$a.total}}",
|
||||||
"addon.mod_assign.overdue": "<font color=\"red\">Assignment is overdue by: {{$a}}</font>",
|
"addon.mod_assign.overdue": "<font color=\"red\">Assignment is overdue by: {{$a}}</font>",
|
||||||
"addon.mod_assign.savechanges": "Save changes",
|
|
||||||
"addon.mod_assign.submission": "Submission",
|
"addon.mod_assign.submission": "Submission",
|
||||||
"addon.mod_assign.submissioneditable": "Student can edit this submission",
|
"addon.mod_assign.submissioneditable": "Student can edit this submission",
|
||||||
"addon.mod_assign.submissionnoteditable": "Student cannot edit this submission",
|
"addon.mod_assign.submissionnoteditable": "Student cannot edit this submission",
|
||||||
|
@ -571,6 +570,7 @@
|
||||||
"addon.mod_forum.cannotadddiscussionall": "You do not have permission to add a new discussion topic for all participants.",
|
"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.cannotcreatediscussion": "Could not create new discussion",
|
||||||
"addon.mod_forum.couldnotadd": "Could not add your post due to an unknown error",
|
"addon.mod_forum.couldnotadd": "Could not add your post due to an unknown error",
|
||||||
|
"addon.mod_forum.couldnotupdate": "Could not update 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.cutoffdatereached": "The cut-off date for posting to this forum is reached so you can no longer post to it.",
|
||||||
"addon.mod_forum.delete": "Delete",
|
"addon.mod_forum.delete": "Delete",
|
||||||
"addon.mod_forum.deletedpost": "The post has been deleted",
|
"addon.mod_forum.deletedpost": "The post has been deleted",
|
||||||
|
@ -624,6 +624,7 @@
|
||||||
"addon.mod_forum.unpindiscussion": "Unpin this discussion",
|
"addon.mod_forum.unpindiscussion": "Unpin this discussion",
|
||||||
"addon.mod_forum.unread": "Unread",
|
"addon.mod_forum.unread": "Unread",
|
||||||
"addon.mod_forum.unreadpostsnumber": "{{$a}} unread posts",
|
"addon.mod_forum.unreadpostsnumber": "{{$a}} unread posts",
|
||||||
|
"addon.mod_forum.yourreply": "Your reply",
|
||||||
"addon.mod_glossary.addentry": "Add a new entry",
|
"addon.mod_glossary.addentry": "Add a new entry",
|
||||||
"addon.mod_glossary.aliases": "Keyword(s)",
|
"addon.mod_glossary.aliases": "Keyword(s)",
|
||||||
"addon.mod_glossary.attachment": "Attachment",
|
"addon.mod_glossary.attachment": "Attachment",
|
||||||
|
@ -1787,6 +1788,7 @@
|
||||||
"core.restricted": "Restricted",
|
"core.restricted": "Restricted",
|
||||||
"core.retry": "Retry",
|
"core.retry": "Retry",
|
||||||
"core.save": "Save",
|
"core.save": "Save",
|
||||||
|
"core.savechanges": "Save changes",
|
||||||
"core.search": "Search",
|
"core.search": "Search",
|
||||||
"core.searching": "Searching",
|
"core.searching": "Searching",
|
||||||
"core.searchresults": "Search results",
|
"core.searchresults": "Search results",
|
||||||
|
|
|
@ -216,6 +216,7 @@
|
||||||
"restricted": "Restricted",
|
"restricted": "Restricted",
|
||||||
"retry": "Retry",
|
"retry": "Retry",
|
||||||
"save": "Save",
|
"save": "Save",
|
||||||
|
"savechanges": "Save changes",
|
||||||
"search": "Search",
|
"search": "Search",
|
||||||
"searching": "Searching",
|
"searching": "Searching",
|
||||||
"searchresults": "Search results",
|
"searchresults": "Search results",
|
||||||
|
|
|
@ -146,24 +146,25 @@ export class CoreMimetypeUtilsProvider {
|
||||||
*/
|
*/
|
||||||
getEmbeddedHtml(file: any, path?: string): string {
|
getEmbeddedHtml(file: any, path?: string): string {
|
||||||
let ext;
|
let ext;
|
||||||
|
const filename = file.filename || file.name;
|
||||||
|
|
||||||
if (file.mimetype) {
|
if (file.mimetype) {
|
||||||
ext = this.getExtension(file.mimetype);
|
ext = this.getExtension(file.mimetype);
|
||||||
} else {
|
} else {
|
||||||
ext = this.getFileExtension(file.filename);
|
ext = this.getFileExtension(filename);
|
||||||
file.mimetype = this.getMimeType(ext);
|
file.mimetype = this.getMimeType(ext);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (this.canBeEmbedded(ext)) {
|
if (this.canBeEmbedded(ext)) {
|
||||||
file.embedType = this.getExtensionType(ext);
|
file.embedType = this.getExtensionType(ext);
|
||||||
|
|
||||||
path = path || file.fileurl;
|
path = path || file.fileurl || (file.toURL && file.toURL());
|
||||||
|
|
||||||
if (file.embedType == 'image') {
|
if (file.embedType == 'image') {
|
||||||
return '<img src="' + path + '">';
|
return '<img src="' + path + '">';
|
||||||
}
|
}
|
||||||
if (file.embedType == 'audio' || file.embedType == 'video') {
|
if (file.embedType == 'audio' || file.embedType == 'video') {
|
||||||
return '<' + file.embedType + ' controls title="' + file.filename + '" src="' + path + '">' +
|
return '<' + file.embedType + ' controls title="' + filename + '" src="' + path + '">' +
|
||||||
'<source src="' + path + '" type="' + file.mimetype + '">' +
|
'<source src="' + path + '" type="' + file.mimetype + '">' +
|
||||||
'</' + file.embedType + '>';
|
'</' + file.embedType + '>';
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue