MOBILE-3745 core: Use new openModal function

main
Pau Ferrer Ocaña 2021-05-04 15:26:06 +02:00
parent fa22325fb4
commit 7af5c510bf
36 changed files with 211 additions and 276 deletions

View File

@ -39,7 +39,7 @@ import { Md5 } from 'ts-md5/dist/md5';
import moment from 'moment'; import moment from 'moment';
import { CoreAnimations } from '@components/animations'; import { CoreAnimations } from '@components/animations';
import { CoreError } from '@classes/errors/error'; import { CoreError } from '@classes/errors/error';
import { ModalController, Translate } from '@singletons'; import { Translate } from '@singletons';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreIonLoadingElement } from '@classes/ion-loading'; import { CoreIonLoadingElement } from '@classes/ion-loading';
import { ActivatedRoute } from '@angular/router'; import { ActivatedRoute } from '@angular/router';
@ -1302,18 +1302,14 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
async viewInfo(): Promise<void> { async viewInfo(): Promise<void> {
if (this.isGroup) { if (this.isGroup) {
// Display the group information. // Display the group information.
const modal = await ModalController.create({ const userId = await CoreDomUtils.openModal<number>({
component: AddonMessagesConversationInfoComponent, component: AddonMessagesConversationInfoComponent,
componentProps: { componentProps: {
conversationId: this.conversationId, conversationId: this.conversationId,
}, },
}); });
await modal.present(); if (typeof userId != 'undefined') {
const result = await modal.onDidDismiss();
if (typeof result.data != 'undefined') {
const splitViewLoaded = CoreNavigator.isCurrentPathInTablet('**/messages/**/discussion'); const splitViewLoaded = CoreNavigator.isCurrentPathInTablet('**/messages/**/discussion');
// Open user conversation. // Open user conversation.
@ -1321,12 +1317,12 @@ export class AddonMessagesDiscussionPage implements OnInit, OnDestroy, AfterView
// Notify the left pane to load it, this way the right conversation will be highlighted. // Notify the left pane to load it, this way the right conversation will be highlighted.
CoreEvents.trigger( CoreEvents.trigger(
AddonMessagesProvider.OPEN_CONVERSATION_EVENT, AddonMessagesProvider.OPEN_CONVERSATION_EVENT,
{ userId: result.data }, { userId },
this.siteId, this.siteId,
); );
} else { } else {
// Open the discussion in a new view. // Open the discussion in a new view.
CoreNavigator.navigateToSitePath('/messages/discussion', { params: { userId: result.data.userId } }); CoreNavigator.navigateToSitePath('/messages/discussion', { params: { userId } });
} }
} }
} else { } else {

View File

@ -15,7 +15,7 @@
import { Component, Input } from '@angular/core'; import { Component, Input } from '@angular/core';
import { CoreCanceledError } from '@classes/errors/cancelederror'; import { CoreCanceledError } from '@classes/errors/cancelederror';
import { CoreError } from '@classes/errors/error'; import { CoreError } from '@classes/errors/error';
import { ModalController } from '@singletons'; import { CoreDomUtils } from '@services/utils/dom';
import { AddonModAssignEditFeedbackModalComponent } from '../components/edit-feedback-modal/edit-feedback-modal'; import { AddonModAssignEditFeedbackModalComponent } from '../components/edit-feedback-modal/edit-feedback-modal';
import { AddonModAssignFeedbackCommentsTextData } from '../feedback/comments/services/handler'; import { AddonModAssignFeedbackCommentsTextData } from '../feedback/comments/services/handler';
import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '../services/assign'; import { AddonModAssignAssign, AddonModAssignPlugin, AddonModAssignSubmission } from '../services/assign';
@ -47,7 +47,7 @@ export class AddonModAssignFeedbackPluginBaseComponent {
} }
// Create the navigation modal. // Create the navigation modal.
const modal = await ModalController.create({ const modalData = await CoreDomUtils.openModal<AddonModAssignFeedbackCommentsTextData>({
component: AddonModAssignEditFeedbackModalComponent, component: AddonModAssignEditFeedbackModalComponent,
componentProps: { componentProps: {
assign: this.assign, assign: this.assign,
@ -57,15 +57,11 @@ export class AddonModAssignFeedbackPluginBaseComponent {
}, },
}); });
await modal.present(); if (typeof modalData == 'undefined') {
const result = await modal.onDidDismiss();
if (typeof result.data == 'undefined') {
throw new CoreCanceledError(); // User cancelled. throw new CoreCanceledError(); // User cancelled.
} else {
return result.data;
} }
return modalData;
} }
/** /**

View File

@ -28,7 +28,7 @@ import {
import { CoreTag, CoreTagItem } from '@features/tag/services/tag'; import { CoreTag, CoreTagItem } from '@features/tag/services/tag';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreCourseContentsPage } from '@features/course/pages/contents/contents'; import { CoreCourseContentsPage } from '@features/course/pages/contents/contents';
import { ModalController, Translate } from '@singletons'; import { Translate } from '@singletons';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { CoreCourse } from '@features/course/services/course'; import { CoreCourse } from '@features/course/services/course';
import { AddonModBookTocComponent } from '../toc/toc'; import { AddonModBookTocComponent } from '../toc/toc';
@ -84,7 +84,7 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp
*/ */
async showToc(): Promise<void> { async showToc(): Promise<void> {
// Create the toc modal. // Create the toc modal.
const modal = await ModalController.create({ const modalData = await CoreDomUtils.openSideModal<number>({
component: AddonModBookTocComponent, component: AddonModBookTocComponent,
componentProps: { componentProps: {
moduleId: this.module.id, moduleId: this.module.id,
@ -93,19 +93,10 @@ export class AddonModBookIndexComponent extends CoreCourseModuleMainResourceComp
courseId: this.courseId, courseId: this.courseId,
book: this.book, book: this.book,
}, },
cssClass: 'core-modal-lateral',
showBackdrop: true,
backdropDismiss: true,
// @todo enterAnimation: 'core-modal-lateral-transition',
// @todo leaveAnimation: 'core-modal-lateral-transition',
}); });
await modal.present(); if (modalData) {
this.changeChapter(modalData);
const result = await modal.onDidDismiss();
if (result.data) {
this.changeChapter(result.data);
} }
} }

View File

