commit
						287aa73e08
					
				| @ -389,7 +389,6 @@ | ||||
|   "addon.mod_assign.numwords": "moodle", | ||||
|   "addon.mod_assign.outof": "assign", | ||||
|   "addon.mod_assign.overdue": "assign", | ||||
|   "addon.mod_assign.savechanges": "assign", | ||||
|   "addon.mod_assign.submission": "assign", | ||||
|   "addon.mod_assign.submissioneditable": "assign", | ||||
|   "addon.mod_assign.submissionnoteditable": "assign", | ||||
| @ -572,6 +571,7 @@ | ||||
|   "addon.mod_forum.cannotadddiscussionall": "forum", | ||||
|   "addon.mod_forum.cannotcreatediscussion": "forum", | ||||
|   "addon.mod_forum.couldnotadd": "forum", | ||||
|   "addon.mod_forum.couldnotupdate": "forum", | ||||
|   "addon.mod_forum.cutoffdatereached": "forum", | ||||
|   "addon.mod_forum.delete": "forum", | ||||
|   "addon.mod_forum.deletedpost": "forum", | ||||
| @ -625,6 +625,7 @@ | ||||
|   "addon.mod_forum.unpindiscussion": "forum", | ||||
|   "addon.mod_forum.unread": "forum", | ||||
|   "addon.mod_forum.unreadpostsnumber": "forum", | ||||
|   "addon.mod_forum.yourreply": "forum", | ||||
|   "addon.mod_glossary.addentry": "glossary", | ||||
|   "addon.mod_glossary.aliases": "glossary", | ||||
|   "addon.mod_glossary.attachment": "glossary", | ||||
| @ -1792,6 +1793,7 @@ | ||||
|   "core.restricted": "moodle", | ||||
|   "core.retry": "local_moodlemobileapp", | ||||
|   "core.save": "moodle", | ||||
|   "core.savechanges": "assign", | ||||
|   "core.search": "moodle", | ||||
|   "core.searching": "local_moodlemobileapp", | ||||
|   "core.searchresults": "moodle", | ||||
|  | ||||
| @ -114,7 +114,7 @@ export class AddonCalendarDayPage implements OnInit, OnDestroy { | ||||
|         this.filter.courseId = navParams.get('courseId'); | ||||
|         this.filter.categoryId = navParams.get('categoryId'); | ||||
| 
 | ||||
|         this.filter.filtered = this.filter.courseId || AddonCalendarProvider.ALL_TYPES.some((name) => !this.filter[name]); | ||||
|         this.filter.filtered = !!this.filter.courseId || AddonCalendarProvider.ALL_TYPES.some((name) => !this.filter[name]); | ||||
| 
 | ||||
|         this.year = navParams.get('year') || now.getFullYear(); | ||||
|         this.month = navParams.get('month') || (now.getMonth() + 1); | ||||
|  | ||||
| @ -71,7 +71,6 @@ | ||||
|     "numwords": "{{$a}} words", | ||||
|     "outof": "{{$a.current}} out of {{$a.total}}", | ||||
|     "overdue": "<font color=\"red\">Assignment is overdue by: {{$a}}</font>", | ||||
|     "savechanges": "Save changes", | ||||
|     "submissioneditable": "Student can 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.", | ||||
|  | ||||
| @ -51,9 +51,11 @@ | ||||
|                         </div> | ||||
|                         <div class="addon-mod-forum-discussion-info"> | ||||
|                             <ion-avatar core-user-avatar [user]="discussion" item-start [courseId]="courseId" *ngIf="discussion.userfullname"></ion-avatar> | ||||
|                             <h3 *ngIf="discussion.userfullname">{{discussion.userfullname}}</h3> | ||||
|                             <p *ngIf="discussion.groupname"><ion-icon name="people"></ion-icon> {{ discussion.groupname }}</p> | ||||
|                             <p><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</p> | ||||
|                             <div class="addon-mod-forum-discussion-author"> | ||||
|                                 <h3 *ngIf="discussion.userfullname">{{discussion.userfullname}}</h3> | ||||
|                                 <p *ngIf="discussion.groupname"><ion-icon name="people"></ion-icon> {{ discussion.groupname }}</p> | ||||
|                                 <p><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</p> | ||||
|                             </div> | ||||
|                         </div> | ||||
|                     </ion-item> | ||||
|                 </ng-container> | ||||
|  | ||||
| @ -11,7 +11,8 @@ | ||||
|     <ion-item text-wrap (click)="dismiss()" *ngIf="wordCount"> | ||||
|         <h2>{{ 'core.numwords' | translate: {'$a': wordCount} }}</h2> | ||||
|     </ion-item> | ||||
|     <ion-item text-wrap (click)="dismiss()" *ngIf="!canEdit && !canDelete && !wordCount"> | ||||
|         <h2>{{ 'core.nooptionavailable' | translate }}</h2> | ||||
|     </ion-item> | ||||
|     <a ion-item text-wrap [href]="url" *ngIf="url" core-link capture="false"> | ||||
|         <ion-icon name="open" item-start></ion-icon> | ||||
|         <h2>{{ 'core.openinbrowser' | translate }}</h2> | ||||
|     </a> | ||||
| </core-loading> | ||||
|  | ||||
| @ -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; | ||||
|     } | ||||
| } | ||||
| @ -15,6 +15,8 @@ | ||||
| import { Component, OnInit } from '@angular/core'; | ||||
| import { NavParams, ViewController } from 'ionic-angular'; | ||||
| import { CoreDomUtilsProvider } from '@providers/utils/dom'; | ||||
| import { CoreSitesProvider } from '@providers/sites'; | ||||
| import { CoreSite } from '@classes/site'; | ||||
| import { AddonModForumProvider } from '../../providers/forum'; | ||||
| 
 | ||||
