MOBILE-3643 forum: Migrate navigation guards
parent
d4bc77b386
commit
26f18ac5f4
|
@ -39,6 +39,7 @@ import { CorePageItemsListManager } from '@classes/page-items-list-manager';
|
||||||
import { CoreSplitViewComponent } from '@components/split-view/split-view';
|
import { CoreSplitViewComponent } from '@components/split-view/split-view';
|
||||||
import { AddonModForumDiscussionOptionsMenuComponent } from '../discussion-options-menu/discussion-options-menu';
|
import { AddonModForumDiscussionOptionsMenuComponent } from '../discussion-options-menu/discussion-options-menu';
|
||||||
import { AddonModForumSortOrderSelectorComponent } from '../sort-order-selector/sort-order-selector';
|
import { AddonModForumSortOrderSelectorComponent } from '../sort-order-selector/sort-order-selector';
|
||||||
|
import { CoreScreen } from '@services/screen';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Type to use for selecting new discussion form in the discussions manager.
|
* Type to use for selecting new discussion form in the discussions manager.
|
||||||
|
@ -48,6 +49,16 @@ type NewDiscussionForm = {
|
||||||
timeCreated: number;
|
timeCreated: number;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Type guard to infer NewDiscussionForm objects.
|
||||||
|
*
|
||||||
|
* @param discussion Object to check.
|
||||||
|
* @return Whether the object is a new discussion form.
|
||||||
|
*/
|
||||||
|
function isNewDiscussionForm(discussion: Record<string, unknown>): discussion is NewDiscussionForm {
|
||||||
|
return 'newDiscussion' in discussion;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Component that displays a forum entry page.
|
* Component that displays a forum entry page.
|
||||||
*/
|
*/
|
||||||
|
@ -115,6 +126,21 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
|
||||||
this.sortOrders = AddonModForum.instance.getAvailableSortOrders();
|
this.sortOrders = AddonModForum.instance.getAvailableSortOrders();
|
||||||
|
|
||||||
await super.ngOnInit();
|
await super.ngOnInit();
|
||||||
|
|
||||||
|
// Refresh data if this forum discussion is synchronized from discussions list.
|
||||||
|
this.syncManualObserver = CoreEvents.on(AddonModForumSyncProvider.MANUAL_SYNCED, (data) => {
|
||||||
|
this.autoSyncEventReceived(data);
|
||||||
|
}, this.siteId);
|
||||||
|
|
||||||
|
// Listen for discussions added. When a discussion is added, we reload the data.
|
||||||
|
this.newDiscObserver = CoreEvents.on(
|
||||||
|
AddonModForumProvider.NEW_DISCUSSION_EVENT,
|
||||||
|
this.eventReceived.bind(this, true),
|
||||||
|
);
|
||||||
|
this.replyObserver = CoreEvents.on(
|
||||||
|
AddonModForumProvider.REPLY_DISCUSSION_EVENT,
|
||||||
|
this.eventReceived.bind(this, false),
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
async ngAfterViewInit(): Promise<void> {
|
async ngAfterViewInit(): Promise<void> {
|
||||||
|
@ -503,6 +529,37 @@ export class AddonModForumIndexComponent extends CoreCourseModuleMainActivityCom
|
||||||
return result.updated;
|
return result.updated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function called when we receive an event of new discussion or reply to discussion.
|
||||||
|
*
|
||||||
|
* @param isNewDiscussion Whether it's a new discussion event.
|
||||||
|
* @param data Event data.
|
||||||
|
*/
|
||||||
|
protected eventReceived(isNewDiscussion: boolean, data: any): void {
|
||||||
|
if ((this.forum && this.forum.id === data.forumId) || data.cmId === this.module?.id) {
|
||||||
|
this.showLoadingAndRefresh(false).finally(() => {
|
||||||
|
// If it's a new discussion in tablet mode, try to open it.
|
||||||
|
if (isNewDiscussion && CoreScreen.instance.isTablet) {
|
||||||
|
if (data.discussionIds) {
|
||||||
|
// Discussion sent to server, search it in the list of discussions.
|
||||||
|
const discussion = this.discussions.items.find(
|
||||||
|
(disc) =>
|
||||||
|
!isNewDiscussionForm(disc) &&
|
||||||
|
data.discussionIds.indexOf(disc.discussion) >= 0,
|
||||||
|
);
|
||||||
|
|
||||||
|
this.discussions.select(discussion ?? this.discussions.items[0]);
|
||||||
|
} else if (data.discTimecreated) {
|
||||||
|
// It's an offline discussion, open it.
|
||||||
|
this.openNewDiscussion(data.discTimecreated);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Check completion since it could be configured to complete once the user adds a new discussion or replies.
|
||||||
|
CoreCourse.instance.checkModuleCompletion(this.courseId!, this.module!.completiondata);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opens the new discussion form.
|
* Opens the new discussion form.
|
||||||
|
@ -611,7 +668,7 @@ class AddonModForumDiscussionsManager extends CorePageItemsListManager<AddonModF
|
||||||
cmId: this.component.module!.id,
|
cmId: this.component.module!.id,
|
||||||
forumId: this.component.forum!.id,
|
forumId: this.component.forum!.id,
|
||||||
...(
|
...(
|
||||||
this.isNewDiscussionForm(discussion)
|
isNewDiscussionForm(discussion)
|
||||||
? { timeCreated: discussion.timeCreated }
|
? { timeCreated: discussion.timeCreated }
|
||||||
: { discussion, trackPosts: this.component.trackPosts }
|
: { discussion, trackPosts: this.component.trackPosts }
|
||||||
),
|
),
|
||||||
|
@ -619,7 +676,7 @@ class AddonModForumDiscussionsManager extends CorePageItemsListManager<AddonModF
|
||||||
}
|
}
|
||||||
|
|
||||||
protected getItemPath(discussion: AddonModForumDiscussion | NewDiscussionForm): string {
|
protected getItemPath(discussion: AddonModForumDiscussion | NewDiscussionForm): string {
|
||||||
const discussionId = this.isNewDiscussionForm(discussion) ? 'new' : discussion.id;
|
const discussionId = isNewDiscussionForm(discussion) ? 'new' : discussion.id;
|
||||||
|
|
||||||
return this.discussionsPathPrefix + discussionId;
|
return this.discussionsPathPrefix + discussionId;
|
||||||
}
|
}
|
||||||
|
@ -630,8 +687,4 @@ class AddonModForumDiscussionsManager extends CorePageItemsListManager<AddonModF
|
||||||
return discussionId ? this.discussionsPathPrefix + discussionId : null;
|
return discussionId ? this.discussionsPathPrefix + discussionId : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private isNewDiscussionForm(discussion: AddonModForumDiscussion | NewDiscussionForm): discussion is NewDiscussionForm {
|
|
||||||
return 'newDiscussion' in discussion;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,14 +15,12 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
|
||||||
|
import { conditionalRoutes } from '@/app/app-routing.module';
|
||||||
|
import { CoreScreen } from '@services/screen';
|
||||||
import { CoreSharedModule } from '@/core/shared.module';
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
import { CoreEditorComponentsModule } from '@features/editor/components/components.module';
|
|
||||||
|
|
||||||
import { AddonModForumComponentsModule } from './components/components.module';
|
import { AddonModForumComponentsModule } from './components/components.module';
|
||||||
import { AddonModForumIndexPage } from './pages/index';
|
import { AddonModForumIndexPage } from './pages/index';
|
||||||
import { conditionalRoutes } from '@/app/app-routing.module';
|
|
||||||
import { CoreScreen } from '@services/screen';
|
|
||||||
import { AddonModForumNewDiscussionPage } from './pages/new-discussion/new-discussion';
|
|
||||||
|
|
||||||
const mobileRoutes: Routes = [
|
const mobileRoutes: Routes = [
|
||||||
{
|
{
|
||||||
|
@ -31,7 +29,7 @@ const mobileRoutes: Routes = [
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ':courseId/:cmId/new',
|
path: ':courseId/:cmId/new',
|
||||||
component: AddonModForumNewDiscussionPage,
|
loadChildren: () => import('./pages/new-discussion/new-discussion.module').then(m => m.AddonForumNewDiscussionPageModule),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ':courseId/:cmId/:discussionId',
|
path: ':courseId/:cmId/:discussionId',
|
||||||
|
@ -46,7 +44,8 @@ const tabletRoutes: Routes = [
|
||||||
children: [
|
children: [
|
||||||
{
|
{
|
||||||
path: 'new',
|
path: 'new',
|
||||||
component: AddonModForumNewDiscussionPage,
|
loadChildren: () => import('./pages/new-discussion/new-discussion.module')
|
||||||
|
.then(m => m.AddonForumNewDiscussionPageModule),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
path: ':discussionId',
|
path: ':discussionId',
|
||||||
|
@ -67,11 +66,9 @@ const routes: Routes = [
|
||||||
RouterModule.forChild(routes),
|
RouterModule.forChild(routes),
|
||||||
CoreSharedModule,
|
CoreSharedModule,
|
||||||
AddonModForumComponentsModule,
|
AddonModForumComponentsModule,
|
||||||
CoreEditorComponentsModule,
|
|
||||||
],
|
],
|
||||||
declarations: [
|
declarations: [
|
||||||
AddonModForumIndexPage,
|
AddonModForumIndexPage,
|
||||||
AddonModForumNewDiscussionPage,
|
|
||||||
],
|
],
|
||||||
})
|
})
|
||||||
export class AddonModForumLazyModule {}
|
export class AddonModForumLazyModule {}
|
||||||
|
|
|
@ -33,6 +33,11 @@ const mainMenuRoutes: Routes = [
|
||||||
},
|
},
|
||||||
...conditionalRoutes(
|
...conditionalRoutes(
|
||||||
[
|
[
|
||||||
|
{
|
||||||
|
path: 'course/index/contents/mod_forum/new',
|
||||||
|
loadChildren: () => import('./pages/new-discussion/new-discussion.module')
|
||||||
|
.then(m => m.AddonForumNewDiscussionPageModule),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'course/index/contents/mod_forum/:discussionId',
|
path: 'course/index/contents/mod_forum/:discussionId',
|
||||||
loadChildren: () => import('./pages/discussion/discussion.module').then(m => m.AddonForumDiscussionPageModule),
|
loadChildren: () => import('./pages/discussion/discussion.module').then(m => m.AddonForumDiscussionPageModule),
|
||||||
|
@ -44,6 +49,11 @@ const mainMenuRoutes: Routes = [
|
||||||
|
|
||||||
const courseContentsRoutes: Routes = conditionalRoutes(
|
const courseContentsRoutes: Routes = conditionalRoutes(
|
||||||
[
|
[
|
||||||
|
{
|
||||||
|
path: 'mod_forum/new',
|
||||||
|
loadChildren: () => import('./pages/new-discussion/new-discussion.module')
|
||||||
|
.then(m => m.AddonForumNewDiscussionPageModule),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
path: 'mod_forum/:discussionId',
|
path: 'mod_forum/:discussionId',
|
||||||
loadChildren: () => import('./pages/discussion/discussion.module').then(m => m.AddonForumDiscussionPageModule),
|
loadChildren: () => import('./pages/discussion/discussion.module').then(m => m.AddonForumDiscussionPageModule),
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
<core-navbar-buttons slot="end">
|
<core-navbar-buttons slot="end">
|
||||||
<core-context-menu>
|
<core-context-menu>
|
||||||
<core-context-menu-item [priority]="650" *ngIf="discussionLoaded && !postHasOffline && isOnline" [content]="'addon.mod_forum.refreshposts' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
<core-context-menu-item [priority]="650" *ngIf="discussionLoaded && !postHasOffline && isOnline" [content]="'addon.mod_forum.refreshposts' | translate" (action)="doRefresh(null, $event)" [iconAction]="refreshIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||||
<core-context-menu-item [priority]="550" *ngIf="discussionLoaded && !isSplitViewOn && postHasOffline && isOnline" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
<core-context-menu-item [priority]="550" *ngIf="discussionLoaded && isMobile && postHasOffline && isOnline" [content]="'core.settings.synchronizenow' | translate" (action)="doRefresh(null, $event, true)" [iconAction]="syncIcon" [closeOnClick]="false"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="sort == 'flat-oldest'" [priority]="500" [content]="'addon.mod_forum.modeflatoldestfirst' | translate" (action)="changeSort('flat-oldest')" iconAction="arrow-round-down"></core-context-menu-item>
|
<core-context-menu-item [hidden]="sort == 'flat-oldest'" [priority]="500" [content]="'addon.mod_forum.modeflatoldestfirst' | translate" (action)="changeSort('flat-oldest')" iconAction="arrow-round-down"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="sort == 'flat-newest'" [priority]="450" [content]="'addon.mod_forum.modeflatnewestfirst' | translate" (action)="changeSort('flat-newest')" iconAction="arrow-round-up"></core-context-menu-item>
|
<core-context-menu-item [hidden]="sort == 'flat-newest'" [priority]="450" [content]="'addon.mod_forum.modeflatnewestfirst' | translate" (action)="changeSort('flat-newest')" iconAction="arrow-round-up"></core-context-menu-item>
|
||||||
<core-context-menu-item [hidden]="sort == 'nested'" [priority]="400" [content]="'addon.mod_forum.modenested' | translate" (action)="changeSort('nested')" iconAction="swap"></core-context-menu-item>
|
<core-context-menu-item [hidden]="sort == 'nested'" [priority]="400" [content]="'addon.mod_forum.modenested' | translate" (action)="changeSort('nested')" iconAction="swap"></core-context-menu-item>
|
||||||
|
|
|
@ -16,6 +16,7 @@ import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
|
|
||||||
import { AddonModForumComponentsModule } from '@addons/mod/forum/components/components.module';
|
import { AddonModForumComponentsModule } from '@addons/mod/forum/components/components.module';
|
||||||
|
import { CanLeaveGuard } from '@guards/can-leave';
|
||||||
import { CoreSharedModule } from '@/core/shared.module';
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
|
||||||
import { AddonModForumDiscussionPage } from './discussion.page';
|
import { AddonModForumDiscussionPage } from './discussion.page';
|
||||||
|
@ -23,6 +24,7 @@ import { AddonModForumDiscussionPage } from './discussion.page';
|
||||||
const routes: Routes = [{
|
const routes: Routes = [{
|
||||||
path: '',
|
path: '',
|
||||||
component: AddonModForumDiscussionPage,
|
component: AddonModForumDiscussionPage,
|
||||||
|
canDeactivate: [CanLeaveGuard],
|
||||||
}];
|
}];
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
|
@ -13,10 +13,13 @@
|
||||||
// limitations under the License.
|
// limitations under the License.
|
||||||
|
|
||||||
import { Component, OnDestroy, ViewChild, OnInit, AfterViewInit, ElementRef } from '@angular/core';
|
import { Component, OnDestroy, ViewChild, OnInit, AfterViewInit, ElementRef } from '@angular/core';
|
||||||
|
import { CoreFileUploader } from '@features/fileuploader/services/fileuploader';
|
||||||
import { CoreUser } from '@features/user/services/user';
|
import { CoreUser } from '@features/user/services/user';
|
||||||
|
import { CanLeave } from '@guards/can-leave';
|
||||||
import { IonContent } from '@ionic/angular';
|
import { IonContent } from '@ionic/angular';
|
||||||
import { CoreApp } from '@services/app';
|
import { CoreApp } from '@services/app';
|
||||||
import { CoreNavigator } from '@services/navigator';
|
import { CoreNavigator } from '@services/navigator';
|
||||||
|
import { CoreScreen } from '@services/screen';
|
||||||
import { CoreSites } from '@services/sites';
|
import { CoreSites } from '@services/sites';
|
||||||
import { CoreDomUtils } from '@services/utils/dom';
|
import { CoreDomUtils } from '@services/utils/dom';
|
||||||
import { CoreUtils } from '@services/utils/utils';
|
import { CoreUtils } from '@services/utils/utils';
|
||||||
|
@ -48,7 +51,7 @@ type Post = AddonModForumPost & { children?: Post[] };
|
||||||
templateUrl: 'discussion.html',
|
templateUrl: 'discussion.html',
|
||||||
styleUrls: ['discussion.scss'],
|
styleUrls: ['discussion.scss'],
|
||||||
})
|
})
|
||||||
export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDestroy {
|
export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDestroy, CanLeave {
|
||||||
|
|
||||||
@ViewChild(IonContent) content!: IonContent;
|
@ViewChild(IonContent) content!: IonContent;
|
||||||
|
|
||||||
|
@ -105,6 +108,10 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
|
|
||||||
constructor(protected elementRef: ElementRef) {}
|
constructor(protected elementRef: ElementRef) {}
|
||||||
|
|
||||||
|
get isMobile(): boolean {
|
||||||
|
return CoreScreen.instance.isMobile;
|
||||||
|
}
|
||||||
|
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.courseId = CoreNavigator.instance.getRouteNumberParam('courseId')!;
|
this.courseId = CoreNavigator.instance.getRouteNumberParam('courseId')!;
|
||||||
this.cmId = CoreNavigator.instance.getRouteNumberParam('cmId')!;
|
this.cmId = CoreNavigator.instance.getRouteNumberParam('cmId')!;
|
||||||
|
@ -153,40 +160,6 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Get sort type configured by the current user.
|
|
||||||
*
|
|
||||||
* @return Promise resolved with the sort type.
|
|
||||||
*/
|
|
||||||
protected async getUserSort(): Promise<SortType> {
|
|
||||||
try {
|
|
||||||
const value = await CoreSites.instance.getCurrentSite()!.getLocalSiteConfig<SortType>('AddonModForumDiscussionSort');
|
|
||||||
|
|
||||||
return value;
|
|
||||||
} catch (error) {
|
|
||||||
try {
|
|
||||||
const value = await CoreUser.instance.getUserPreference('forum_displaymode');
|
|
||||||
|
|
||||||
switch (Number(value)) {
|
|
||||||
case 1:
|
|
||||||
return 'flat-oldest';
|
|
||||||
case -1:
|
|
||||||
return 'flat-newest';
|
|
||||||
case 3:
|
|
||||||
return 'nested';
|
|
||||||
case 2: // Threaded not implemented.
|
|
||||||
default:
|
|
||||||
// Not set, use default sort.
|
|
||||||
// @TODO add fallback to $CFG->forum_displaymode.
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
// Ignore errors.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 'flat-oldest';
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* User entered the page that contains the component.
|
* User entered the page that contains the component.
|
||||||
*/
|
*/
|
||||||
|
@ -216,11 +189,10 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
}
|
}
|
||||||
}, CoreSites.instance.getCurrentSiteId());
|
}, CoreSites.instance.getCurrentSiteId());
|
||||||
|
|
||||||
// Trigger view event, to highlight the current opened discussion in the split view.
|
// Invalidate discussion list if it was not read.
|
||||||
CoreEvents.trigger(AddonModForumProvider.VIEW_DISCUSSION_EVENT, {
|
if (this.discussion.numunread > 0) {
|
||||||
forumId: this.forumId,
|
AddonModForum.instance.invalidateDiscussionsList(this.forumId);
|
||||||
discussion: this.discussionId,
|
}
|
||||||
}, CoreSites.instance.getCurrentSiteId());
|
|
||||||
|
|
||||||
this.changeDiscObserver = CoreEvents.on(AddonModForumProvider.CHANGE_DISCUSSION_EVENT, (data: any) => {
|
this.changeDiscObserver = CoreEvents.on(AddonModForumProvider.CHANGE_DISCUSSION_EVENT, (data: any) => {
|
||||||
if ((this.forumId && this.forumId === data.forumId) || data.cmId === this.cmId) {
|
if ((this.forumId && this.forumId === data.forumId) || data.cmId === this.cmId) {
|
||||||
|
@ -253,24 +225,77 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// @todo
|
/**
|
||||||
// /**
|
* Check if we can leave the page or not.
|
||||||
// * Check if we can leave the page or not.
|
*
|
||||||
// *
|
* @return Resolved if we can leave it, rejected if not.
|
||||||
// * @return Resolved if we can leave it, rejected if not.
|
*/
|
||||||
// */
|
async canLeave(): Promise<boolean> {
|
||||||
// async ionViewCanLeave(): Promise<void> {
|
if (AddonModForumHelper.instance.hasPostDataChanged(this.replyData, this.originalData)) {
|
||||||
|
// Show confirmation if some data has been modified.
|
||||||
|
await CoreDomUtils.instance.showConfirm(Translate.instant('core.confirmcanceledit'));
|
||||||
|
}
|
||||||
|
|
||||||
// if (AddonModForumHelper.instance.hasPostDataChanged(this.replyData, this.originalData)) {
|
// Delete the local files from the tmp folder.
|
||||||
// // Show confirmation if some data has been modified.
|
CoreFileUploader.instance.clearTmpFiles(this.replyData.files);
|
||||||
// await CoreDomUtils.instance.showConfirm(this.translate.instant('core.confirmcanceledit'));
|
|
||||||
// }
|
|
||||||
|
|
||||||
// // Delete the local files from the tmp folder.
|
this.leavingPage = true;
|
||||||
// this.uploaderProvider.clearTmpFiles(this.replyData.files);
|
|
||||||
|
|
||||||
// this.leavingPage = true;
|
return true;
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runs when the page is about to leave and no longer be the active page.
|
||||||
|
*/
|
||||||
|
ionViewWillLeave(): void {
|
||||||
|
this.syncObserver && this.syncObserver.off();
|
||||||
|
this.syncManualObserver && this.syncManualObserver.off();
|
||||||
|
this.ratingOfflineObserver && this.ratingOfflineObserver.off();
|
||||||
|
this.ratingSyncObserver && this.ratingSyncObserver.off();
|
||||||
|
this.changeDiscObserver && this.changeDiscObserver.off();
|
||||||
|
delete this.syncObserver;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Page destroyed.
|
||||||
|
*/
|
||||||
|
ngOnDestroy(): void {
|
||||||
|
this.onlineObserver && this.onlineObserver.unsubscribe();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get sort type configured by the current user.
|
||||||
|
*
|
||||||
|
* @return Promise resolved with the sort type.
|
||||||
|
*/
|
||||||
|
protected async getUserSort(): Promise<SortType> {
|
||||||
|
try {
|
||||||
|
const value = await CoreSites.instance.getCurrentSite()!.getLocalSiteConfig<SortType>('AddonModForumDiscussionSort');
|
||||||
|
|
||||||
|
return value;
|
||||||
|
} catch (error) {
|
||||||
|
try {
|
||||||
|
const value = await CoreUser.instance.getUserPreference('forum_displaymode');
|
||||||
|
|
||||||
|
switch (Number(value)) {
|
||||||
|
case 1:
|
||||||
|
return 'flat-oldest';
|
||||||
|
case -1:
|
||||||
|
return 'flat-newest';
|
||||||
|
case 3:
|
||||||
|
return 'nested';
|
||||||
|
case 2: // Threaded not implemented.
|
||||||
|
default:
|
||||||
|
// Not set, use default sort.
|
||||||
|
// @TODO add fallback to $CFG->forum_displaymode.
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
// Ignore errors.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 'flat-oldest';
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Convenience function to get the forum.
|
* Convenience function to get the forum.
|
||||||
|
@ -710,25 +735,6 @@ export class AddonModForumDiscussionPage implements OnInit, AfterViewInit, OnDes
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Runs when the page is about to leave and no longer be the active page.
|
|
||||||
*/
|
|
||||||
ionViewWillLeave(): void {
|
|
||||||
this.syncObserver && this.syncObserver.off();
|
|
||||||
this.syncManualObserver && this.syncManualObserver.off();
|
|
||||||
this.ratingOfflineObserver && this.ratingOfflineObserver.off();
|
|
||||||
this.ratingSyncObserver && this.ratingSyncObserver.off();
|
|
||||||
this.changeDiscObserver && this.changeDiscObserver.off();
|
|
||||||
delete this.syncObserver;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Page destroyed.
|
|
||||||
*/
|
|
||||||
ngOnDestroy(): void {
|
|
||||||
this.onlineObserver && this.onlineObserver.unsubscribe();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get all the posts contained in the discussion.
|
* Get all the posts contained in the discussion.
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,42 @@
|
||||||
|
// (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 { RouterModule, Routes } from '@angular/router';
|
||||||
|
|
||||||
|
import { AddonModForumComponentsModule } from '@addons/mod/forum/components/components.module';
|
||||||
|
import { CanLeaveGuard } from '@guards/can-leave';
|
||||||
|
import { CoreEditorComponentsModule } from '@features/editor/components/components.module';
|
||||||
|
import { CoreSharedModule } from '@/core/shared.module';
|
||||||
|
|
||||||
|
import { AddonModForumNewDiscussionPage } from './new-discussion.page';
|
||||||
|
|
||||||
|
const routes: Routes = [{
|
||||||
|
path: '',
|
||||||
|
component: AddonModForumNewDiscussionPage,
|
||||||
|
canDeactivate: [CanLeaveGuard],
|
||||||
|
}];
|
||||||
|
|
||||||
|
@NgModule({
|
||||||
|
imports: [
|
||||||
|
RouterModule.forChild(routes),
|
||||||
|
CoreSharedModule,
|
||||||
|
AddonModForumComponentsModule,
|
||||||
|
CoreEditorComponentsModule,
|
||||||
|
],
|
||||||
|
declarations: [
|
||||||
|
AddonModForumNewDiscussionPage,
|
||||||
|
],
|
||||||
|
})
|
||||||
|
export class AddonForumNewDiscussionPageModule {}
|
|
@ -37,6 +37,8 @@ import { AddonModForumHelper } from '@addons/mod/forum/services/helper.service';
|
||||||
import { IonRefresher } from '@ionic/angular';
|
import { IonRefresher } from '@ionic/angular';
|
||||||
import { CoreFileUploader } from '@features/fileuploader/services/fileuploader';
|
import { CoreFileUploader } from '@features/fileuploader/services/fileuploader';
|
||||||
import { CoreTextUtils } from '@services/utils/text';
|
import { CoreTextUtils } from '@services/utils/text';
|
||||||
|
import { CanLeave } from '@guards/can-leave';
|
||||||
|
import { CoreScreen } from '@services/screen';
|
||||||
|
|
||||||
type NewDiscussionData = {
|
type NewDiscussionData = {
|
||||||
subject: string;
|
subject: string;
|
||||||
|
@ -55,7 +57,7 @@ type NewDiscussionData = {
|
||||||
selector: 'page-addon-mod-forum-new-discussion',
|
selector: 'page-addon-mod-forum-new-discussion',
|
||||||
templateUrl: 'new-discussion.html',
|
templateUrl: 'new-discussion.html',
|
||||||
})
|
})
|
||||||
export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy {
|
export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy, CanLeave {
|
||||||
|
|
||||||
@ViewChild('newDiscFormEl') formElement!: ElementRef;
|
@ViewChild('newDiscFormEl') formElement!: ElementRef;
|
||||||
@ViewChild(CoreEditorRichTextEditorComponent) messageEditor!: CoreEditorRichTextEditorComponent;
|
@ViewChild(CoreEditorRichTextEditorComponent) messageEditor!: CoreEditorRichTextEditorComponent;
|
||||||
|
@ -124,12 +126,6 @@ export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy {
|
||||||
this.returnToDiscussions();
|
this.returnToDiscussions();
|
||||||
}
|
}
|
||||||
}, CoreSites.instance.getCurrentSiteId());
|
}, CoreSites.instance.getCurrentSiteId());
|
||||||
|
|
||||||
// Trigger view event, to highlight the current opened discussion in the split view.
|
|
||||||
CoreEvents.trigger(AddonModForumProvider.VIEW_DISCUSSION_EVENT, {
|
|
||||||
forumId: this.forumId,
|
|
||||||
discussion: -this.timeCreated,
|
|
||||||
}, CoreSites.instance.getCurrentSiteId());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -421,16 +417,34 @@ export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy {
|
||||||
* @param discTimecreated The time created of the discussion (if offline).
|
* @param discTimecreated The time created of the discussion (if offline).
|
||||||
*/
|
*/
|
||||||
protected returnToDiscussions(discussionIds?: number[] | null, discTimecreated?: number): void {
|
protected returnToDiscussions(discussionIds?: number[] | null, discTimecreated?: number): void {
|
||||||
const data: any = {
|
this.forceLeave = true;
|
||||||
forumId: this.forumId,
|
|
||||||
cmId: this.cmId,
|
|
||||||
discussionIds: discussionIds,
|
|
||||||
discTimecreated: discTimecreated,
|
|
||||||
};
|
|
||||||
CoreEvents.trigger(AddonModForumProvider.NEW_DISCUSSION_EVENT, data, CoreSites.instance.getCurrentSiteId());
|
|
||||||
|
|
||||||
// Delete the local files from the tmp folder.
|
// Delete the local files from the tmp folder.
|
||||||
CoreFileUploader.instance.clearTmpFiles(this.newDiscussion.files);
|
CoreFileUploader.instance.clearTmpFiles(this.newDiscussion.files);
|
||||||
|
|
||||||
|
CoreEvents.trigger(
|
||||||
|
AddonModForumProvider.NEW_DISCUSSION_EVENT,
|
||||||
|
{
|
||||||
|
forumId: this.forumId,
|
||||||
|
cmId: this.cmId,
|
||||||
|
discussionIds: discussionIds,
|
||||||
|
discTimecreated: discTimecreated,
|
||||||
|
},
|
||||||
|
CoreSites.instance.getCurrentSiteId(),
|
||||||
|
);
|
||||||
|
|
||||||
|
if (CoreScreen.instance.isMobile) {
|
||||||
|
CoreNavigator.instance.back();
|
||||||
|
} else {
|
||||||
|
// Empty form.
|
||||||
|
this.hasOffline = false;
|
||||||
|
this.newDiscussion.subject = '';
|
||||||
|
this.newDiscussion.message = null;
|
||||||
|
this.newDiscussion.files = [];
|
||||||
|
this.newDiscussion.postToAllGroups = false;
|
||||||
|
this.messageEditor.clearText();
|
||||||
|
this.originalData = CoreUtils.instance.clone(this.newDiscussion);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -555,9 +569,9 @@ export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy {
|
||||||
*
|
*
|
||||||
* @return Resolved if we can leave it, rejected if not.
|
* @return Resolved if we can leave it, rejected if not.
|
||||||
*/
|
*/
|
||||||
async ionViewCanLeave(): Promise<void> {
|
async canLeave(): Promise<boolean> {
|
||||||
if (this.forceLeave) {
|
if (this.forceLeave) {
|
||||||
return;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (AddonModForumHelper.instance.hasPostDataChanged(this.newDiscussion, this.originalData)) {
|
if (AddonModForumHelper.instance.hasPostDataChanged(this.newDiscussion, this.originalData)) {
|
||||||
|
@ -571,6 +585,8 @@ export class AddonModForumNewDiscussionPage implements OnInit, OnDestroy {
|
||||||
if (this.formElement) {
|
if (this.formElement) {
|
||||||
CoreDomUtils.instance.triggerFormCancelledEvent(this.formElement, CoreSites.instance.getCurrentSiteId());
|
CoreDomUtils.instance.triggerFormCancelledEvent(this.formElement, CoreSites.instance.getCurrentSiteId());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
|
@ -42,7 +42,6 @@ export class AddonModForumProvider {
|
||||||
static readonly DISCUSSIONS_PER_PAGE = 10; // Max of discussions per page.
|
static readonly DISCUSSIONS_PER_PAGE = 10; // Max of discussions per page.
|
||||||
static readonly NEW_DISCUSSION_EVENT = 'addon_mod_forum_new_discussion';
|
static readonly NEW_DISCUSSION_EVENT = 'addon_mod_forum_new_discussion';
|
||||||
static readonly REPLY_DISCUSSION_EVENT = 'addon_mod_forum_reply_discussion';
|
static readonly REPLY_DISCUSSION_EVENT = 'addon_mod_forum_reply_discussion';
|
||||||
static readonly VIEW_DISCUSSION_EVENT = 'addon_mod_forum_view_discussion';
|
|
||||||
static readonly CHANGE_DISCUSSION_EVENT = 'addon_mod_forum_change_discussion_status';
|
static readonly CHANGE_DISCUSSION_EVENT = 'addon_mod_forum_change_discussion_status';
|
||||||
static readonly MARK_READ_EVENT = 'addon_mod_forum_mark_read';
|
static readonly MARK_READ_EVENT = 'addon_mod_forum_mark_read';
|
||||||
static readonly LEAVING_POSTS_PAGE = 'addon_mod_forum_leaving_posts_page';
|
static readonly LEAVING_POSTS_PAGE = 'addon_mod_forum_leaving_posts_page';
|
||||||
|
|
Loading…
Reference in New Issue