@ -21,7 +21,7 @@ import { CoreNavigator } from '@services/navigator';
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';
import { ModalController, Network, NgZone } from '@singletons'; import { Network, NgZone } from '@singletons';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { AddonModChatUsersModalComponent, AddonModChatUsersModalResult } from '../../components/users-modal/users-modal'; import { AddonModChatUsersModalComponent, AddonModChatUsersModalResult } from '../../components/users-modal/users-modal';
@ -178,32 +178,23 @@ export class AddonModChatChatPage implements OnInit, OnDestroy {
*/ */
async showChatUsers(): Promise<void> { async showChatUsers(): Promise<void> {
// Create the toc modal. // Create the toc modal.
const modal = await ModalController.create({ const modalData = await CoreDomUtils.openSideModal<AddonModChatUsersModalResult>({
component: AddonModChatUsersModalComponent, component: AddonModChatUsersModalComponent,
componentProps: { componentProps: {
sessionId: this.sessionId, sessionId: this.sessionId,
cmId: this.cmId, cmId: this.cmId,
}, },
cssClass: 'core-modal-lateral',
showBackdrop: true,
backdropDismiss: true,
// @todo enterAnimation: 'core-modal-lateral-transition',
// @todo leaveAnimation: 'core-modal-lateral-transition',
}); });
await modal.present(); if (modalData) {
if (modalData.talkTo) {
const result = await modal.onDidDismiss<AddonModChatUsersModalResult>(); this.newMessage = `To ${modalData.talkTo}: ` + (this.sendMessageForm?.message || '');
if (result.data) {
if (result.data.talkTo) {
this.newMessage = `To ${result.data.talkTo}: ` + (this.sendMessageForm?.message || '');
} }
if (result.data.beepTo) { if (modalData.beepTo) {
this.sendMessage('', result.data.beepTo); this.sendMessage('', modalData.beepTo);
} }
this.users = result.data.users; this.users = modalData.users;
} }
} }

View File

@ -29,7 +29,6 @@ import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { ModalController } from '@singletons';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { import {
AddonModDataProvider, AddonModDataProvider,
@ -376,7 +375,7 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
* Display the chat users modal. * Display the chat users modal.
*/ */
async showSearch(): Promise<void> { async showSearch(): Promise<void> {
const modal = await ModalController.create({ const modalData = await CoreDomUtils.openModal<AddonModDataSearchDataParams>({
component: AddonModDataSearchComponent, component: AddonModDataSearchComponent,
componentProps: { componentProps: {
search: this.search, search: this.search,
@ -385,12 +384,9 @@ export class AddonModDataIndexComponent extends CoreCourseModuleMainActivityComp
}, },
}); });
await modal.present();
const result = await modal.onDidDismiss();
// Add data to search object. // Add data to search object.
if (result.data) { if (modalData) {
this.search = result.data; this.search = modalData;
this.searchEntries(0); this.searchEntries(0);
} }
} }

View File

@ -40,7 +40,7 @@ import {
AddonModForumUpdateDiscussionPostWSOptionsObject, AddonModForumUpdateDiscussionPostWSOptionsObject,
} from '../../services/forum'; } from '../../services/forum';
import { CoreTag } from '@features/tag/services/tag'; import { CoreTag } from '@features/tag/services/tag';
import { ModalController, PopoverController, Translate } from '@singletons'; import { PopoverController, Translate } from '@singletons';
import { CoreFileUploader } from '@features/fileuploader/services/fileuploader'; import { CoreFileUploader } from '@features/fileuploader/services/fileuploader';
import { IonContent } from '@ionic/angular'; import { IonContent } from '@ionic/angular';
import { AddonModForumSync } from '../../services/forum-sync'; import { AddonModForumSync } from '../../services/forum-sync';
@ -254,7 +254,7 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges
* Shows a form modal to edit an online post. * Shows a form modal to edit an online post.
*/ */
async editPost(): Promise<void> { async editPost(): Promise<void> {
const modal = await ModalController.create({ const modalData = await CoreDomUtils.openModal<AddonModForumReply>({
component: AddonModForumEditPostComponent, component: AddonModForumEditPostComponent,
componentProps: { componentProps: {
post: this.post, post: this.post,
@ -265,18 +265,13 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges
backdropDismiss: false, backdropDismiss: false,
}); });
await modal.present(); if (!modalData) {
const result = await modal.onDidDismiss<AddonModForumReply>();
const data = result.data;
if (!data) {
return; return;
} }
// Add some HTML to the message if needed. // Add some HTML to the message if needed.
const message = CoreTextUtils.formatHtmlLines(data.message!); const message = CoreTextUtils.formatHtmlLines(modalData.message!);
const files = data.files; const files = modalData.files;
const options: AddonModForumUpdateDiscussionPostWSOptionsObject = {}; const options: AddonModForumUpdateDiscussionPostWSOptionsObject = {};
const sendingModal = await CoreDomUtils.showModalLoading('core.sending', true); const sendingModal = await CoreDomUtils.showModalLoading('core.sending', true);
@ -295,16 +290,16 @@ export class AddonModForumPostComponent implements OnInit, OnDestroy, OnChanges
} }
// Try to send it to server. // Try to send it to server.
const sent = await AddonModForum.updatePost(this.post.id, data.subject!, message, options); const sent = await AddonModForum.updatePost(this.post.id, modalData.subject!, message, options);
if (sent && this.forum.id) { if (sent && this.forum.id) {
// Data sent to server, delete stored files (if any). // Data sent to server, delete stored files (if any).
AddonModForumHelper.deleteReplyStoredFiles(this.forum.id, this.post.id); AddonModForumHelper.deleteReplyStoredFiles(this.forum.id, this.post.id);
this.onPostChange.emit(); this.onPostChange.emit();
this.post.subject = data.subject!; this.post.subject = modalData.subject!;
this.post.message = message; this.post.message = message;
this.post.attachments = data.files; this.post.attachments = modalData.files;
} }
} catch (error) { } catch (error) {
CoreDomUtils.showErrorModalDefault(error, 'addon.mod_forum.couldnotupdate', true); CoreDomUtils.showErrorModalDefault(error, 'addon.mod_forum.couldnotupdate', true);

View File

@ -21,7 +21,6 @@ import {
import { CoreCourseContentsPage } from '@features/course/pages/contents/contents'; import { CoreCourseContentsPage } from '@features/course/pages/contents/contents';
import { CoreCourse } from '@features/course/services/course'; import { CoreCourse } from '@features/course/services/course';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { ModalController } from '@singletons';
import { AddonModImscpProvider, AddonModImscp, AddonModImscpTocItem } from '../../services/imscp'; import { AddonModImscpProvider, AddonModImscp, AddonModImscpTocItem } from '../../services/imscp';
import { AddonModImscpTocComponent } from '../toc/toc'; import { AddonModImscpTocComponent } from '../toc/toc';
@ -150,25 +149,16 @@ export class AddonModImscpIndexComponent extends CoreCourseModuleMainResourceCom
*/ */
async showToc(): Promise<void> { async showToc(): Promise<void> {
// Create the toc modal. // Create the toc modal.
const modal = await ModalController.create({ const modalData = await CoreDomUtils.openSideModal<string>({
component: AddonModImscpTocComponent, component: AddonModImscpTocComponent,
componentProps: { componentProps: {
items: this.items, items: this.items,
selected: this.currentItem, selected: this.currentItem,
}, },
cssClass: 'core-modal-lateral',
showBackdrop: true,
backdropDismiss: true,
// @todo enterAnimation: 'core-modal-lateral-transition',
// @todo leaveAnimation: 'core-modal-lateral-transition',
}); });
await modal.present(); if (modalData) {
this.loadItem(modalData);
const result = await modal.onDidDismiss();
if (result.data) {
this.loadItem(result.data);
} }
} }

View File

@ -762,22 +762,13 @@ export class AddonModLessonPlayerPage implements OnInit, OnDestroy, CanLeave {
async showMenu(): Promise<void> { async showMenu(): Promise<void> {
this.menuShown = true; this.menuShown = true;
const menuModal = await ModalController.create({ await CoreDomUtils.openSideModal({
component: AddonModLessonMenuModalPage, component: AddonModLessonMenuModalPage,
componentProps: { componentProps: {
pageInstance: this, pageInstance: this,
}, },
cssClass: 'core-modal-lateral',
showBackdrop: true,
backdropDismiss: true,
// @todo enterAnimation: 'core-modal-lateral-transition',
// leaveAnimation: 'core-modal-lateral-transition',
}); });
await menuModal.present();
await menuModal.onWillDismiss();
this.menuShown = false; this.menuShown = false;
} }

View File

@ -22,9 +22,10 @@ import { CoreFilepool } from '@services/filepool';
import { CoreGroups } from '@services/groups'; import { CoreGroups } from '@services/groups';
import { CoreFileSizeSum, CorePluginFileDelegate } from '@services/plugin-file-delegate'; import { CoreFileSizeSum, CorePluginFileDelegate } from '@services/plugin-file-delegate';
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreSites, CoreSitesReadingStrategy } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { CoreWSFile } from '@services/ws'; import { CoreWSFile } from '@services/ws';
import { makeSingleton, ModalController, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { AddonModLessonPasswordModalComponent } from '../../components/password-modal/password-modal'; import { AddonModLessonPasswordModalComponent } from '../../components/password-modal/password-modal';
import { import {
AddonModLesson, AddonModLesson,
@ -54,19 +55,15 @@ export class AddonModLessonPrefetchHandlerService extends CoreCourseActivityPref
*/ */
protected async askUserPassword(): Promise<string> { protected async askUserPassword(): Promise<string> {
// Create and show the modal. // Create and show the modal.
const modal = await ModalController.create({ const modalData = await CoreDomUtils.openModal<string>({
component: AddonModLessonPasswordModalComponent, component: AddonModLessonPasswordModalComponent,
}); });
await modal.present(); if (typeof modalData != 'string') {
const result = await modal.onWillDismiss();
if (typeof result.data != 'string') {
throw new CoreCanceledError(); throw new CoreCanceledError();
} }
return result.data; return modalData;
} }
/** /**

View File

@ -50,7 +50,7 @@ export class AddonModQuizNavigationModalComponent {
* @param slot Slot of the question to scroll to. * @param slot Slot of the question to scroll to.
*/ */
loadPage(page: number, slot?: number): void { loadPage(page: number, slot?: number): void {
ModalController.dismiss({ ModalController.dismiss(<AddonModQuizNavigationModalReturn>{
action: AddonModQuizNavigationModalComponent.CHANGE_PAGE, action: AddonModQuizNavigationModalComponent.CHANGE_PAGE,
page, page,
slot, slot,
@ -61,7 +61,7 @@ export class AddonModQuizNavigationModalComponent {
* Switch mode in review. * Switch mode in review.
*/ */
switchMode(): void { switchMode(): void {
ModalController.dismiss({ ModalController.dismiss(<AddonModQuizNavigationModalReturn>{
action: AddonModQuizNavigationModalComponent.SWITCH_MODE, action: AddonModQuizNavigationModalComponent.SWITCH_MODE,
}); });
} }
@ -74,3 +74,9 @@ export class AddonModQuizNavigationModalComponent {
export type AddonModQuizNavigationQuestion = CoreQuestionQuestionParsed & { export type AddonModQuizNavigationQuestion = CoreQuestionQuestionParsed & {
stateClass?: string; stateClass?: string;
}; };
export type AddonModQuizNavigationModalReturn = {
action: number;
page?: number;
slot?: number;
};

View File

@ -31,6 +31,7 @@ import { CoreEvents } from '@singletons/events';
import { AddonModQuizAutoSave } from '../../classes/auto-save'; import { AddonModQuizAutoSave } from '../../classes/auto-save';
import { import {
AddonModQuizNavigationModalComponent, AddonModQuizNavigationModalComponent,
AddonModQuizNavigationModalReturn,
AddonModQuizNavigationQuestion, AddonModQuizNavigationQuestion,
} from '../../components/navigation-modal/navigation-modal'; } from '../../components/navigation-modal/navigation-modal';
import { import {
@ -581,7 +582,7 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave {
} }
// Create the navigation modal. // Create the navigation modal.
const modal = await ModalController.create({ const modalData = await CoreDomUtils.openSideModal<AddonModQuizNavigationModalReturn>({
component: AddonModQuizNavigationModalComponent, component: AddonModQuizNavigationModalComponent,
componentProps: { componentProps: {
navigation: this.navigation, navigation: this.navigation,
@ -589,19 +590,10 @@ export class AddonModQuizPlayerPage implements OnInit, OnDestroy, CanLeave {
currentPage: this.attempt?.currentpage, currentPage: this.attempt?.currentpage,
isReview: false, isReview: false,
}, },
cssClass: 'core-modal-lateral',
showBackdrop: true,
backdropDismiss: true,
// @todo enterAnimation: 'core-modal-lateral-transition',
// @todo leaveAnimation: 'core-modal-lateral-transition',
}); });
await modal.present(); if (modalData && modalData.action == AddonModQuizNavigationModalComponent.CHANGE_PAGE) {
this.changePage(modalData.page!, true, modalData.slot);
const result = await modal.onWillDismiss();
if (result.data && result.data.action == AddonModQuizNavigationModalComponent.CHANGE_PAGE) {
this.changePage(result.data.page, true, result.data.slot);
} }
} }

View File

@ -21,9 +21,10 @@ import { CoreDomUtils } from '@services/utils/dom';
import { CoreTextUtils } from '@services/utils/text'; import { CoreTextUtils } from '@services/utils/text';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { ModalController, Translate } from '@singletons'; import { Translate } from '@singletons';
import { import {
AddonModQuizNavigationModalComponent, AddonModQuizNavigationModalComponent,
AddonModQuizNavigationModalReturn,
AddonModQuizNavigationQuestion, AddonModQuizNavigationQuestion,
} from '../../components/navigation-modal/navigation-modal'; } from '../../components/navigation-modal/navigation-modal';
import { import {
@ -325,7 +326,7 @@ export class AddonModQuizReviewPage implements OnInit {
async openNavigation(): Promise<void> { async openNavigation(): Promise<void> {
// Create the navigation modal. // Create the navigation modal.
const modal = await ModalController.create({ const modalData = await CoreDomUtils.openSideModal<AddonModQuizNavigationModalReturn>({
component: AddonModQuizNavigationModalComponent, component: AddonModQuizNavigationModalComponent,
componentProps: { componentProps: {
navigation: this.navigation, navigation: this.navigation,
@ -335,24 +336,15 @@ export class AddonModQuizReviewPage implements OnInit {
numPages: this.numPages, numPages: this.numPages,
showAll: this.showAll, showAll: this.showAll,
}, },
cssClass: 'core-modal-lateral',
showBackdrop: true,
backdropDismiss: true,
// @todo enterAnimation: 'core-modal-lateral-transition',
// @todo leaveAnimation: 'core-modal-lateral-transition',
}); });
await modal.present(); if (!modalData) {
const result = await modal.onWillDismiss();
if (!result.data) {
return; return;
} }
if (result.data.action == AddonModQuizNavigationModalComponent.CHANGE_PAGE) { if (modalData.action == AddonModQuizNavigationModalComponent.CHANGE_PAGE) {
this.changePage(result.data.page, true, result.data.slot); this.changePage(modalData.page!, true, modalData.slot);
} else if (result.data.action == AddonModQuizNavigationModalComponent.SWITCH_MODE) { } else if (modalData.action == AddonModQuizNavigationModalComponent.SWITCH_MODE) {
this.switchMode(); this.switchMode();
} }
} }

View File

@ -21,7 +21,7 @@ import { CoreNavigator } from '@services/navigator';
import { CoreSites, CoreSitesReadingStrategy } from '@services/sites'; import { CoreSites, CoreSitesReadingStrategy } 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';
import { makeSingleton, ModalController, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { AddonModQuizPreflightModalComponent } from '../components/preflight-modal/preflight-modal'; import { AddonModQuizPreflightModalComponent } from '../components/preflight-modal/preflight-modal';
import { AddonModQuizAccessRuleDelegate } from './access-rules-delegate'; import { AddonModQuizAccessRuleDelegate } from './access-rules-delegate';
import { AddonModQuizModuleHandlerService } from './handlers/module'; import { AddonModQuizModuleHandlerService } from './handlers/module';
@ -160,7 +160,7 @@ export class AddonModQuizHelperProvider {
} }
// Create and show the modal. // Create and show the modal.
const modal = await ModalController.create({ const modalData = await CoreDomUtils.openModal<Record<string, string>>({
component: AddonModQuizPreflightModalComponent, component: AddonModQuizPreflightModalComponent,
componentProps: { componentProps: {
title: title, title: title,
@ -172,15 +172,11 @@ export class AddonModQuizHelperProvider {
}, },
}); });
await modal.present(); if (!modalData) {
const result = await modal.onWillDismiss();
if (!result.data) {
throw new CoreCanceledError(); throw new CoreCanceledError();
} }
return <Record<string, string>> result.data; return modalData;
} }
/** /**

View File

@ -20,7 +20,6 @@ import { CoreSync } from '@services/sync';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { ModalController } from '@singletons';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { AddonModScormDataModel12 } from '../../classes/data-model-12'; import { AddonModScormDataModel12 } from '../../classes/data-model-12';
import { AddonModScormTocComponent } from '../../components/toc/toc'; import { AddonModScormTocComponent } from '../../components/toc/toc';
@ -486,7 +485,7 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
* Show the TOC. * Show the TOC.
*/ */
async openToc(): Promise<void> { async openToc(): Promise<void> {
const modal = await ModalController.create({ const modalData = await CoreDomUtils.openSideModal<AddonModScormScoWithData>({
component: AddonModScormTocComponent, component: AddonModScormTocComponent,
componentProps: { componentProps: {
toc: this.toc, toc: this.toc,
@ -497,19 +496,10 @@ export class AddonModScormPlayerPage implements OnInit, OnDestroy {
accessInfo: this.accessInfo, accessInfo: this.accessInfo,
mode: this.mode, mode: this.mode,
}, },
cssClass: 'core-modal-lateral',
showBackdrop: true,
backdropDismiss: true,
// @todo enterAnimation: 'core-modal-lateral-transition',
// leaveAnimation: 'core-modal-lateral-transition'
}); });
await modal.present(); if (modalData) {
this.loadSco(modalData);
const result = await modal.onDidDismiss();
if (result.data) {
this.loadSco(result.data);
} }
} }

View File

@ -27,7 +27,7 @@ import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreTextUtils } from '@services/utils/text'; import { CoreTextUtils } from '@services/utils/text';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { ModalController, PopoverController, Translate } from '@singletons'; import { PopoverController, Translate } from '@singletons';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { Md5 } from 'ts-md5'; import { Md5 } from 'ts-md5';
import { AddonModWikiPageDBRecord } from '../../services/database/wiki'; import { AddonModWikiPageDBRecord } from '../../services/database/wiki';
@ -51,7 +51,7 @@ import {
AddonModWikiSyncWikiResult, AddonModWikiSyncWikiResult,
AddonModWikiSyncWikiSubwiki, AddonModWikiSyncWikiSubwiki,
} from '../../services/wiki-sync'; } from '../../services/wiki-sync';
import { AddonModWikiMapModalComponent } from '../map/map'; import { AddonModWikiMapModalComponent, AddonModWikiMapModalReturn } from '../map/map';
import { AddonModWikiSubwikiPickerComponent } from '../subwiki-picker/subwiki-picker'; import { AddonModWikiSubwikiPickerComponent } from '../subwiki-picker/subwiki-picker';
/** /**
@ -576,7 +576,7 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp
*/ */
async openMap(): Promise<void> { async openMap(): Promise<void> {
// Create the toc modal. // Create the toc modal.
const modal = await ModalController.create({ const modalData = await CoreDomUtils.openSideModal<AddonModWikiMapModalReturn>({
component: AddonModWikiMapModalComponent, component: AddonModWikiMapModalComponent,
componentProps: { componentProps: {
pages: this.subwikiPages, pages: this.subwikiPages,
@ -585,23 +585,14 @@ export class AddonModWikiIndexComponent extends CoreCourseModuleMainActivityComp
courseId: this.courseId, courseId: this.courseId,
selectedTitle: this.currentPageObj && this.currentPageObj.title, selectedTitle: this.currentPageObj && this.currentPageObj.title,
}, },
cssClass: 'core-modal-lateral',
showBackdrop: true,
backdropDismiss: true,
// @todo enterAnimation: 'core-modal-lateral-transition',
// @todo leaveAnimation: 'core-modal-lateral-transition',
}); });
await modal.present(); if (modalData) {
if (modalData.home) {
const result = await modal.onDidDismiss();
if (result.data) {
if (result.data.type == 'home') {
// Go back to the initial page of the wiki. // Go back to the initial page of the wiki.
CoreNavigator.navigateToSitePath(result.data.goto); CoreNavigator.navigateToSitePath(modalData.home);
} else { } else if (modalData.page) {
this.goToPage(result.data.goto); this.goToPage(modalData.page);
} }
} }

View File

@ -47,14 +47,14 @@ export class AddonModWikiMapModalComponent implements OnInit {
* @param page Clicked page. * @param page Clicked page.
*/ */
goToPage(page: AddonModWikiSubwikiPage | AddonModWikiPageDBRecord): void { goToPage(page: AddonModWikiSubwikiPage | AddonModWikiPageDBRecord): void {
ModalController.dismiss({ type: 'page', goto: page }); ModalController.dismiss(<AddonModWikiMapModalReturn>{ page });
} }
/** /**
* Go back to the initial page of the wiki. * Go back to the initial page of the wiki.
*/ */
goToWikiHome(): void { goToWikiHome(): void {
ModalController.dismiss({ type: 'home', goto: this.homeView }); ModalController.dismiss(<AddonModWikiMapModalReturn>{ home: this.homeView });
} }
/** /**
@ -103,3 +103,8 @@ type AddonModWikiPagesMapLetter = {
label: string; label: string;
pages: (AddonModWikiSubwikiPage | AddonModWikiPageDBRecord)[]; pages: (AddonModWikiSubwikiPage | AddonModWikiPageDBRecord)[];
}; };
export type AddonModWikiMapModalReturn = {
page?: AddonModWikiSubwikiPage | AddonModWikiPageDBRecord;
home?: string;
};

View File

@ -20,8 +20,9 @@ import { CoreCourse } from '@features/course/services/course';
import { IonContent } from '@ionic/angular'; import { IonContent } from '@ionic/angular';
import { CoreGroupInfo, CoreGroups } from '@services/groups'; import { CoreGroupInfo, CoreGroups } from '@services/groups';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { ModalController, Platform } from '@singletons'; import { Platform } from '@singletons';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { Subscription } from 'rxjs'; import { Subscription } from 'rxjs';
import { AddonModWorkshopModuleHandlerService } from '../../services/handlers/module'; import { AddonModWorkshopModuleHandlerService } from '../../services/handlers/module';
@ -387,7 +388,7 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
*/ */
async viewPhaseInfo(): Promise<void> { async viewPhaseInfo(): Promise<void> {
if (this.phases) { if (this.phases) {
const modal = await ModalController.create({ const modalData = await CoreDomUtils.openModal<boolean>({
component: AddonModWorkshopPhaseInfoComponent, component: AddonModWorkshopPhaseInfoComponent,
componentProps: { componentProps: {
phases: CoreUtils.objectToArray(this.phases), phases: CoreUtils.objectToArray(this.phases),
@ -396,10 +397,8 @@ export class AddonModWorkshopIndexComponent extends CoreCourseModuleMainActivity
showSubmit: this.showSubmit, showSubmit: this.showSubmit,
}, },
}); });
await modal.present();
const result = await modal.onDidDismiss(); if (modalData === true) {
if (result.data === true) {
this.gotoSubmit(); this.gotoSubmit();
} }
} }

View File

@ -12,7 +12,7 @@
// See the License for the specific language governing permissions and // See the License for the specific language governing permissions and
// limitations under the License. // limitations under the License.
import { AddonNotes } from '@addons/notes/services/notes'; import { AddonNotes, AddonNotesPublishState } from '@addons/notes/services/notes';
import { Component, ViewChild, ElementRef, Input } from '@angular/core'; import { Component, ViewChild, ElementRef, Input } from '@angular/core';
import { CoreApp } from '@services/app'; import { CoreApp } from '@services/app';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
@ -32,7 +32,7 @@ export class AddonNotesAddComponent {
@Input() protected courseId!: number; @Input() protected courseId!: number;
@Input() protected userId?: number; @Input() protected userId?: number;
@Input() type = 'personal'; @Input() type: AddonNotesPublishState = 'personal';
text = ''; text = '';
processing = false; processing = false;
@ -56,7 +56,7 @@ export class AddonNotesAddComponent {
CoreForms.triggerFormSubmittedEvent(this.formElement, sent, CoreSites.getCurrentSiteId()); CoreForms.triggerFormSubmittedEvent(this.formElement, sent, CoreSites.getCurrentSiteId());
ModalController.dismiss({ type: this.type, sent: true }).finally(() => { ModalController.dismiss(<AddonNotesAddModalReturn>{ type: this.type, sent: true }).finally(() => {
CoreDomUtils.showToast(sent ? 'addon.notes.eventnotecreated' : 'core.datastoredoffline', true, 3000); CoreDomUtils.showToast(sent ? 'addon.notes.eventnotecreated' : 'core.datastoredoffline', true, 3000);
}); });
} catch (error){ } catch (error){
@ -73,7 +73,12 @@ export class AddonNotesAddComponent {
closeModal(): void { closeModal(): void {
CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId());
ModalController.dismiss({ type: this.type }); ModalController.dismiss(<AddonNotesAddModalReturn>{ type: this.type });
} }
} }
export type AddonNotesAddModalReturn = {
type: AddonNotesPublishState;
sent?: boolean;
};

View File

@ -13,8 +13,8 @@
// limitations under the License. // limitations under the License.
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { AddonNotesAddComponent } from '@addons/notes/components/add/add-modal'; import { AddonNotesAddComponent, AddonNotesAddModalReturn } from '@addons/notes/components/add/add-modal';
import { AddonNotes, AddonNotesNoteFormatted } from '@addons/notes/services/notes'; import { AddonNotes, AddonNotesNoteFormatted, AddonNotesPublishState } from '@addons/notes/services/notes';
import { AddonNotesOffline } from '@addons/notes/services/notes-offline'; import { AddonNotesOffline } from '@addons/notes/services/notes-offline';
import { AddonNotesSync, AddonNotesSyncProvider } from '@addons/notes/services/notes-sync'; import { AddonNotesSync, AddonNotesSyncProvider } from '@addons/notes/services/notes-sync';
import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core'; import { Component, OnDestroy, OnInit, ViewChild } from '@angular/core';
@ -26,7 +26,6 @@ import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreTextUtils } from '@services/utils/text'; import { CoreTextUtils } from '@services/utils/text';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { ModalController } from '@singletons';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
/** /**
@ -43,7 +42,7 @@ export class AddonNotesListPage implements OnInit, OnDestroy {
courseId: number; courseId: number;
userId?: number; userId?: number;
type = 'course'; type: AddonNotesPublishState = 'course';
refreshIcon = CoreConstants.ICON_LOADING; refreshIcon = CoreConstants.ICON_LOADING;
syncIcon = CoreConstants.ICON_LOADING; syncIcon = CoreConstants.ICON_LOADING;
notes: AddonNotesNoteFormatted[] = []; notes: AddonNotesNoteFormatted[] = [];
@ -160,7 +159,7 @@ export class AddonNotesListPage implements OnInit, OnDestroy {
* *
* @param type New type. * @param type New type.
*/ */
async typeChanged(type: string): Promise<void> { async typeChanged(type: AddonNotesPublishState): Promise<void> {
this.type = type; this.type = type;
this.notesLoaded = false; this.notesLoaded = false;
this.refreshIcon = CoreConstants.ICON_LOADING; this.refreshIcon = CoreConstants.ICON_LOADING;
@ -179,7 +178,7 @@ export class AddonNotesListPage implements OnInit, OnDestroy {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
const modal = await ModalController.create({ const modalData = await CoreDomUtils.openModal<AddonNotesAddModalReturn>({
component: AddonNotesAddComponent, component: AddonNotesAddComponent,
componentProps: { componentProps: {
userId: this.userId, userId: this.userId,
@ -188,21 +187,17 @@ export class AddonNotesListPage implements OnInit, OnDestroy {
}, },
}); });
await modal.present(); if (typeof modalData != 'undefined') {
const result = await modal.onDidDismiss(); if (modalData.sent && modalData.type) {
if (modalData.type != this.type) {
if (typeof result.data != 'undefined') { this.type = modalData.type;
if (result.data.sent && result.data.type) {
if (result.data.type != this.type) {
this.type = result.data.type;
this.notesLoaded = false; this.notesLoaded = false;
} }
this.refreshNotes(false); this.refreshNotes(false);
} else if (result.data.type && result.data.type != this.type) { } else if (modalData.type && modalData.type != this.type) {
this.typeChanged(result.data.type); this.typeChanged(modalData.type);
} }
} }
} }

View File

@ -13,6 +13,7 @@
// limitations under the License. // limitations under the License.
import { CoreSiteSchema } from '@services/sites'; import { CoreSiteSchema } from '@services/sites';
import { AddonNotesPublishState } from '../notes';
/** /**
* Database variables for AddonNotesOfflineProvider. * Database variables for AddonNotesOfflineProvider.
@ -83,7 +84,7 @@ export type AddonNotesDBRecord = {
content: string; // Primary key. content: string; // Primary key.
created: number; // Primary key. created: number; // Primary key.
courseid: number; courseid: number;
publishstate: string; publishstate: AddonNotesPublishState;
format: number; format: number;
lastmodified: number; lastmodified: number;
}; };

View File

@ -17,6 +17,7 @@ import { CoreSites } from '@services/sites';
import { CoreTimeUtils } from '@services/utils/time'; import { CoreTimeUtils } from '@services/utils/time';
import { makeSingleton } from '@singletons'; import { makeSingleton } from '@singletons';
import { AddonNotesDBRecord, AddonNotesDeletedDBRecord, NOTES_DELETED_TABLE, NOTES_TABLE } from './database/notes'; import { AddonNotesDBRecord, AddonNotesDeletedDBRecord, NOTES_DELETED_TABLE, NOTES_TABLE } from './database/notes';
import { AddonNotesPublishState } from './notes';
/** /**
* Service to handle offline notes. * Service to handle offline notes.
@ -150,7 +151,7 @@ export class AddonNotesOfflineProvider {
* @param siteId Site ID. If not defined, current site. * @param siteId Site ID. If not defined, current site.
* @return Promise resolved with notes. * @return Promise resolved with notes.
*/ */
async getNotesWithPublishState(state: string, siteId?: string): Promise<AddonNotesDBRecord[]> { async getNotesWithPublishState(state: AddonNotesPublishState, siteId?: string): Promise<AddonNotesDBRecord[]> {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
return await site.getDb().getRecords(NOTES_TABLE, { publishstate: state }); return await site.getDb().getRecords(NOTES_TABLE, { publishstate: state });
@ -189,7 +190,7 @@ export class AddonNotesOfflineProvider {
* @param siteId Site ID. If not defined, current site. * @param siteId Site ID. If not defined, current site.
* @return Promise resolved with boolean: true if has offline notes, false otherwise. * @return Promise resolved with boolean: true if has offline notes, false otherwise.
*/ */
async hasNotesWithPublishState(state: string, siteId?: string): Promise<boolean> { async hasNotesWithPublishState(state: AddonNotesPublishState, siteId?: string): Promise<boolean> {
const notes = await this.getNotesWithPublishState(state, siteId); const notes = await this.getNotesWithPublishState(state, siteId);
return !!notes.length; return !!notes.length;
@ -205,7 +206,13 @@ export class AddonNotesOfflineProvider {
* @param siteId Site ID. If not defined, current site. * @param siteId Site ID. If not defined, current site.
* @return Promise resolved if stored, rejected if failure. * @return Promise resolved if stored, rejected if failure.
*/ */
async saveNote(userId: number, courseId: number, state: string, content: string, siteId?: string): Promise<void> { async saveNote(
userId: number,
courseId: number,
state: AddonNotesPublishState,
content: string,
siteId?: string,
): Promise<void> {
const site = await CoreSites.getSite(siteId); const site = await CoreSites.getSite(siteId);
const now = CoreTimeUtils.timestamp(); const now = CoreTimeUtils.timestamp();

View File

@ -42,7 +42,13 @@ export class AddonNotesProvider {
* @param siteId Site ID. If not defined, current site. * @param siteId Site ID. If not defined, current site.
* @return Promise resolved with boolean: true if note was sent to server, false if stored in device. * @return Promise resolved with boolean: true if note was sent to server, false if stored in device.
*/ */
async addNote(userId: number, courseId: number, publishState: string, noteText: string, siteId?: string): Promise<boolean> { async addNote(
userId: number,
courseId: number,
publishState: AddonNotesPublishState,
noteText: string,
siteId?: string,
): Promise<boolean> {
siteId = siteId || CoreSites.getCurrentSiteId(); siteId = siteId || CoreSites.getCurrentSiteId();
// Convenience function to store a note to be synchronized later. // Convenience function to store a note to be synchronized later.
@ -82,7 +88,13 @@ export class AddonNotesProvider {
* @param siteId Site ID. If not defined, current site. * @param siteId Site ID. If not defined, current site.
* @return Promise resolved when added, rejected otherwise. * @return Promise resolved when added, rejected otherwise.
*/ */
async addNoteOnline(userId: number, courseId: number, publishState: string, noteText: string, siteId?: string): Promise<void> { async addNoteOnline(
userId: number,
courseId: number,
publishState: AddonNotesPublishState,
noteText: string,
siteId?: string,
): Promise<void> {
const notes: AddonNotesCreateNoteData[] = [ const notes: AddonNotesCreateNoteData[] = [
{ {
courseid: courseId, courseid: courseId,
@ -438,7 +450,7 @@ export type AddonNotesNote = {
created: number; // Time created (timestamp). created: number; // Time created (timestamp).
lastmodified: number; // Time of last modification (timestamp). lastmodified: number; // Time of last modification (timestamp).
usermodified: number; // User id of the creator of this note. usermodified: number; // User id of the creator of this note.
publishstate: string; // State of the note (i.e. draft, public, site). publishstate: AddonNotesPublishState; // State of the note (i.e. draft, public, site).
offline?: boolean; offline?: boolean;
}; };
@ -474,7 +486,7 @@ export type AddonNotesNoteFormatted = AddonNotesNote & {
export type AddonNotesCreateNoteData = { export type AddonNotesCreateNoteData = {
userid: number; // Id of the user the note is about. userid: number; // Id of the user the note is about.
publishstate: string; // 'personal', 'course' or 'site'. publishstate: AddonNotesPublishState; // 'personal', 'course' or 'site'.
courseid: number; // Course id of the note (in Moodle a note can only be created into a course, courseid: number; // Course id of the note (in Moodle a note can only be created into a course,
// even for site and personal notes). // even for site and personal notes).
text: string; // The text of the message - text or HTML. text: string; // The text of the message - text or HTML.
@ -504,3 +516,5 @@ export type AddonNotesCreateNotesWSResponse = {
type AddonNotesDeleteNotesWSParams = { type AddonNotesDeleteNotesWSParams = {
notes: number[]; // Array of Note Ids to be deleted. notes: number[]; // Array of Note Ids to be deleted.
}; };
export type AddonNotesPublishState = 'personal' | 'site' | 'course';

View File

@ -42,7 +42,7 @@ export class CoreRecaptchaModalComponent implements OnDestroy {
* Close modal. * Close modal.
*/ */
closeModal(): void { closeModal(): void {
ModalController.dismiss({ ModalController.dismiss(<CoreRecaptchaModalReturn>{
expired: this.expired, expired: this.expired,
value: this.value, value: this.value,
}); });
@ -119,3 +119,8 @@ export class CoreRecaptchaModalComponent implements OnDestroy {
} }
} }
export type CoreRecaptchaModalReturn = {
expired: boolean;
value: string;
};

View File

@ -16,9 +16,9 @@ import { Component, Input, OnInit } from '@angular/core';
import { CoreLang } from '@services/lang'; import { CoreLang } from '@services/lang';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom';
import { CoreTextUtils } from '@services/utils/text'; import { CoreTextUtils } from '@services/utils/text';
import { ModalController } from '@singletons'; import { CoreRecaptchaModalComponent, CoreRecaptchaModalReturn } from './recaptcha-modal';
import { CoreRecaptchaModalComponent } from './recaptcha-modal';
/** /**
* Component that allows answering a recaptcha. * Component that allows answering a recaptcha.
@ -66,7 +66,7 @@ export class CoreRecaptchaComponent implements OnInit {
// Modal to answer the recaptcha. // Modal to answer the recaptcha.
// This is because the size of the recaptcha is dynamic, so it could cause problems if it was displayed inline. // This is because the size of the recaptcha is dynamic, so it could cause problems if it was displayed inline.
const modal = await ModalController.create({ const modalData = await CoreDomUtils.openModal<CoreRecaptchaModalReturn>({
component: CoreRecaptchaModalComponent, component: CoreRecaptchaModalComponent,
cssClass: 'core-modal-fullscreen', cssClass: 'core-modal-fullscreen',
componentProps: { componentProps: {
@ -74,12 +74,10 @@ export class CoreRecaptchaComponent implements OnInit {
}, },
}); });
await modal.present(); if (modalData) {
this.expired = modalData.expired;
const result = await modal.onWillDismiss(); this.model![this.modelValueName] = modalData.value;
}
this.expired = result.data.expired;
this.model![this.modelValueName] = result.data.value;
} }
} }

View File

@ -69,7 +69,7 @@ export class CoreCommentsAddComponent {
CoreSites.getCurrentSiteId(), CoreSites.getCurrentSiteId(),
); );
ModalController.dismiss({ comment: commentsResponse }).finally(() => { ModalController.dismiss(commentsResponse).finally(() => {
CoreDomUtils.showToast( CoreDomUtils.showToast(
commentsResponse ? 'core.comments.eventcommentcreated' : 'core.datastoredoffline', commentsResponse ? 'core.comments.eventcommentcreated' : 'core.datastoredoffline',
true, true,

View File

@ -30,7 +30,7 @@ import {
import { IonContent, IonRefresher } from '@ionic/angular'; import { IonContent, IonRefresher } from '@ionic/angular';
import { ContextLevel, CoreConstants } from '@/core/constants'; import { ContextLevel, CoreConstants } from '@/core/constants';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { ModalController, Translate } from '@singletons'; import { Translate } from '@singletons';
import { CoreUtils } from '@services/utils/utils'; import { CoreUtils } from '@services/utils/utils';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreUser, CoreUserProfile } from '@features/user/services/user'; import { CoreUser, CoreUserProfile } from '@features/user/services/user';
@ -279,19 +279,15 @@ export class CoreCommentsViewerPage implements OnInit, OnDestroy {
content: this.offlineComment ? this.offlineComment!.content : '', content: this.offlineComment ? this.offlineComment!.content : '',
}; };
const modal = await ModalController.create({ const comment = await CoreDomUtils.openModal<CoreCommentsDataWithUser>({
component: CoreCommentsAddComponent, component: CoreCommentsAddComponent,
componentProps: params, componentProps: params,
}); });
await modal.present(); if (comment) {
const result = await modal.onDidDismiss();
if (result?.data?.comment) {
this.invalidateComments(); this.invalidateComments();
const addedComments = await this.loadCommentProfile(result.data.comment); const addedComments = await this.loadCommentProfile(comment);
// Add the comment to the top. // Add the comment to the top.
this.comments = [addedComments].concat(this.comments); this.comments = [addedComments].concat(this.comments);
this.canDeleteComments = this.addDeleteCommentsAvailable; this.canDeleteComments = this.addDeleteCommentsAvailable;
@ -305,7 +301,7 @@ export class CoreCommentsViewerPage implements OnInit, OnDestroy {
countChange: 1, countChange: 1,
}, CoreSites.getCurrentSiteId()); }, CoreSites.getCurrentSiteId());
} else if (result?.data?.comment === false) { } else if (comment === false) {
// Comments added in offline mode. // Comments added in offline mode.
return this.loadOfflineData(); return this.loadOfflineData();
} }

View File

@ -17,7 +17,7 @@ import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreContentLinksDelegate, CoreContentLinksAction } from './contentlinks-delegate'; import { CoreContentLinksDelegate, CoreContentLinksAction } from './contentlinks-delegate';
import { CoreSite } from '@classes/site'; import { CoreSite } from '@classes/site';
import { makeSingleton, ModalController, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { Params } from '@angular/router'; import { Params } from '@angular/router';
import { CoreContentLinksChooseSiteModalComponent } from '../components/choose-site-modal/choose-site-modal'; import { CoreContentLinksChooseSiteModalComponent } from '../components/choose-site-modal/choose-site-modal';
@ -112,15 +112,13 @@ export class CoreContentLinksHelperProvider {
* @todo set correct root. * @todo set correct root.
*/ */
async goToChooseSite(url: string): Promise<void> { async goToChooseSite(url: string): Promise<void> {
const modal = await ModalController.create({ await CoreDomUtils.openModal({
component: CoreContentLinksChooseSiteModalComponent, component: CoreContentLinksChooseSiteModalComponent,
componentProps: { componentProps: {
url: url, url: url,
}, },
cssClass: 'core-modal-fullscreen', cssClass: 'core-modal-fullscreen',
}); });
await modal.present();
} }
/** /**

View File

@ -13,7 +13,7 @@
// limitations under the License. // limitations under the License.
import { Component, OnDestroy, NgZone, OnInit } from '@angular/core'; import { Component, OnDestroy, NgZone, OnInit } from '@angular/core';
import { ModalController, IonRefresher } from '@ionic/angular'; import { IonRefresher } from '@ionic/angular';
import { CoreApp } from '@services/app'; import { CoreApp } from '@services/app';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
@ -76,7 +76,6 @@ export class CoreCoursePreviewPage implements OnInit, OnDestroy {
protected courseStatusObserver?: CoreEventObserver; protected courseStatusObserver?: CoreEventObserver;
constructor( constructor(
protected modalCtrl: ModalController,
protected zone: NgZone, protected zone: NgZone,
) { ) {
this.isMobile = CoreApp.isMobile(); this.isMobile = CoreApp.isMobile();
@ -347,19 +346,16 @@ export class CoreCoursePreviewPage implements OnInit, OnDestroy {
if (error && error.errorcode === CoreCoursesProvider.ENROL_INVALID_KEY) { if (error && error.errorcode === CoreCoursesProvider.ENROL_INVALID_KEY) {
// Initialize the self enrol modal. // Initialize the self enrol modal.
const selfEnrolModal = await this.modalCtrl.create( // Invalid password, show the modal to enter the password.
const modalData = await CoreDomUtils.openModal<string>(
{ {
component: CoreCoursesSelfEnrolPasswordComponent, component: CoreCoursesSelfEnrolPasswordComponent,
componentProps: { password }, componentProps: { password },
}, },
); );
// Invalid password, show the modal to enter the password. if (typeof modalData != 'undefined') {
await selfEnrolModal.present(); this.selfEnrolInCourse(modalData, instanceId);
const data = await selfEnrolModal.onDidDismiss<string>();
if (typeof data?.data != 'undefined') {
this.selfEnrolInCourse(data.data, instanceId);
return; return;
} }

View File

@ -13,8 +13,9 @@
// limitations under the License. // limitations under the License.
import { Component, ViewChild, ElementRef } from '@angular/core'; import { Component, ViewChild, ElementRef } from '@angular/core';
import { ModalController, NavParams } from '@ionic/angular'; import { NavParams } from '@ionic/angular';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { ModalController } from '@singletons';
import { CoreForms } from '@singletons/form'; import { CoreForms } from '@singletons/form';
/** /**
@ -30,7 +31,6 @@ export class CoreCoursesSelfEnrolPasswordComponent {
password = ''; password = '';
constructor( constructor(
protected modalCtrl: ModalController,
navParams: NavParams, navParams: NavParams,
) { ) {
this.password = navParams.get('password') || ''; this.password = navParams.get('password') || '';
@ -42,7 +42,7 @@ export class CoreCoursesSelfEnrolPasswordComponent {
close(): void { close(): void {
CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId()); CoreForms.triggerFormCancelledEvent(this.formElement, CoreSites.getCurrentSiteId());
this.modalCtrl.dismiss(); ModalController.dismiss();
} }
/** /**
@ -57,7 +57,7 @@ export class CoreCoursesSelfEnrolPasswordComponent {
CoreForms.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId()); CoreForms.triggerFormSubmittedEvent(this.formElement, false, CoreSites.getCurrentSiteId());
this.modalCtrl.dismiss(this.password); ModalController.dismiss(this.password);
} }
} }

View File

@ -24,7 +24,7 @@ import { CoreLoginHelper, CoreLoginHelperProvider } from '@features/login/servic
import { CoreSite } from '@classes/site'; import { CoreSite } from '@classes/site';
import { CoreError } from '@classes/errors/error'; import { CoreError } from '@classes/errors/error';
import { CoreConstants } from '@/core/constants'; import { CoreConstants } from '@/core/constants';
import { Translate, ModalController } from '@singletons'; import { Translate } from '@singletons';
import { CoreUrl } from '@singletons/url'; import { CoreUrl } from '@singletons/url';
import { CoreUrlUtils } from '@services/utils/url'; import { CoreUrlUtils } from '@services/utils/url';
import { CoreLoginSiteHelpComponent } from '@features/login/components/site-help/site-help'; import { CoreLoginSiteHelpComponent } from '@features/login/components/site-help/site-help';
@ -215,24 +215,20 @@ export class CoreLoginSitePage implements OnInit {
* Show a help modal. * Show a help modal.
*/ */
async showHelp(): Promise<void> { async showHelp(): Promise<void> {
const modal = await ModalController.create({ await CoreDomUtils.openModal({
component: CoreLoginSiteHelpComponent, component: CoreLoginSiteHelpComponent,
cssClass: 'core-modal-fullscreen', cssClass: 'core-modal-fullscreen',
}); });
await modal.present();
} }
/** /**
* Show an onboarding modal. * Show an onboarding modal.
*/ */
async showOnboarding(): Promise<void> { async showOnboarding(): Promise<void> {
const modal = await ModalController.create({ await CoreDomUtils.openModal({
component: CoreLoginSiteOnboardingComponent, component: CoreLoginSiteOnboardingComponent,
cssClass: 'core-modal-fullscreen', cssClass: 'core-modal-fullscreen',
}); });
await modal.present();
} }
/** /**

View File

@ -21,7 +21,7 @@ import {
CoreRatingProvider, CoreRatingProvider,
} from '@features/rating/services/rating'; } from '@features/rating/services/rating';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { ModalController } from '@singletons'; import { CoreDomUtils } from '@services/utils/dom';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreRatingRatingsComponent } from '../ratings/ratings'; import { CoreRatingRatingsComponent } from '../ratings/ratings';
@ -117,7 +117,7 @@ export class CoreRatingAggregateComponent implements OnChanges, OnDestroy {
return; return;
} }
const modal = await ModalController.create({ await CoreDomUtils.openModal({
component: CoreRatingRatingsComponent, component: CoreRatingRatingsComponent,
componentProps: { componentProps: {
contextLevel: this.contextLevel, contextLevel: this.contextLevel,
@ -129,8 +129,6 @@ export class CoreRatingAggregateComponent implements OnChanges, OnDestroy {
courseId: this.courseId, courseId: this.courseId,
}, },
}); });
await modal.present();
} }
/** /**

View File

@ -23,7 +23,7 @@ import { CoreFile } from '@services/file';
import { CoreNavigator } from '@services/navigator'; import { CoreNavigator } from '@services/navigator';
import { CoreSites } from '@services/sites'; import { CoreSites } from '@services/sites';
import { CoreDomUtils } from '@services/utils/dom'; import { CoreDomUtils } from '@services/utils/dom';
import { AlertController, ApplicationInit, makeSingleton, ModalController, Platform, Translate } from '@singletons'; import { AlertController, ApplicationInit, makeSingleton, Platform, Translate } from '@singletons';
import { CoreEvents } from '@singletons/events'; import { CoreEvents } from '@singletons/events';
import { CoreLogger } from '@singletons/logger'; import { CoreLogger } from '@singletons/logger';
import { CoreSharedFilesListModalComponent } from '../components/list-modal/list-modal'; import { CoreSharedFilesListModalComponent } from '../components/list-modal/list-modal';
@ -150,17 +150,12 @@ export class CoreSharedFilesHelperProvider {
* @return Promise resolved when a file is picked, rejected if file picker is closed without selecting a file. * @return Promise resolved when a file is picked, rejected if file picker is closed without selecting a file.
*/ */
async pickSharedFile(mimetypes?: string[]): Promise<CoreFileUploaderHandlerResult> { async pickSharedFile(mimetypes?: string[]): Promise<CoreFileUploaderHandlerResult> {
const modal = await ModalController.create({ const file = await CoreDomUtils.openModal<FileEntry>({
component: CoreSharedFilesListModalComponent, component: CoreSharedFilesListModalComponent,
cssClass: 'core-modal-fullscreen', cssClass: 'core-modal-fullscreen',
componentProps: { mimetypes, pick: true }, componentProps: { mimetypes, pick: true },
}); });
await modal.present();
const result = await modal.onDidDismiss();
const file: FileEntry | undefined = result.data;
if (!file) { if (!file) {
// User cancelled. // User cancelled.
throw new CoreCanceledError(); throw new CoreCanceledError();

View File

@ -1684,23 +1684,43 @@ export class CoreDomUtilsProvider {
/** /**
* Opens a Modal. * Opens a Modal.
* *
* @param opts Modal Options. * @param modalOptions Modal Options.
*/ */
// eslint-disable-next-line @typescript-eslint/no-explicit-any async openModal<T = unknown>(
async openModal<T = any>( modalOptions: ModalOptions,
opts: ModalOptions,
): Promise<T | undefined> { ): Promise<T | undefined> {
const modal = await ModalController.create(opts); const modal = await ModalController.create(modalOptions);
await modal.present(); await modal.present();
// If onDidDismiss is nedded we can add a new param to the function to wait one function or the other.
const result = await modal.onWillDismiss<T>(); const result = await modal.onWillDismiss<T>();
if (result?.data) { if (result?.data) {
return result?.data; return result?.data;
} }
} }
/**
* Opens a side Modal.
*
* @param modalOptions Modal Options.
*/
async openSideModal<T = unknown>(
modalOptions: ModalOptions,
): Promise<T | undefined> {
modalOptions = Object.assign(modalOptions, {
cssClass: 'core-modal-lateral',
showBackdrop: true,
backdropDismiss: true,
// @todo enterAnimation: 'core-modal-lateral-transition',
// @todo leaveAnimation: 'core-modal-lateral-transition',
});
return await this.openModal<T>(modalOptions);
}
/** /**
* View an image in a modal. * View an image in a modal.
* *
@ -1721,7 +1741,7 @@ export class CoreDomUtilsProvider {
return; return;
} }
const modal = await ModalController.create({ await CoreDomUtils.openModal({
component: CoreViewerImageComponent, component: CoreViewerImageComponent,
componentProps: { componentProps: {
title, title,
@ -1732,7 +1752,6 @@ export class CoreDomUtilsProvider {
cssClass: fullScreen ? 'core-modal-fullscreen' : '', cssClass: fullScreen ? 'core-modal-fullscreen' : '',
}); });
await modal.present();
} }
/** /**

View File

@ -19,11 +19,12 @@ import { ModalOptions } from '@ionic/core';
import { CoreApp } from '@services/app'; import { CoreApp } from '@services/app';
import { CoreLang } from '@services/lang'; import { CoreLang } from '@services/lang';
import { CoreAnyError, CoreError } from '@classes/errors/error'; import { CoreAnyError, CoreError } from '@classes/errors/error';
import { makeSingleton, ModalController, Translate } from '@singletons'; import { makeSingleton, Translate } from '@singletons';
import { CoreWSFile } from '@services/ws'; import { CoreWSFile } from '@services/ws';
import { Locutus } from '@singletons/locutus'; import { Locutus } from '@singletons/locutus';
import { CoreViewerTextComponent } from '@features/viewer/components/text/text'; import { CoreViewerTextComponent } from '@features/viewer/components/text/text';
import { CoreFileHelper } from '@services/file-helper'; import { CoreFileHelper } from '@services/file-helper';
import { CoreDomUtils } from './dom';
/** /**
* Different type of errors the app can treat. * Different type of errors the app can treat.
@ -1097,9 +1098,7 @@ export class CoreTextUtilsProvider {
...options, ...options,
}; };
const modal = await ModalController.create(modalOptions); await CoreDomUtils.openModal(modalOptions);
await modal.present();
} }
} }

View File

@ -26,7 +26,7 @@ import { CoreDomUtils } from '@services/utils/dom';
import { CoreMimetypeUtils } from '@services/utils/mimetype'; import { CoreMimetypeUtils } from '@services/utils/mimetype';
import { CoreTextUtils } from '@services/utils/text'; import { CoreTextUtils } from '@services/utils/text';
import { CoreWSError } from '@classes/errors/wserror'; import { CoreWSError } from '@classes/errors/wserror';
import { makeSingleton, Clipboard, InAppBrowser, FileOpener, WebIntent, QRScanner, Translate, ModalController } from '@singletons'; import { makeSingleton, Clipboard, InAppBrowser, FileOpener, WebIntent, QRScanner, Translate } from '@singletons';
import { CoreLogger } from '@singletons/logger'; import { CoreLogger } from '@singletons/logger';
import { CoreFileSizeSum } from '@services/plugin-file-delegate'; import { CoreFileSizeSum } from '@services/plugin-file-delegate';
import { CoreViewerQRScannerComponent } from '@features/viewer/components/qr-scanner/qr-scanner'; import { CoreViewerQRScannerComponent } from '@features/viewer/components/qr-scanner/qr-scanner';
@ -1515,20 +1515,14 @@ export class CoreUtilsProvider {
* @param title Title of the modal. Defaults to "QR reader". * @param title Title of the modal. Defaults to "QR reader".
* @return Promise resolved with the captured text or undefined if cancelled or error. * @return Promise resolved with the captured text or undefined if cancelled or error.
*/ */
async scanQR(title?: string): Promise<string> { async scanQR(title?: string): Promise<string | undefined> {
const modal = await ModalController.create({ return await CoreDomUtils.openModal<string>({
component: CoreViewerQRScannerComponent, component: CoreViewerQRScannerComponent,
cssClass: 'core-modal-fullscreen', cssClass: 'core-modal-fullscreen',
componentProps: { componentProps: {
title, title,
}, },
}); });
await modal.present();
const result = await modal.onWillDismiss();
return result.data;
} }
/** /**

View File

@ -50,6 +50,11 @@ ion-item.ion-text-wrap ion-label {
white-space: normal !important; white-space: normal !important;
} }
// Buttons.
.button-clear {
--ion-color-primary: var(--ion-text-color);
}
// It fixes the click on links where ion-ripple-effect is present. // It fixes the click on links where ion-ripple-effect is present.
.ion-activatable ion-label, .ion-activatable ion-label,
.item-multiple-items ion-label { .item-multiple-items ion-label {