| /** | ||||
| @ -31,11 +33,13 @@ export class AddonForumPostOptionsMenuComponent implements OnInit { | ||||
|     canEdit = false; | ||||
|     canDelete = false; | ||||
|     loaded = false; | ||||
|     url: string; | ||||
| 
 | ||||
|     constructor(navParams: NavParams, | ||||
|             protected viewCtrl: ViewController, | ||||
|             protected domUtils: CoreDomUtilsProvider, | ||||
|             protected forumProvider: AddonModForumProvider) { | ||||
|             protected forumProvider: AddonModForumProvider, | ||||
|             protected sitesProvider: CoreSitesProvider) { | ||||
|         this.post = navParams.get('post'); | ||||
|         this.forumId = navParams.get('forumId'); | ||||
|     } | ||||
| @ -46,9 +50,12 @@ export class AddonForumPostOptionsMenuComponent implements OnInit { | ||||
|     ngOnInit(): void { | ||||
|         if (this.forumId) { | ||||
|             if (this.post.id) { | ||||
|                 this.forumProvider.getDiscussionPost(this.forumId, this.post.discussion, this.post.id).then((post) => { | ||||
|                 const site: CoreSite = this.sitesProvider.getCurrentSite(); | ||||
|                 this.url = site.createSiteUrl('/mod/forum/discuss.php', {d: this.post.discussion}, 'p' + this.post.id); | ||||
| 
 | ||||
|                 this.forumProvider.getDiscussionPost(this.forumId, this.post.discussion, this.post.id, true).then((post) => { | ||||
|                     this.canDelete = post.capabilities.delete && this.forumProvider.isDeletePostAvailable(); | ||||
|                     this.canEdit = false; | ||||
|                     this.canEdit = post.capabilities.edit && this.forumProvider.isUpdatePostAvailable(); | ||||
|                     this.wordCount = post.wordcount; | ||||
|                 }).catch((error) => { | ||||
|                     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-format-text [text]="post.subject" contextLevel="module" [contextInstanceId]="forum && forum.cmid" [courseId]="courseId"></core-format-text> | ||||
|                 </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"> | ||||
|                     <core-icon name="more"></core-icon> | ||||
|                 </button> | ||||
| @ -19,12 +22,14 @@ | ||||
|                     <p *ngIf="post.modified">{{post.modified * 1000 | coreFormatDate: "strftimerecentfull"}}</p> | ||||
|                     <p *ngIf="!post.modified"><ion-icon name="time"></ion-icon> {{ 'core.notsent' | translate }}</p> | ||||
|                 </div> | ||||
|                 <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="!displaySubject && optionsMenuEnabled"> | ||||
|                     <core-icon name="more"></core-icon> | ||||
|                 </button> | ||||
|                 <ng-container *ngIf="!displaySubject"> | ||||
|                     <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"> | ||||
|                         <core-icon name="more"></core-icon> | ||||
|                     </button> | ||||
|                 </ng-container> | ||||
|             </div> | ||||
|         </ion-item> | ||||
|     </ion-card-header> | ||||
|  | ||||
| @ -14,7 +14,7 @@ | ||||
| 
 | ||||
| import { Component, Input, Output, Optional, EventEmitter, OnInit, OnDestroy } from '@angular/core'; | ||||
| 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 { CoreFileUploaderProvider } from '@core/fileuploader/providers/fileuploader'; | ||||
| import { CoreSyncProvider } from '@providers/sync'; | ||||
| @ -75,6 +75,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy { | ||||
|             private tagProvider: CoreTagProvider, | ||||
|             @Optional() private content: Content, | ||||
|             protected popoverCtrl: PopoverController, | ||||
|             protected modalCtrl: ModalController, | ||||
|             protected eventsProvider: CoreEventsProvider, | ||||
|             protected sitesProvider: CoreSitesProvider) { | ||||
|         this.onPostChange = new EventEmitter<void>(); | ||||
| @ -93,7 +94,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy { | ||||
|                 this.post.subject != reTranslated + this.defaultSubject); | ||||
| 
 | ||||
|         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) { | ||||
|                 switch (data.action) { | ||||
|                     case 'edit': | ||||
|                         // Not implemented.
 | ||||
|                         this.editPost(); | ||||
|                         break; | ||||
|                     case 'editoffline': | ||||
|                         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. | ||||
|      */ | ||||
|  | ||||
| @ -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", | ||||
|     "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.", | ||||
|     "delete": "Delete", | ||||
|     "deletedpost": "The post has been deleted", | ||||
| @ -60,5 +61,6 @@ | ||||
|     "unlockdiscussion": "Unlock this discussion", | ||||
|     "unpindiscussion": "Unpin this discussion", | ||||
|     "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> | ||||
							
								
								
									
										35
									
								
								src/addon/mod/forum/pages/edit-post/edit-post.module.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										35
									
								
								src/addon/mod/forum/pages/edit-post/edit-post.module.ts
									
									
									
									
									
										Normal file
									
								
							| @ -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 {} | ||||
							
								
								
									
										141
									
								
								src/addon/mod/forum/pages/edit-post/edit-post.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										141
									
								
								src/addon/mod/forum/pages/edit-post/edit-post.ts
									
									
									
									
									
										Normal file
									
								
							| @ -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'); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * 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. | ||||
