diff --git a/scripts/langindex.json b/scripts/langindex.json
index 19eabe1cf..bb5317983 100644
--- a/scripts/langindex.json
+++ b/scripts/langindex.json
@@ -1387,6 +1387,7 @@
"core.contentlinks.errorredirectothersite": "local_moodlemobileapp",
"core.continue": "moodle",
"core.copiedtoclipboard": "local_moodlemobileapp",
+ "core.copytoclipboard": "local_moodlemobileapp",
"core.course": "moodle",
"core.course.activitydisabled": "local_moodlemobileapp",
"core.course.activitynotyetviewableremoteaddon": "local_moodlemobileapp",
@@ -1754,6 +1755,7 @@
"core.login.mustconfirm": "moodle",
"core.login.newaccount": "moodle",
"core.login.notloggedin": "local_moodlemobileapp",
+ "core.login.or": "local_moodlemobileapp",
"core.login.password": "moodle",
"core.login.passwordforgotten": "moodle",
"core.login.passwordforgotteninstructions2": "moodle",
@@ -1860,6 +1862,7 @@
"core.online": "message",
"core.openfullimage": "local_moodlemobileapp",
"core.openinbrowser": "local_moodlemobileapp",
+ "core.openmodinbrowser": "local_moodlemobileapp",
"core.othergroups": "group",
"core.pagea": "moodle",
"core.parentlanguage": "langconfig",
diff --git a/src/addon/mod/assign/components/index/index.ts b/src/addon/mod/assign/components/index/index.ts
index b392abef3..8d8fb9985 100644
--- a/src/addon/mod/assign/components/index/index.ts
+++ b/src/addon/mod/assign/components/index/index.ts
@@ -133,8 +133,15 @@ export class AddonModAssignIndexComponent extends CoreCourseModuleMainActivityCo
ev && ev.stopPropagation();
if (this.assign && (this.description || this.assign.introattachments)) {
- this.textUtils.expandText(this.translate.instant('core.description'), this.description, this.component,
- this.module.id, this.assign.introattachments, true, 'module', this.module.id, this.courseId);
+ this.textUtils.viewText(this.translate.instant('core.description'), this.description, {
+ component: this.component,
+ componentId: this.module.id,
+ files: this.assign.introattachments,
+ filter: true,
+ contextLevel: 'module',
+ instanceId: this.module.id,
+ courseId: this.courseId,
+ });
}
}
diff --git a/src/addon/mod/assign/components/submission/submission.ts b/src/addon/mod/assign/components/submission/submission.ts
index 9c231cabf..6bc9c7282 100644
--- a/src/addon/mod/assign/components/submission/submission.ts
+++ b/src/addon/mod/assign/components/submission/submission.ts
@@ -678,8 +678,10 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy {
*/
showAdvancedGrade(): void {
if (this.feedback && this.feedback.advancedgrade) {
- this.textUtils.expandText(this.translate.instant('core.grades.grade'), this.feedback.gradefordisplay,
- AddonModAssignProvider.COMPONENT, this.moduleId);
+ this.textUtils.viewText(this.translate.instant('core.grades.grade'), this.feedback.gradefordisplay, {
+ component: AddonModAssignProvider.COMPONENT,
+ componentId: this.moduleId,
+ });
}
}
diff --git a/src/addon/mod/assign/feedback/comments/component/comments.ts b/src/addon/mod/assign/feedback/comments/component/comments.ts
index 27eb0baa1..1207e8f33 100644
--- a/src/addon/mod/assign/feedback/comments/component/comments.ts
+++ b/src/addon/mod/assign/feedback/comments/component/comments.ts
@@ -65,8 +65,14 @@ export class AddonModAssignFeedbackCommentsComponent extends AddonModAssignFeedb
if (this.text) {
// Open a new state with the text.
- this.textUtils.expandText(this.plugin.name, this.text, this.component, this.assign.cmid, undefined, true,
- 'module', this.assign.cmid, this.assign.course);
+ this.textUtils.viewText(this.plugin.name, this.text, {
+ component: this.component,
+ componentId: this.assign.cmid,
+ filter: true,
+ contextLevel: 'module',
+ instanceId: this.assign.cmid,
+ courseId: this.assign.course,
+ });
}
});
} else if (this.edit) {
diff --git a/src/addon/mod/assign/submission/onlinetext/component/onlinetext.ts b/src/addon/mod/assign/submission/onlinetext/component/onlinetext.ts
index a788de667..ccfb0d3cd 100644
--- a/src/addon/mod/assign/submission/onlinetext/component/onlinetext.ts
+++ b/src/addon/mod/assign/submission/onlinetext/component/onlinetext.ts
@@ -83,8 +83,14 @@ export class AddonModAssignSubmissionOnlineTextComponent extends AddonModAssignS
if (text) {
// Open a new state with the interpolated contents.
- this.textUtils.expandText(this.plugin.name, text, this.component, this.assign.cmid, undefined, true,
- 'module', this.assign.cmid, this.assign.course);
+ this.textUtils.viewText(this.plugin.name, text, {
+ component: this.component,
+ componentId: this.assign.cmid,
+ filter: true,
+ contextLevel: 'module',
+ instanceId: this.assign.cmid,
+ courseId: this.assign.course,
+ });
}
});
} else {
diff --git a/src/assets/lang/en.json b/src/assets/lang/en.json
index 7e4902eba..7fd738ba5 100644
--- a/src/assets/lang/en.json
+++ b/src/assets/lang/en.json
@@ -1387,6 +1387,7 @@
"core.contentlinks.errorredirectothersite": "The redirect URL cannot point to a different site.",
"core.continue": "Continue",
"core.copiedtoclipboard": "Text copied to clipboard",
+ "core.copytoclipboard": "Copy to clipboard",
"core.course": "Course",
"core.course.activitydisabled": "Your organisation has disabled this activity in the mobile app.",
"core.course.activitynotyetviewableremoteaddon": "Your organisation installed a plugin that is not yet supported.",
diff --git a/src/components/navigation-bar/navigation-bar.ts b/src/components/navigation-bar/navigation-bar.ts
index c19aad5ac..5eb878cb2 100644
--- a/src/components/navigation-bar/navigation-bar.ts
+++ b/src/components/navigation-bar/navigation-bar.ts
@@ -47,7 +47,13 @@ export class CoreNavigationBarComponent {
}
showInfo(): void {
- this.textUtils.expandText(this.title, this.info, this.component, this.componentId, [], true, this.contextLevel,
- this.contextInstanceId, this.courseId);
+ this.textUtils.viewText(this.title, this.info, {
+ component: this.component,
+ componentId: this.componentId,
+ filter: true,
+ contextLevel: this.contextLevel,
+ instanceId: this.contextInstanceId,
+ courseId: this.courseId,
+ });
}
}
diff --git a/src/core/course/classes/main-resource-component.ts b/src/core/course/classes/main-resource-component.ts
index b84b2964e..0a333639b 100644
--- a/src/core/course/classes/main-resource-component.ts
+++ b/src/core/course/classes/main-resource-component.ts
@@ -265,8 +265,14 @@ export class CoreCourseModuleMainResourceComponent implements OnInit, OnDestroy,
* Expand the description.
*/
expandDescription(): void {
- this.textUtils.expandText(this.translate.instant('core.description'), this.description, this.component, this.module.id,
- [], true, 'module', this.module.id, this.courseId);
+ this.textUtils.viewText(this.translate.instant('core.description'), this.description, {
+ component: this.component,
+ componentId: this.module.id,
+ filter: true,
+ contextLevel: 'module',
+ instanceId: this.module.id,
+ courseId: this.courseId,
+ });
}
/**
diff --git a/src/core/course/pages/unsupported-module/unsupported-module.ts b/src/core/course/pages/unsupported-module/unsupported-module.ts
index a28a2dde6..e63edc461 100644
--- a/src/core/course/pages/unsupported-module/unsupported-module.ts
+++ b/src/core/course/pages/unsupported-module/unsupported-module.ts
@@ -38,7 +38,11 @@ export class CoreCourseUnsupportedModulePage {
* Expand the description.
*/
expandDescription(): void {
- this.textUtils.expandText(this.translate.instant('core.description'), this.module.description, undefined, undefined,
- [], true, 'module', this.module.id, this.courseId);
+ this.textUtils.viewText(this.translate.instant('core.description'), this.module.description, {
+ filter: true,
+ contextLevel: 'module',
+ instanceId: this.module.id,
+ courseId: this.courseId,
+ });
}
}
diff --git a/src/core/login/pages/email-signup/email-signup.ts b/src/core/login/pages/email-signup/email-signup.ts
index 62121f94b..fc0eb808d 100644
--- a/src/core/login/pages/email-signup/email-signup.ts
+++ b/src/core/login/pages/email-signup/email-signup.ts
@@ -317,7 +317,7 @@ export class CoreLoginEmailSignupPage {
* Show authentication instructions.
*/
protected showAuthInstructions(): void {
- this.textUtils.expandText(this.translate.instant('core.login.instructions'), this.authInstructions);
+ this.textUtils.viewText(this.translate.instant('core.login.instructions'), this.authInstructions);
}
/**
diff --git a/src/core/mainmenu/pages/more/more.ts b/src/core/mainmenu/pages/more/more.ts
index f583edc2d..cca0add21 100644
--- a/src/core/mainmenu/pages/more/more.ts
+++ b/src/core/mainmenu/pages/more/more.ts
@@ -192,7 +192,9 @@ export class CoreMainMenuMorePage implements OnDestroy {
});
} else {
// It's not a URL, open it in a modal so the user can see it and copy it.
- this.textUtils.expandText(this.translate.instant('core.qrscanner'), text);
+ this.textUtils.viewText(this.translate.instant('core.qrscanner'), text, {
+ displayCopyButton: true,
+ });
}
}
});
diff --git a/src/core/question/providers/helper.ts b/src/core/question/providers/helper.ts
index 7623ea747..378c1a2cb 100644
--- a/src/core/question/providers/helper.ts
+++ b/src/core/question/providers/helper.ts
@@ -709,8 +709,14 @@ export class CoreQuestionHelperProvider {
if (span) {
// There's a hidden feedback, show it when the icon is clicked.
icon.addEventListener('click', (event) => {
- this.textUtils.expandText(title, span.innerHTML, component, componentId, [], true, contextLevel,
- contextInstanceId, courseId);
+ this.textUtils.viewText(title, span.innerHTML, {
+ component: component,
+ componentId: componentId,
+ filter: true,
+ contextLevel: contextLevel,
+ instanceId: contextInstanceId,
+ courseId: courseId,
+ });
});
}
});
diff --git a/src/core/siteplugins/components/module-index/module-index.ts b/src/core/siteplugins/components/module-index/module-index.ts
index 586bd5203..94f1dcc75 100644
--- a/src/core/siteplugins/components/module-index/module-index.ts
+++ b/src/core/siteplugins/components/module-index/module-index.ts
@@ -146,8 +146,14 @@ export class CoreSitePluginsModuleIndexComponent implements OnInit, OnDestroy, C
* Expand the description.
*/
expandDescription(): void {
- this.textUtils.expandText(this.translate.instant('core.description'), this.description, this.component, this.module.id,
- [], true, 'module', this.module.id, this.courseId);
+ this.textUtils.viewText(this.translate.instant('core.description'), this.description, {
+ component: this.component,
+ componentId: this.module.id,
+ filter: true,
+ contextLevel: 'module',
+ instanceId: this.module.id,
+ courseId: this.courseId,
+ });
}
/**
diff --git a/src/core/viewer/pages/text/text.html b/src/core/viewer/pages/text/text.html
index 410063705..108d28929 100644
--- a/src/core/viewer/pages/text/text.html
+++ b/src/core/viewer/pages/text/text.html
@@ -16,3 +16,9 @@
+
+
+
diff --git a/src/core/viewer/pages/text/text.scss b/src/core/viewer/pages/text/text.scss
new file mode 100644
index 000000000..4377e35e3
--- /dev/null
+++ b/src/core/viewer/pages/text/text.scss
@@ -0,0 +1,5 @@
+ion-app.app-root page-core-viewer-text {
+ ion-footer {
+ padding: 6px;
+ }
+}
diff --git a/src/core/viewer/pages/text/text.ts b/src/core/viewer/pages/text/text.ts
index 6c8c1b6f8..935978391 100644
--- a/src/core/viewer/pages/text/text.ts
+++ b/src/core/viewer/pages/text/text.ts
@@ -15,6 +15,7 @@
import { Component } from '@angular/core';
import { IonicPage, ViewController, NavParams } from 'ionic-angular';
import { CoreTextUtilsProvider } from '@providers/utils/text';
+import { CoreUtils } from '@providers/utils/utils';
/**
* Page to render a certain text. If opened as a modal, it will have a button to close the modal.
@@ -34,6 +35,7 @@ export class CoreViewerTextPage {
contextLevel: string; // The context level.
instanceId: number; // The instance ID related to the context.
courseId: number; // Course ID the text belongs to. It can be used to improve performance with filters.
+ displayCopyButton: boolean; // Whether to display a button to copy the contents.
constructor(private viewCtrl: ViewController, params: NavParams, textUtils: CoreTextUtilsProvider) {
this.title = params.get('title');
@@ -45,6 +47,7 @@ export class CoreViewerTextPage {
this.contextLevel = params.get('contextLevel');
this.instanceId = params.get('instanceId');
this.courseId = params.get('courseId');
+ this.displayCopyButton = !!params.get('displayCopyButton');
}
/**
@@ -53,4 +56,11 @@ export class CoreViewerTextPage {
closeModal(): void {
this.viewCtrl.dismiss();
}
+
+ /**
+ * Copy the text to clipboard.
+ */
+ copyText(): void {
+ CoreUtils.instance.copyToClipboard(this.content);
+ }
}
diff --git a/src/directives/format-text.ts b/src/directives/format-text.ts
index fdec21043..f5c9f8f4b 100644
--- a/src/directives/format-text.ts
+++ b/src/directives/format-text.ts
@@ -307,8 +307,14 @@ export class CoreFormatTextDirective implements OnChanges {
// Open a new state with the contents.
const filter = typeof this.filter != 'undefined' ? this.utils.isTrueOrOne(this.filter) : undefined;
- this.textUtils.expandText(this.fullTitle || this.translate.instant('core.description'), this.text,
- this.component, this.componentId, undefined, filter, this.contextLevel, this.contextInstanceId, this.courseId);
+ this.textUtils.viewText(this.fullTitle || this.translate.instant('core.description'), this.text, {
+ component: this.component,
+ componentId: this.componentId,
+ filter: filter,
+ contextLevel: this.contextLevel,
+ instanceId: this.contextInstanceId,
+ courseId: this.courseId,
+ });
}
}
diff --git a/src/lang/en.json b/src/lang/en.json
index cc4d99e42..8d279f23c 100644
--- a/src/lang/en.json
+++ b/src/lang/en.json
@@ -51,6 +51,7 @@
"contenteditingsynced": "The content you are editing has been synced.",
"continue": "Continue",
"copiedtoclipboard": "Text copied to clipboard",
+ "copytoclipboard": "Copy to clipboard",
"course": "Course",
"coursedetails": "Course details",
"coursenogroups": "You are not a member of any group of this course.",
diff --git a/src/providers/utils/text.ts b/src/providers/utils/text.ts
index 3cac7f846..5ba186d9b 100644
--- a/src/providers/utils/text.ts
+++ b/src/providers/utils/text.ts
@@ -441,28 +441,20 @@ export class CoreTextUtilsProvider {
* @param contextLevel The context level.
* @param instanceId The instance ID related to the context.
* @param courseId Course ID the text belongs to. It can be used to improve performance with filters.
+ * @deprecated since 3.8.3. Please use viewText instead.
*/
expandText(title: string, text: string, component?: string, componentId?: string | number, files?: any[],
filter?: boolean, contextLevel?: string, instanceId?: number, courseId?: number): void {
- if (text.length > 0) {
- const params: any = {
- title: title,
- content: text,
- component: component,
- componentId: componentId,
- files: files,
- filter: filter,
- contextLevel: contextLevel,
- instanceId: instanceId,
- courseId: courseId
- };
- // Open a modal with the contents.
- params.isModal = true;
-
- const modal = this.modalCtrl.create('CoreViewerTextPage', params);
- modal.present();
- }
+ return this.viewText(title, text, {
+ component,
+ componentId,
+ files,
+ filter,
+ contextLevel,
+ instanceId,
+ courseId,
+ });
}
/**
@@ -1133,6 +1125,50 @@ export class CoreTextUtilsProvider {
return _unserialize((data + ''), 0)[2];
}
+
+ /**
+ * Shows a text on a new page.
+ *
+ * @param title Title of the new state.
+ * @param text Content of the text to be expanded.
+ * @param component Component to link the embedded files to.
+ * @param componentId An ID to use in conjunction with the component.
+ * @param files List of files to display along with the text.
+ * @param filter Whether the text should be filtered.
+ * @param contextLevel The context level.
+ * @param instanceId The instance ID related to the context.
+ * @param courseId Course ID the text belongs to. It can be used to improve performance with filters.
+ */
+ viewText(title: string, text: string, options?: CoreTextUtilsViewTextOptions): void {
+ if (text.length > 0) {
+ options = options || {};
+
+ const params: any = {
+ title: title,
+ content: text,
+ isModal: true,
+ };
+
+ Object.assign(params, options);
+
+ const modal = this.modalCtrl.create('CoreViewerTextPage', params);
+ modal.present();
+ }
+ }
}
+/**
+ * Options for viewText.
+ */
+export type CoreTextUtilsViewTextOptions = {
+ component?: string; // Component to link the embedded files to.
+ componentId?: string | number; // An ID to use in conjunction with the component.
+ files?: any[]; // List of files to display along with the text.
+ filter?: boolean; // Whether the text should be filtered.
+ contextLevel?: string; // The context level.
+ instanceId?: number; // The instance ID related to the context.
+ courseId?: number; // Course ID the text belongs to. It can be used to improve performance with filters.
+ displayCopyButton?: boolean; // Whether to display a button to copy the text.
+};
+
export class CoreTextUtils extends makeSingleton(CoreTextUtilsProvider) {}