|      * | ||||
| @ -385,25 +395,31 @@ export class AddonModForumProvider { | ||||
|      * @param forumId Forum ID. | ||||
|      * @param discussionId Discussion 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. | ||||
|      * @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) => { | ||||
|             const params = { | ||||
|                 postid: postId | ||||
|             }; | ||||
|             const preSets = { | ||||
|                 cacheKey: this.getDiscussionPostDataCacheKey(forumId, discussionId, postId), | ||||
|                 updateFrequency: CoreSite.FREQUENCY_RARELY | ||||
|             }; | ||||
|                     postid: postId | ||||
|                 }, | ||||
|                 preSets: CoreSiteWSPreSets = { | ||||
|                     cacheKey: this.getDiscussionPostDataCacheKey(forumId, discussionId, postId), | ||||
|                     updateFrequency: CoreSite.FREQUENCY_USUALLY | ||||
|                 }; | ||||
| 
 | ||||
|             if (ignoreCache) { | ||||
|                 preSets.getFromCache = false; | ||||
|                 preSets.emergencyCache = false; | ||||
|             } | ||||
| 
 | ||||
|             return site.read('mod_forum_get_discussion_post', params, preSets).then((response) => { | ||||
|                 if (response.post) { | ||||
|                     return response.post; | ||||
|                 } else { | ||||
|                     return Promise.reject(null); | ||||
|                 } | ||||
| 
 | ||||
|                 return Promise.reject(null); | ||||
|             }); | ||||
|         }); | ||||
|     } | ||||
| @ -1050,4 +1066,29 @@ export class AddonModForumProvider { | ||||
| 
 | ||||
|         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.outof": "{{$a.current}} out of {{$a.total}}", | ||||
|     "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.submissioneditable": "Student can 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.cannotcreatediscussion": "Could not create new discussion", | ||||
|     "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.delete": "Delete", | ||||
|     "addon.mod_forum.deletedpost": "The post has been deleted", | ||||
| @ -624,6 +624,7 @@ | ||||
|     "addon.mod_forum.unpindiscussion": "Unpin this discussion", | ||||
|     "addon.mod_forum.unread": "Unread", | ||||
|     "addon.mod_forum.unreadpostsnumber": "{{$a}} unread posts", | ||||
|     "addon.mod_forum.yourreply": "Your reply", | ||||
|     "addon.mod_glossary.addentry": "Add a new entry", | ||||
|     "addon.mod_glossary.aliases": "Keyword(s)", | ||||
|     "addon.mod_glossary.attachment": "Attachment", | ||||
| @ -1787,6 +1788,7 @@ | ||||
|     "core.restricted": "Restricted", | ||||
|     "core.retry": "Retry", | ||||
|     "core.save": "Save", | ||||
|     "core.savechanges": "Save changes", | ||||
|     "core.search": "Search", | ||||
|     "core.searching": "Searching", | ||||
|     "core.searchresults": "Search results", | ||||
|  | ||||
| @ -1309,6 +1309,18 @@ export class CoreSite { | ||||
|         return this.urlUtils.getDocsUrl(release, page); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Returns a url to link an specific page on the site. | ||||
|      * | ||||
|      * @param path Path of the url to go to. | ||||
|      * @param params Object with the params to add. | ||||
|      * @param anchor Anchor text if needed. | ||||
|      * @return URL with params. | ||||
|      */ | ||||
|     createSiteUrl(path: string, params?: {[key: string]: any}, anchor?: string): string { | ||||
|         return this.urlUtils.addParamsToUrl(this.siteUrl + path, params, anchor); | ||||
|     } | ||||
| 
 | ||||
|     /** | ||||
|      * Check if the local_mobile plugin is installed in the Moodle site. | ||||
|      * | ||||
|  | ||||
| @ -216,6 +216,7 @@ | ||||
|     "restricted": "Restricted", | ||||
|     "retry": "Retry", | ||||
|     "save": "Save", | ||||
|     "savechanges": "Save changes", | ||||
|     "search": "Search", | ||||
|     "searching": "Searching", | ||||
|     "searchresults": "Search results", | ||||
|  | ||||
| @ -146,24 +146,25 @@ export class CoreMimetypeUtilsProvider { | ||||
|      */ | ||||
|     getEmbeddedHtml(file: any, path?: string): string { | ||||
|         let ext; | ||||
|         const filename = file.filename || file.name; | ||||
| 
 | ||||
|         if (file.mimetype) { | ||||
|             ext = this.getExtension(file.mimetype); | ||||
|         } else { | ||||
|             ext = this.getFileExtension(file.filename); | ||||
|             ext = this.getFileExtension(filename); | ||||
|             file.mimetype = this.getMimeType(ext); | ||||
|         } | ||||
| 
 | ||||
|         if (this.canBeEmbedded(ext)) { | ||||
|             file.embedType = this.getExtensionType(ext); | ||||
| 
 | ||||
|             path = path || file.fileurl; | ||||
|             path = path || file.fileurl || (file.toURL && file.toURL()); | ||||
| 
 | ||||
|             if (file.embedType == 'image') { | ||||
|                 return '<img src="' + path + '">'; | ||||
|             } | ||||
|             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 + '">' + | ||||
|                     '</' + file.embedType + '>'; | ||||
|             } | ||||
|  | ||||
| @ -49,9 +49,10 @@ export class CoreUrlUtilsProvider { | ||||
|      * | ||||
|      * @param url URL to add the params to. | ||||
|      * @param params Object with the params to add. | ||||
|      * @param anchor Anchor text if needed. | ||||
|      * @return URL with params. | ||||
|      */ | ||||
|     addParamsToUrl(url: string, params: {[key: string]: any}): string { | ||||
|     addParamsToUrl(url: string, params?: {[key: string]: any}, anchor?: string): string { | ||||
|         let separator = url.indexOf('?') != -1 ? '&' : '?'; | ||||
| 
 | ||||
|         for (const key in params) { | ||||
| @ -64,6 +65,10 @@ export class CoreUrlUtilsProvider { | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (anchor) { | ||||
|             url += '#' + anchor; | ||||
|         } | ||||
| 
 | ||||
|         return url; | ||||
|     } | ||||
| 
 | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user