diff --git a/.github/workflows/acceptance.yml b/.github/workflows/acceptance.yml index ace8d2d2a..35b9a772f 100644 --- a/.github/workflows/acceptance.yml +++ b/.github/workflows/acceptance.yml @@ -153,7 +153,7 @@ jobs: - name: Initialise moodle-plugin-ci run: | - composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^4.4 + composer create-project -n --no-dev --prefer-dist moodlehq/moodle-plugin-ci ci ^4.5 echo $(cd ci/bin; pwd) >> $GITHUB_PATH echo $(cd ci/vendor/bin; pwd) >> $GITHUB_PATH sudo locale-gen en_AU.UTF-8 diff --git a/.github/workflows/testing.yml b/.github/workflows/testing.yml index d2397ede2..a176115c2 100644 --- a/.github/workflows/testing.yml +++ b/.github/workflows/testing.yml @@ -69,7 +69,8 @@ jobs: cat circular-dependencies lines=$(cat circular-dependencies | wc -l) echo "Total circular dependencies: $lines" - test $lines -le 185 + test $lines -ge 138 + test $lines -le 148 - name: JavaScript code compatibility run: | npx check-es-compat www/*.js --polyfills="\{Array,String,TypedArray\}.prototype.at,Object.hasOwn" diff --git a/local_moodleappbehat/templates/mobile.mustache b/local_moodleappbehat/templates/mobile.mustache index d56f2fe4f..c73bd7fcd 100644 --- a/local_moodleappbehat/templates/mobile.mustache +++ b/local_moodleappbehat/templates/mobile.mustache @@ -3,8 +3,7 @@ - What is the answer to the Ultimate Question of Life, The Universe, and Everything? - + That is correct! diff --git a/package-lock.json b/package-lock.json index 282ddf4a3..8c296ef5e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -38,7 +38,7 @@ "@awesome-cordova-plugins/sqlite": "^6.7.0", "@awesome-cordova-plugins/status-bar": "^6.7.0", "@awesome-cordova-plugins/web-intent": "^6.7.0", - "@ionic/angular": "^7.8.6", + "@ionic/angular": "^8.2.5", "@ionic/cordova-builders": "^11.0.0", "@moodlehq/cordova-plugin-advanced-http": "3.3.1-moodle.1", "@moodlehq/cordova-plugin-camera": "7.0.0-moodle.1", @@ -107,7 +107,7 @@ "@angular/cli": "^17.3.6", "@angular/compiler-cli": "^17.3.7", "@angular/language-service": "^17.3.7", - "@ionic/angular-toolkit": "^10.1.1", + "@ionic/angular-toolkit": "^11.0.1", "@ionic/cli": "^7.2.0", "@jsdevtools/coverage-istanbul-loader": "^3.0.5", "@types/faker": "^5.5.9", @@ -3646,123 +3646,32 @@ "dev": true }, "node_modules/@ionic/angular": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-7.8.6.tgz", - "integrity": "sha512-3Qe53hXpyjtx6fFcxt/NTAlauIawsGmCZJPauV5sAnSKVuX8C82C1zMAZTeJt6m2dnd71wythc98BXUXsx/UxQ==", + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/@ionic/angular/-/angular-8.2.5.tgz", + "integrity": "sha512-vvL5TIN8YbrkW5IZ4TYw2zVa4/+boITe19nElPz1Bu7O15lEEzLe+9RqcIMDERwzgqzsBXLh1CUJk+1TXkMhJg==", "dependencies": { - "@ionic/core": "7.8.6", + "@ionic/core": "8.2.5", "ionicons": "^7.0.0", "jsonc-parser": "^3.0.0", "tslib": "^2.3.0" }, "peerDependencies": { - "@angular/core": ">=14.0.0", - "@angular/forms": ">=14.0.0", - "@angular/router": ">=14.0.0", + "@angular/core": ">=16.0.0", + "@angular/forms": ">=16.0.0", + "@angular/router": ">=16.0.0", "rxjs": ">=7.5.0", - "zone.js": ">=0.11.0" + "zone.js": ">=0.13.0" } }, "node_modules/@ionic/angular-toolkit": { - "version": "10.1.1", - "resolved": "https://registry.npmjs.org/@ionic/angular-toolkit/-/angular-toolkit-10.1.1.tgz", - "integrity": "sha512-idLaBUY14M7JQmvxAGeDZvk7WcamWEHo1OHGRuLRAn+7uWrKeGxfWbnbZJhvRCLQndr8j7q3WV3Z+0APkPuKaQ==", + "version": "11.0.1", + "resolved": "https://registry.npmjs.org/@ionic/angular-toolkit/-/angular-toolkit-11.0.1.tgz", + "integrity": "sha512-dxx2RDbxDYM2nWRPIirKMJySHtqJ1u02T25PGbNb99W2Wlcmu1cza3+2/PQ8ga18yMz/dQqaGyEmPDf3ZSVO0w==", "dev": true, "dependencies": { - "@angular-devkit/core": "^16.0.0", - "@angular-devkit/schematics": "^16.0.0", - "@schematics/angular": "^16.0.0" - } - }, - "node_modules/@ionic/angular-toolkit/node_modules/@angular-devkit/core": { - "version": "16.2.14", - "resolved": "https://registry.npmjs.org/@angular-devkit/core/-/core-16.2.14.tgz", - "integrity": "sha512-Ui14/d2+p7lnmXlK/AX2ieQEGInBV75lonNtPQgwrYgskF8ufCuN0DyVZQUy9fJDkC+xQxbJyYrby/BS0R0e7w==", - "dev": true, - "dependencies": { - "ajv": "8.12.0", - "ajv-formats": "2.1.1", - "jsonc-parser": "3.2.0", - "picomatch": "2.3.1", - "rxjs": "7.8.1", - "source-map": "0.7.4" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - }, - "peerDependencies": { - "chokidar": "^3.5.2" - }, - "peerDependenciesMeta": { - "chokidar": { - "optional": true - } - } - }, - "node_modules/@ionic/angular-toolkit/node_modules/@angular-devkit/schematics": { - "version": "16.2.14", - "resolved": "https://registry.npmjs.org/@angular-devkit/schematics/-/schematics-16.2.14.tgz", - "integrity": "sha512-B6LQKInCT8w5zx5Pbroext5eFFRTCJdTwHN8GhcVS8IeKCnkeqVTQLjB4lBUg7LEm8Y7UHXwzrVxmk+f+MBXhw==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "16.2.14", - "jsonc-parser": "3.2.0", - "magic-string": "0.30.1", - "ora": "5.4.1", - "rxjs": "7.8.1" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@ionic/angular-toolkit/node_modules/@schematics/angular": { - "version": "16.2.14", - "resolved": "https://registry.npmjs.org/@schematics/angular/-/angular-16.2.14.tgz", - "integrity": "sha512-YqIv727l9Qze8/OL6H9mBHc2jVXzAGRNBYnxYWqWhLbfvuVbbldo6NNIIjgv6lrl2LJSdPAAMNOD5m/f6210ug==", - "dev": true, - "dependencies": { - "@angular-devkit/core": "16.2.14", - "@angular-devkit/schematics": "16.2.14", - "jsonc-parser": "3.2.0" - }, - "engines": { - "node": "^16.14.0 || >=18.10.0", - "npm": "^6.11.0 || ^7.5.6 || >=8.0.0", - "yarn": ">= 1.13.0" - } - }, - "node_modules/@ionic/angular-toolkit/node_modules/jsonc-parser": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/jsonc-parser/-/jsonc-parser-3.2.0.tgz", - "integrity": "sha512-gfFQZrcTc8CnKXp6Y4/CBT3fTc0OVuDofpre4aEeEpSBPV5X5v4+Vmx+8snU7RLPrNHPKSgLxGo9YuQzz20o+w==", - "dev": true - }, - "node_modules/@ionic/angular-toolkit/node_modules/magic-string": { - "version": "0.30.1", - "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.1.tgz", - "integrity": "sha512-mbVKXPmS0z0G4XqFDCTllmDQ6coZzn94aMlb0o/A4HEHJCKcanlDZwYJgwnkmgD3jyWhUgj9VsPrfd972yPffA==", - "dev": true, - "dependencies": { - "@jridgewell/sourcemap-codec": "^1.4.15" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/@ionic/angular-toolkit/node_modules/picomatch": { - "version": "2.3.1", - "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", - "integrity": "sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA==", - "dev": true, - "engines": { - "node": ">=8.6" - }, - "funding": { - "url": "https://github.com/sponsors/jonschlinkert" + "@angular-devkit/core": "^17.0.0", + "@angular-devkit/schematics": "^17.0.0", + "@schematics/angular": "^17.0.0" } }, "node_modules/@ionic/angular/node_modules/jsonc-parser": { @@ -4291,11 +4200,11 @@ } }, "node_modules/@ionic/core": { - "version": "7.8.6", - "resolved": "https://registry.npmjs.org/@ionic/core/-/core-7.8.6.tgz", - "integrity": "sha512-HAYZdEmeJgOdo2kDlZkcCGHb+zs/vjU6iv4skbVBL7y+OnSv/oC2u83Yee8S3/aY0YAxkyBgu7hLTYH13Zc2Aw==", + "version": "8.2.5", + "resolved": "https://registry.npmjs.org/@ionic/core/-/core-8.2.5.tgz", + "integrity": "sha512-NhK5KfP5NL5NITibj8sOUlfI/ARNCF5rBu5HdIEfFe25MJkd0IYBQWjVaESFhSk7aB8pXEP8DIx1AHbT9e3Sog==", "dependencies": { - "@stencil/core": "^4.12.2", + "@stencil/core": "^4.19.2", "ionicons": "^7.2.2", "tslib": "^2.1.0" } diff --git a/package.json b/package.json index 6d7090a34..b3d280a85 100644 --- a/package.json +++ b/package.json @@ -72,7 +72,7 @@ "@awesome-cordova-plugins/sqlite": "^6.7.0", "@awesome-cordova-plugins/status-bar": "^6.7.0", "@awesome-cordova-plugins/web-intent": "^6.7.0", - "@ionic/angular": "^7.8.6", + "@ionic/angular": "^8.2.5", "@ionic/cordova-builders": "^11.0.0", "@moodlehq/cordova-plugin-advanced-http": "3.3.1-moodle.1", "@moodlehq/cordova-plugin-camera": "7.0.0-moodle.1", @@ -141,7 +141,7 @@ "@angular/cli": "^17.3.6", "@angular/compiler-cli": "^17.3.7", "@angular/language-service": "^17.3.7", - "@ionic/angular-toolkit": "^10.1.1", + "@ionic/angular-toolkit": "^11.0.1", "@ionic/cli": "^7.2.0", "@jsdevtools/coverage-istanbul-loader": "^3.0.5", "@types/faker": "^5.5.9", diff --git a/patches/@ionic+core+7.8.6.patch b/patches/@ionic+core+8.2.5.patch similarity index 95% rename from patches/@ionic+core+7.8.6.patch rename to patches/@ionic+core+8.2.5.patch index b88976d43..26270e1c8 100644 --- a/patches/@ionic+core+7.8.6.patch +++ b/patches/@ionic+core+8.2.5.patch @@ -1,5 +1,5 @@ diff --git a/node_modules/@ionic/core/components/popover.js b/node_modules/@ionic/core/components/popover.js -index 21fb3e3..52ea4a6 100644 +index 19b79c4..67289f4 100644 --- a/node_modules/@ionic/core/components/popover.js +++ b/node_modules/@ionic/core/components/popover.js @@ -763,8 +763,10 @@ const iosEnterAnimation = (baseEl, opts) => { @@ -29,10 +29,10 @@ index 21fb3e3..52ea4a6 100644 const contentEl = root.querySelector('.popover-content'); const referenceSizeEl = trigger || ((_a = ev === null || ev === void 0 ? void 0 : ev.detail) === null || _a === void 0 ? void 0 : _a.ionShadowTarget) || (ev === null || ev === void 0 ? void 0 : ev.target); diff --git a/node_modules/@ionic/core/dist/cjs/ion-popover.cjs.entry.js b/node_modules/@ionic/core/dist/cjs/ion-popover.cjs.entry.js -index 68a908b..050e544 100644 +index 2dcf484..54aeac9 100644 --- a/node_modules/@ionic/core/dist/cjs/ion-popover.cjs.entry.js +++ b/node_modules/@ionic/core/dist/cjs/ion-popover.cjs.entry.js -@@ -768,8 +768,10 @@ const iosEnterAnimation = (baseEl, opts) => { +@@ -769,8 +769,10 @@ const iosEnterAnimation = (baseEl, opts) => { const { event: ev, size, trigger, reference, side, align } = opts; const doc = baseEl.ownerDocument; const isRTL = doc.dir === 'rtl'; @@ -45,7 +45,7 @@ index 68a908b..050e544 100644 const root = helpers.getElementRoot(baseEl); const contentEl = root.querySelector('.popover-content'); const arrowEl = root.querySelector('.popover-arrow'); -@@ -889,8 +891,10 @@ const mdEnterAnimation = (baseEl, opts) => { +@@ -890,8 +892,10 @@ const mdEnterAnimation = (baseEl, opts) => { const { event: ev, size, trigger, reference, side, align } = opts; const doc = baseEl.ownerDocument; const isRTL = doc.dir === 'rtl'; @@ -93,10 +93,10 @@ index 603923a..ff10a25 100644 const contentEl = root.querySelector('.popover-content'); const referenceSizeEl = trigger || ((_a = ev === null || ev === void 0 ? void 0 : ev.detail) === null || _a === void 0 ? void 0 : _a.ionShadowTarget) || (ev === null || ev === void 0 ? void 0 : ev.target); diff --git a/node_modules/@ionic/core/dist/esm/ion-popover.entry.js b/node_modules/@ionic/core/dist/esm/ion-popover.entry.js -index 839e91c..abcd28f 100644 +index 8ca76cf..c5b990a 100644 --- a/node_modules/@ionic/core/dist/esm/ion-popover.entry.js +++ b/node_modules/@ionic/core/dist/esm/ion-popover.entry.js -@@ -764,8 +764,10 @@ const iosEnterAnimation = (baseEl, opts) => { +@@ -765,8 +765,10 @@ const iosEnterAnimation = (baseEl, opts) => { const { event: ev, size, trigger, reference, side, align } = opts; const doc = baseEl.ownerDocument; const isRTL = doc.dir === 'rtl'; @@ -109,7 +109,7 @@ index 839e91c..abcd28f 100644 const root = getElementRoot(baseEl); const contentEl = root.querySelector('.popover-content'); const arrowEl = root.querySelector('.popover-arrow'); -@@ -885,8 +887,10 @@ const mdEnterAnimation = (baseEl, opts) => { +@@ -886,8 +888,10 @@ const mdEnterAnimation = (baseEl, opts) => { const { event: ev, size, trigger, reference, side, align } = opts; const doc = baseEl.ownerDocument; const isRTL = doc.dir === 'rtl'; @@ -123,10 +123,10 @@ index 839e91c..abcd28f 100644 const contentEl = root.querySelector('.popover-content'); const referenceSizeEl = trigger || ((_a = ev === null || ev === void 0 ? void 0 : ev.detail) === null || _a === void 0 ? void 0 : _a.ionShadowTarget) || (ev === null || ev === void 0 ? void 0 : ev.target); diff --git a/node_modules/@ionic/core/hydrate/index.js b/node_modules/@ionic/core/hydrate/index.js -index 7f898c7..a3a7669 100644 +index 5a50b98..884e2ce 100644 --- a/node_modules/@ionic/core/hydrate/index.js +++ b/node_modules/@ionic/core/hydrate/index.js -@@ -29254,8 +29254,10 @@ const iosEnterAnimation$1 = (baseEl, opts) => { +@@ -23702,8 +23702,10 @@ const iosEnterAnimation$1 = (baseEl, opts) => { const { event: ev, size, trigger, reference, side, align } = opts; const doc = baseEl.ownerDocument; const isRTL = doc.dir === 'rtl'; @@ -139,7 +139,7 @@ index 7f898c7..a3a7669 100644 const root = getElementRoot(baseEl); const contentEl = root.querySelector('.popover-content'); const arrowEl = root.querySelector('.popover-arrow'); -@@ -29375,8 +29377,10 @@ const mdEnterAnimation$1 = (baseEl, opts) => { +@@ -23823,8 +23825,10 @@ const mdEnterAnimation$1 = (baseEl, opts) => { const { event: ev, size, trigger, reference, side, align } = opts; const doc = baseEl.ownerDocument; const isRTL = doc.dir === 'rtl'; diff --git a/src/addons/calendar/components/calendar/calendar.scss b/src/addons/calendar/components/calendar/calendar.scss index 1bdc04ba7..076847ba3 100644 --- a/src/addons/calendar/components/calendar/calendar.scss +++ b/src/addons/calendar/components/calendar/calendar.scss @@ -150,6 +150,6 @@ } } -:host-context(html.dark) { +:host-context(:root.dark) { --addon-calendar-blank-day-background-color: var(--gray-900); } diff --git a/src/addons/calendar/services/calendar-helper.ts b/src/addons/calendar/services/calendar-helper.ts index be7426e56..7f32071b2 100644 --- a/src/addons/calendar/services/calendar-helper.ts +++ b/src/addons/calendar/services/calendar-helper.ts @@ -294,27 +294,6 @@ export class AddonCalendarHelperProvider { } } - /** - * Format reminders, adding calculated data. - * - * @param reminders Reminders. - * @param timestart Event timestart. - * @param siteId Site ID. - * @returns Formatted reminders. - * @deprecated since 4.1 Use AddonCalendarHelper.getEventReminders. - */ - async formatReminders( - reminders: { eventid: number }[], - timestart: number, - siteId?: string, - ): Promise { - if (!reminders.length) { - return []; - } - - return AddonCalendarHelper.getEventReminders(reminders[0].eventid, timestart, siteId); - } - /** * Format reminders, adding calculated data. * diff --git a/src/addons/calendar/services/calendar.ts b/src/addons/calendar/services/calendar.ts index 0b0633094..db0bc8437 100644 --- a/src/addons/calendar/services/calendar.ts +++ b/src/addons/calendar/services/calendar.ts @@ -45,10 +45,7 @@ import { CoreReminders, CoreRemindersPushNotificationData, CoreRemindersService, - CoreRemindersUnits, - CoreReminderValueAndUnit, } from '@features/reminders/services/reminders'; -import { CoreReminderDBRecord } from '@features/reminders/services/database/reminders'; import { CoreEvents } from '@singletons/events'; import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site'; import { ADDON_CALENDAR_COMPONENT } from '../constants'; @@ -66,18 +63,6 @@ export enum AddonCalendarEventType { USER = 'user', } -/** - * Units to set a reminder. - * - * @deprecated since 4.1 Use CoreReminderUnits instead. - */ -export enum AddonCalendarReminderUnits { - MINUTE = CoreConstants.SECONDS_MINUTE, - HOUR = CoreConstants.SECONDS_HOUR, - DAY = CoreConstants.SECONDS_DAY, - WEEK = CoreConstants.SECONDS_WEEK, -} - declare module '@singletons/events' { /** @@ -178,17 +163,6 @@ export class AddonCalendarProvider { return !!site?.isVersionGreaterEqualThan('3.7.1'); } - /** - * Given a number of seconds, convert it to a unit&value format compatible with reminders. - * - * @param seconds Number of seconds. - * @returns Value and unit. - * @deprecated since 4.1 Use CoreRemindersService.convertSecondsToValueAndUnit instead. - */ - static convertSecondsToValueAndUnit(seconds: number): CoreReminderValueAndUnit { - return CoreRemindersService.convertSecondsToValueAndUnit(seconds); - } - /** * Delete an event. * @@ -592,17 +566,6 @@ export class AddonCalendarProvider { return CoreTimeUtils.userDate(time, 'core.strftimedayshort'); } - /** - * Get the configured default notification time. - * - * @param siteId ID of the site. If not defined, use current site. - * @returns Promise resolved with the default time (in seconds). - * @deprecated since 4.1 Use CoreReminders.getDefaultNotificationTime instead. - */ - async getDefaultNotificationTime(siteId?: string): Promise { - return CoreReminders.getDefaultNotificationTime(siteId); - } - /** * Get a calendar event. If the server request fails and data is not cached, try to get it from local DB. * @@ -780,18 +743,6 @@ export class AddonCalendarProvider { return event.eventtype; } - /** - * Remove an event reminder and cancel the notification. - * - * @param id Reminder ID. - * @param siteId ID of the site the event belongs to. If not defined, use current site. - * @returns Promise resolved when the notification is updated. - * @deprecated since 4.1. Use CoreReminders.removeReminder instead. - */ - async deleteEventReminder(id: number, siteId?: string): Promise { - await CoreReminders.removeReminder(id, siteId); - } - /** * Get calendar events for a certain day. * @@ -876,21 +827,6 @@ export class AddonCalendarProvider { (categoryId ? categoryId : ''); } - /** - * Get a calendar reminders from local Db. - * - * @param eventId Event ID. - * @param siteId ID of the site the event belongs to. If not defined, use current site. - * @returns Promise resolved when the event data is retrieved. - * @deprecated since 4.1. Use CoreReminders.getReminders instead. - */ - async getEventReminders(eventId: number, siteId?: string): Promise { - return CoreReminders.getReminders({ - instanceId: eventId, - component: ADDON_CALENDAR_COMPONENT, - }, siteId); - } - /** * Get the events in a certain period. The period is calculated like this: * start time: now + daysToStart @@ -1089,19 +1025,6 @@ export class AddonCalendarProvider { (categoryId ? categoryId : ''); } - /** - * Given a value and a unit, return the translated label. - * - * @param value Value. - * @param unit Unit. - * @param addDefaultLabel Whether to add the "Default" text. - * @returns Translated label. - * @deprecated since 4.1 Use CoreReminders.getUnitValueLabel instead. - */ - getUnitValueLabel(value: number, unit: CoreRemindersUnits, addDefaultLabel = false): string { - return CoreReminders.getUnitValueLabel(value, unit, addDefaultLabel); - } - /** * Get upcoming calendar events. * @@ -1378,16 +1301,6 @@ export class AddonCalendarProvider { return this.isCalendarDisabledInSite(site); } - /** - * Get the next events for all the sites and schedules their notifications. - * - * @returns Promise resolved when done. - * @deprecated since 4.1 Use AddonCalendar.updateAllSitesEventReminders. - */ - async scheduleAllSitesEventsNotifications(): Promise { - await AddonCalendar.updateAllSitesEventReminders(); - } - /** * Get the next events for all the sites and updates their reminders. */ @@ -1415,21 +1328,6 @@ export class AddonCalendarProvider { await this.getEventsList(undefined, undefined, undefined, siteId); } - /** - * Get the next events for all the sites and schedules their notifications. - * - * @returns Promise resolved when done. - * @deprecated since 4.1. No replacement for that function. - */ - async scheduleEventsNotifications( - events: ({ id: number; timestart: number; timeduration: number; name: string})[], - siteId?: string, - ): Promise { - siteId = siteId || CoreSites.getCurrentSiteId(); - - await AddonCalendar.updateEventsReminders(events, siteId); - } - /** * Schedules the notifications for a list of events. * If an event notification time is 0, cancel its scheduled notification (if any). @@ -1470,18 +1368,6 @@ export class AddonCalendarProvider { })); } - /** - * Set the default notification time. - * - * @param time New default time. - * @param siteId ID of the site. If not defined, use current site. - * @returns Promise resolved when stored. - * @deprecated since 4.1 Use CoreReminders.setDefaultNotificationTime. - */ - async setDefaultNotificationTime(time: number, siteId?: string): Promise { - await CoreReminders.setDefaultNotificationTime(time, siteId); - } - /** * Store an event in local DB as it is. * @@ -2203,13 +2089,6 @@ export type AddonCalendarUpdatedEventEvent = { sent?: boolean; }; -/** - * Value and unit for reminders. - * - * @deprecated since 4.1, use CoreReminderValueAndUnit instead. - */ -export type AddonCalendarValueAndUnit = CoreReminderValueAndUnit; - /** * Options to pass to submit event. */ diff --git a/src/addons/messages/pages/discussion/discussion.html b/src/addons/messages/pages/discussion/discussion.html index 0524b379a..6425cc125 100644 --- a/src/addons/messages/pages/discussion/discussion.html +++ b/src/addons/messages/pages/discussion/discussion.html @@ -77,7 +77,7 @@ {{ message.timecreated | coreFormatDate: "strftimedayshort" }} - + {{ 'addon.messages.newmessages' | translate }} diff --git a/src/addons/messages/tests/behat/snapshots/test-basic-usage-of-messages-in-app-view-recent-conversations-and-contacts_30.png b/src/addons/messages/tests/behat/snapshots/test-basic-usage-of-messages-in-app-view-recent-conversations-and-contacts_30.png index 80a903af6..c324279ef 100644 Binary files a/src/addons/messages/tests/behat/snapshots/test-basic-usage-of-messages-in-app-view-recent-conversations-and-contacts_30.png and b/src/addons/messages/tests/behat/snapshots/test-basic-usage-of-messages-in-app-view-recent-conversations-and-contacts_30.png differ diff --git a/src/addons/mod/assign/components/submission/submission.scss b/src/addons/mod/assign/components/submission/submission.scss index ba7e1b126..d2642ed7f 100644 --- a/src/addons/mod/assign/components/submission/submission.scss +++ b/src/addons/mod/assign/components/submission/submission.scss @@ -40,7 +40,7 @@ } } -:host-context(html.dark) ::ng-deep { +:host-context(:root.dark) ::ng-deep { ion-item.submissioneditable p { color: var(--danger-tint); } diff --git a/src/addons/mod/assign/components/submission/submission.ts b/src/addons/mod/assign/components/submission/submission.ts index 9e6011c32..420b69701 100644 --- a/src/addons/mod/assign/components/submission/submission.ts +++ b/src/addons/mod/assign/components/submission/submission.ts @@ -449,7 +449,7 @@ export class AddonModAssignSubmissionComponent implements OnInit, OnDestroy, Can this.feedback, this.submitId, ); - } catch (error) { + } catch { // Error ocurred, consider there are no changes. return false; } diff --git a/src/addons/mod/assign/pages/submission-review/submission-review.html b/src/addons/mod/assign/pages/submission-review/submission-review.html index fe477e715..dd7d7950a 100644 --- a/src/addons/mod/assign/pages/submission-review/submission-review.html +++ b/src/addons/mod/assign/pages/submission-review/submission-review.html @@ -13,7 +13,7 @@ - + {{ 'core.done' | translate }} diff --git a/src/addons/mod/assign/tests/behat/marking_workflow.feature b/src/addons/mod/assign/tests/behat/marking_workflow.feature index 5bb39e488..2e9b33534 100755 --- a/src/addons/mod/assign/tests/behat/marking_workflow.feature +++ b/src/addons/mod/assign/tests/behat/marking_workflow.feature @@ -100,6 +100,7 @@ Feature: Test marking workflow in assignment activity in app And I press "Grade" in the app When I set the field "Grade out of 100" to "60" in the app And I press "Done" in the app + And I wait loading to finish in the app And I press "Student1" in the app And I press "Grade" in the app Then I should find "60 / 100" within "Current grade in assignment" "ion-item" in the app @@ -112,6 +113,7 @@ Feature: Test marking workflow in assignment activity in app And I press "Grade" in the app When I set the field "Grade out of 100" to "80" in the app And I press "Done" in the app + And I wait loading to finish in the app And I press "Student3" in the app And I press "Grade" in the app Then I should find "80" within "Current grade in gradebook" "ion-item" in the app diff --git a/src/addons/mod/bigbluebuttonbn/components/index/index.scss b/src/addons/mod/bigbluebuttonbn/components/index/index.scss index 1aac75966..b586d6845 100644 --- a/src/addons/mod/bigbluebuttonbn/components/index/index.scss +++ b/src/addons/mod/bigbluebuttonbn/components/index/index.scss @@ -24,7 +24,7 @@ } } -:host-context(html.dark) { +:host-context(:root.dark) { --recording-details-background: var(--gray-800); --recording-details-border: var(--gray-500); } diff --git a/src/addons/mod/bigbluebuttonbn/tests/behat/basic_usage.feature b/src/addons/mod/bigbluebuttonbn/tests/behat/basic_usage.feature index 84e49873b..9ca94cf76 100755 --- a/src/addons/mod/bigbluebuttonbn/tests/behat/basic_usage.feature +++ b/src/addons/mod/bigbluebuttonbn/tests/behat/basic_usage.feature @@ -49,6 +49,8 @@ Feature: Test basic usage of BBB activity in app And I should be able to press "Join session" in the app When I press "Join session" in the app + # TODO: This step will make behat github actions work but we should find a better way to wait for the room to start. + And I wait "3" seconds And I wait for the BigBlueButton room to start And I switch back to the app Then I should find "The session is in progress." in the app @@ -68,6 +70,8 @@ Feature: Test basic usage of BBB activity in app And I should be able to press "Join session" in the app When I press "Join session" in the app + # TODO: This step will make behat github actions work but we should find a better way to wait for the room to start. + And I wait "3" seconds And I wait for the BigBlueButton room to start And I switch back to the app Then I should find "The session is in progress." in the app diff --git a/src/addons/mod/book/tests/behat/snapshots/test-basic-usage-of-book-activity-in-app-open-chapters-from-table-of-contents_11.png b/src/addons/mod/book/tests/behat/snapshots/test-basic-usage-of-book-activity-in-app-open-chapters-from-table-of-contents_11.png index 1a1b3c1de..2f932c02b 100644 Binary files a/src/addons/mod/book/tests/behat/snapshots/test-basic-usage-of-book-activity-in-app-open-chapters-from-table-of-contents_11.png and b/src/addons/mod/book/tests/behat/snapshots/test-basic-usage-of-book-activity-in-app-open-chapters-from-table-of-contents_11.png differ diff --git a/src/addons/mod/h5pactivity/pages/attempt-results/attempt-results.scss b/src/addons/mod/h5pactivity/pages/attempt-results/attempt-results.scss index a9021111d..e8045e634 100644 --- a/src/addons/mod/h5pactivity/pages/attempt-results/attempt-results.scss +++ b/src/addons/mod/h5pactivity/pages/attempt-results/attempt-results.scss @@ -35,7 +35,7 @@ } } -:host-context(html.dark) { +:host-context(:root.dark) { .addon-mod_h5pactivity-result-table-row.item:nth-child(even) { --background: var(--gray-900); } diff --git a/src/addons/mod/lesson/components/index/addon-mod-lesson-index.html b/src/addons/mod/lesson/components/index/addon-mod-lesson-index.html index acdf9307a..6478c5c9f 100644 --- a/src/addons/mod/lesson/components/index/addon-mod-lesson-index.html +++ b/src/addons/mod/lesson/components/index/addon-mod-lesson-index.html @@ -31,7 +31,7 @@ - + diff --git a/src/addons/mod/lesson/pages/player/player.scss b/src/addons/mod/lesson/pages/player/player.scss index 2090c01ed..4afb34c08 100644 --- a/src/addons/mod/lesson/pages/player/player.scss +++ b/src/addons/mod/lesson/pages/player/player.scss @@ -2,7 +2,7 @@ --background-odd: var(--light); } -:host-context(html.dark) { +:host-context(:root.dark) { --background-odd: var(--medium); } diff --git a/src/addons/mod/quiz/accessrules/password/component/addon-mod-quiz-access-password.html b/src/addons/mod/quiz/accessrules/password/component/addon-mod-quiz-access-password.html index b2d553869..4e7738556 100644 --- a/src/addons/mod/quiz/accessrules/password/component/addon-mod-quiz-access-password.html +++ b/src/addons/mod/quiz/accessrules/password/component/addon-mod-quiz-access-password.html @@ -8,6 +8,6 @@ - + diff --git a/src/addons/mod/quiz/pages/player/player.html b/src/addons/mod/quiz/pages/player/player.html index b9c3574f1..e3de19c9b 100644 --- a/src/addons/mod/quiz/pages/player/player.html +++ b/src/addons/mod/quiz/pages/player/player.html @@ -11,7 +11,7 @@ - diff --git a/src/addons/mod/quiz/tests/behat/basic_usage.feature b/src/addons/mod/quiz/tests/behat/basic_usage.feature index d02d3e1e2..0c6b90692 100755 --- a/src/addons/mod/quiz/tests/behat/basic_usage.feature +++ b/src/addons/mod/quiz/tests/behat/basic_usage.feature @@ -167,12 +167,16 @@ Feature: Attempt a quiz in app And I press "Three" in the app And I set the field "Answer" to "Berlin" in the app And I press "Next" in the app + And I wait loading to finish in the app And I set the field "Answer" to "testing" in the app And I press "Next" in the app + And I wait loading to finish in the app And I set the field "Answer" to "5" in the app And I press "Next" in the app + And I wait loading to finish in the app And I set the field "Answer" to "Testing an essay" in the app And I press "Next" "ion-button" in the app + And I wait loading to finish in the app And I press "quick" ".drag" in the app And I click on ".place1.drop" "css" And I press "fox" ".drag" in the app @@ -180,26 +184,33 @@ Feature: Attempt a quiz in app And I press "lazy" ".drag" in the app And I click on ".place3.drop" "css" And I press "Next" in the app + And I wait loading to finish in the app And I press "True" in the app And I press "Next" in the app + And I wait loading to finish in the app And I set the field "frog" to "amphibian" in the app And I set the field "newt" to "insect" in the app And I set the field "cat" to "mammal" in the app And I press "Next" in the app + And I wait loading to finish in the app Then I should find "Text of the eighth question" in the app When I press "Next" in the app + And I wait loading to finish in the app And I set the field "Blank 1" to "cat" in the app And I set the field "Blank 2" to "mat" in the app And I press "Next" in the app + And I wait loading to finish in the app And I press "abyssal" ".drag" in the app And I click on ".place6.dropzone" "css" And I press "trench" ".drag" in the app And I click on ".place3.dropzone" "css" And I press "Next" in the app + And I wait loading to finish in the app And I press "Railway station" ".marker" in the app And I click on "img.dropbackground" "css" And I press "Submit" in the app + And I wait loading to finish in the app Then I should find "Answer saved" in the app And I should find "Incomplete answer" within "10" "ion-item" in the app But I should not find "Not yet answered" in the app @@ -224,8 +235,10 @@ Feature: Attempt a quiz in app When I press "True" in the app And I press "Next" in the app + And I wait loading to finish in the app And I press "False" in the app And I press "Submit" in the app + And I wait loading to finish in the app And I press "Submit all and finish" in the app Then I should find "Once you submit" in the app But I should not find "Questions without a response" in the app diff --git a/src/addons/mod/quiz/tests/behat/snapshots/attempt-a-quiz-in-app-submit-a-quiz--review-a-quiz-attempt_40.png b/src/addons/mod/quiz/tests/behat/snapshots/attempt-a-quiz-in-app-submit-a-quiz--review-a-quiz-attempt_42.png similarity index 100% rename from src/addons/mod/quiz/tests/behat/snapshots/attempt-a-quiz-in-app-submit-a-quiz--review-a-quiz-attempt_40.png rename to src/addons/mod/quiz/tests/behat/snapshots/attempt-a-quiz-in-app-submit-a-quiz--review-a-quiz-attempt_42.png diff --git a/src/addons/mod/survey/components/index/index.scss b/src/addons/mod/survey/components/index/index.scss index 42e6f410c..9782bbfa1 100644 --- a/src/addons/mod/survey/components/index/index.scss +++ b/src/addons/mod/survey/components/index/index.scss @@ -25,7 +25,7 @@ } } -:host-context(html.dark) { +:host-context(:root.dark) { --grid-background: var(--gray-900); --even-background: var(--medium); } diff --git a/src/addons/mod/wiki/components/index/index.scss b/src/addons/mod/wiki/components/index/index.scss index e2a7ffaac..7ae6942ed 100644 --- a/src/addons/mod/wiki/components/index/index.scss +++ b/src/addons/mod/wiki/components/index/index.scss @@ -56,7 +56,7 @@ $addon-mod-wiki-toc-level-padding: 12px !default; } } -:host-context(html.dark) { +:host-context(:root.dark) { --addon-mod-wiki-newentry-link-color: var(--danger-tint); --addon-mod-wiki-toc-background-color: var(--medium); } diff --git a/src/addons/mod/workshop/pages/submission/submission.html b/src/addons/mod/workshop/pages/submission/submission.html index 6c5a1afb1..dde29a697 100644 --- a/src/addons/mod/workshop/pages/submission/submission.html +++ b/src/addons/mod/workshop/pages/submission/submission.html @@ -10,8 +10,7 @@ - + {{ 'core.save' | translate }} diff --git a/src/addons/notes/pages/list/list.html b/src/addons/notes/pages/list/list.html index 058c56ec6..7cdafa23f 100644 --- a/src/addons/notes/pages/list/list.html +++ b/src/addons/notes/pages/list/list.html @@ -11,7 +11,8 @@ - + diff --git a/src/addons/notifications/services/notifications.ts b/src/addons/notifications/services/notifications.ts index c25c81fa1..49ed2a791 100644 --- a/src/addons/notifications/services/notifications.ts +++ b/src/addons/notifications/services/notifications.ts @@ -209,72 +209,6 @@ export class AddonNotificationsProvider { return ROOT_CACHE_KEY + 'list'; } - /** - * Get some notifications. - * - * @param notifications Current list of loaded notifications. It's used to calculate the offset. - * @param options Other options. - * @returns Promise resolved with notifications and if can load more. - * @deprecated since 4.1. Use getNotificationsWithStatus instead. - */ - async getNotifications( - notifications: AddonNotificationsNotificationMessageFormatted[], - options?: AddonNotificationsGetNotificationsOptions, - ): Promise<{notifications: AddonNotificationsNotificationMessageFormatted[]; canLoadMore: boolean}> { - - notifications = notifications || []; - options = options || {}; - options.limit = options.limit || AddonNotificationsProvider.LIST_LIMIT; - options.siteId = options.siteId || CoreSites.getCurrentSiteId(); - let newNotifications: AddonNotificationsNotificationMessageFormatted[]; - - // Request 1 more notification so we can know if there are more notifications. - const originalLimit = options.limit; - options.limit = options.limit + 1; - - const site = await CoreSites.getSite(options.siteId); - - if (site.isVersionGreaterEqualThan('4.0')) { - // In 4.0 the app can request read and unread at the same time. - options.offset = notifications.length; - newNotifications = await this.getNotificationsWithStatus( - AddonNotificationsGetReadType.BOTH, - options, - ); - } else { - // We need 2 calls, one for read and the other one for unread. - options.offset = notifications.reduce((total, current) => total + (current.read ? 0 : 1), 0); - - const unread = await this.getNotificationsWithStatus(AddonNotificationsGetReadType.UNREAD, options); - - newNotifications = unread; - - if (unread.length < options.limit) { - // Limit not reached. Get read notifications until reach the limit. - const readOptions = { - ...options, - offset: notifications.length - options.offset, - limit: options.limit - unread.length, - }; - - try { - const read = await this.getNotificationsWithStatus(AddonNotificationsGetReadType.READ, readOptions); - - newNotifications = unread.concat(read); - } catch (error) { - if (unread.length <= 0) { - throw error; - } - } - } - } - - return { - notifications: newNotifications.slice(0, originalLimit), - canLoadMore: newNotifications.length > originalLimit, - }; - } - /** * Get notifications from site. * diff --git a/src/core/classes/errors/siteerror.ts b/src/core/classes/errors/siteerror.ts index 3eed531e6..9e1f2f569 100644 --- a/src/core/classes/errors/siteerror.ts +++ b/src/core/classes/errors/siteerror.ts @@ -31,7 +31,7 @@ export class CoreSiteError extends CoreError { } /** - * @deprecated This getter should not be called directly, but it's defined for backwards compatibility with many + * @deprecated since 4.4. This getter should not be called directly, but it's defined for backwards compatibility with many * parts of the code that type errors as any and use it. We cannot rename those because the errors could also be * CoreWSError instances which do have an "errorcode" property. * diff --git a/src/core/classes/promised-value.ts b/src/core/classes/promised-value.ts index 24f173224..d437e841b 100644 --- a/src/core/classes/promised-value.ts +++ b/src/core/classes/promised-value.ts @@ -55,14 +55,6 @@ export class CorePromisedValue extends CorePromise { this.rejectPromise = rejectPromise; } - /** - * @returns Promise. - * @deprecated since 4.1. The instance can be directly used as a promise. - */ - get promise(): Promise { - return this; - } - get value(): T | null { return this.resolvedValue ?? null; } diff --git a/src/core/classes/sites/site.ts b/src/core/classes/sites/site.ts index 2a8af678a..80e6c07e3 100644 --- a/src/core/classes/sites/site.ts +++ b/src/core/classes/sites/site.ts @@ -475,23 +475,6 @@ export class CoreSite extends CoreAuthenticatedSite { await this.openWithAutoLogin(false, url, options, alertMessage); } - /** - * Open a URL in browser using auto-login in the Moodle site if available and the URL belongs to the site. - * - * @param url The URL to open. - * @param alertMessage If defined, an alert will be shown before opening the browser. - * @param options Other options. - * @returns Promise resolved when done, rejected otherwise. - * @deprecated since 4.1. Use openInBrowserWithAutoLogin instead, now it always checks that URL belongs to same site. - */ - async openInBrowserWithAutoLoginIfSameSite( - url: string, - alertMessage?: string, - options: CoreUtilsOpenInBrowserOptions = {}, - ): Promise { - return this.openInBrowserWithAutoLogin(url, alertMessage, options); - } - /** * Open a URL in inappbrowser using auto-login in the Moodle site if available. * @@ -506,23 +489,6 @@ export class CoreSite extends CoreAuthenticatedSite { return iabInstance; } - /** - * Open a URL in inappbrowser using auto-login in the Moodle site if available and the URL belongs to the site. - * - * @param url The URL to open. - * @param options Override default options passed to inappbrowser. - * @param alertMessage If defined, an alert will be shown before opening the inappbrowser. - * @returns Promise resolved when done. - * @deprecated since 4.1. Use openInAppWithAutoLogin instead, now it always checks that URL belongs to same site. - */ - async openInAppWithAutoLoginIfSameSite( - url: string, - options?: InAppBrowserOptions, - alertMessage?: string, - ): Promise { - return this.openInAppWithAutoLogin(url, options, alertMessage); - } - /** * Open a URL in browser or InAppBrowser using auto-login in the Moodle site if available. * @@ -575,25 +541,6 @@ export class CoreSite extends CoreAuthenticatedSite { } } - /** - * Open a URL in browser or InAppBrowser using auto-login in the Moodle site if available and the URL belongs to the site. - * - * @param inApp True to open it in InAppBrowser, false to open in browser. - * @param url The URL to open. - * @param options Override default options passed to inappbrowser. - * @param alertMessage If defined, an alert will be shown before opening the browser/inappbrowser. - * @returns Promise resolved when done. Resolve param is returned only if inApp=true. - * @deprecated since 4.1. Use openWithAutoLogin instead, now it always checks that URL belongs to same site. - */ - async openWithAutoLoginIfSameSite( - inApp: boolean, - url: string, - options: InAppBrowserOptions & CoreUtilsOpenInBrowserOptions = {}, - alertMessage?: string, - ): Promise { - return this.openWithAutoLogin(inApp, url, options, alertMessage); - } - /** * Get the config of this site. * It is recommended to use getStoredConfig instead since it's faster and doesn't use network. diff --git a/src/core/components/combobox/combobox.scss b/src/core/components/combobox/combobox.scss index a42acf707..dec9eec50 100644 --- a/src/core/components/combobox/combobox.scss +++ b/src/core/components/combobox/combobox.scss @@ -146,7 +146,7 @@ } .select-icon { - color: var(--ion-color-step-500, gray); + color: var(--ion-text-color-step-500, gray); } } diff --git a/src/core/components/components.module.ts b/src/core/components/components.module.ts index 8055d6e70..23b32cf00 100644 --- a/src/core/components/components.module.ts +++ b/src/core/components/components.module.ts @@ -97,7 +97,7 @@ import { CoreSitesListComponent } from './sites-list/sites-list'; CoreProgressBarComponent, CoreRecaptchaComponent, CoreSendMessageFormComponent, - CoreShowPasswordComponent, + CoreShowPasswordComponent, // eslint-disable-line deprecation/deprecation CoreSitePickerComponent, CoreSplitViewComponent, // eslint-disable-next-line deprecation/deprecation @@ -153,7 +153,7 @@ import { CoreSitesListComponent } from './sites-list/sites-list'; CoreProgressBarComponent, CoreRecaptchaComponent, CoreSendMessageFormComponent, - CoreShowPasswordComponent, + CoreShowPasswordComponent, // eslint-disable-line deprecation/deprecation CoreSitePickerComponent, CoreSplitViewComponent, // eslint-disable-next-line deprecation/deprecation diff --git a/src/core/components/context-menu/core-context-menu.html b/src/core/components/context-menu/core-context-menu.html index dee543e37..175bcd677 100644 --- a/src/core/components/context-menu/core-context-menu.html +++ b/src/core/components/context-menu/core-context-menu.html @@ -1,4 +1,4 @@ - diff --git a/src/core/components/empty-box/empty-box.scss b/src/core/components/empty-box/empty-box.scss index b79b0305d..e87befd6e 100644 --- a/src/core/components/empty-box/empty-box.scss +++ b/src/core/components/empty-box/empty-box.scss @@ -38,7 +38,7 @@ } } -:host-context(html.dark) { +:host-context(:root.dark) { &.dimmed { --text-color: var(--gray-300); } diff --git a/src/core/components/mod-icon/mod-icon.scss b/src/core/components/mod-icon/mod-icon.scss index fb23300c9..24bfad6fe 100644 --- a/src/core/components/mod-icon/mod-icon.scss +++ b/src/core/components/mod-icon/mod-icon.scss @@ -78,7 +78,7 @@ --margin-end: 12px; } -:host-context(html.dark) { +:host-context(:root.dark) { &.version_40:not(.colorize), &.version_current { background-color: var(--white); diff --git a/src/core/components/navbar-buttons/navbar-buttons.ts b/src/core/components/navbar-buttons/navbar-buttons.ts index 349377eec..631732347 100644 --- a/src/core/components/navbar-buttons/navbar-buttons.ts +++ b/src/core/components/navbar-buttons/navbar-buttons.ts @@ -40,12 +40,12 @@ const BUTTON_HIDDEN_CLASS = 'core-navbar-button-hidden'; * * You can use the [hidden] input to hide all the inner buttons if a certain condition is met. * - * IMPORTANT: Do not use *ngIf in the buttons inside this component, it can cause problems. Please use [hidden] instead. + * IMPORTANT: Do not use *ngIf in the buttons inside this component, it can cause problems. Please use [class.hidden] instead. * * Example usage: * * - * + * * * * diff --git a/src/core/components/password-modal/password-modal.html b/src/core/components/password-modal/password-modal.html index 8b1b77ef6..a8c99151d 100644 --- a/src/core/components/password-modal/password-modal.html +++ b/src/core/components/password-modal/password-modal.html @@ -17,7 +17,7 @@ - + diff --git a/src/core/components/show-password/core-show-password.html b/src/core/components/show-password/core-show-password.html index 21642a1ce..715bd5bf0 100644 --- a/src/core/components/show-password/core-show-password.html +++ b/src/core/components/show-password/core-show-password.html @@ -1,5 +1,2 @@ - - + diff --git a/src/core/components/show-password/show-password.scss b/src/core/components/show-password/show-password.scss deleted file mode 100644 index ec8244fb6..000000000 --- a/src/core/components/show-password/show-password.scss +++ /dev/null @@ -1,31 +0,0 @@ -@use "theme/globals" as *; - -:host { - display: contents; - - // Only applies to deprecated way (surrounding). - ::ng-deep ion-input + ion-button { - background: transparent; - padding: 0 var(--inner-padding-end) 0 4px; - margin-top: 0; - margin-bottom: 0; - position: absolute; - @include safe-area-position(null, 0px, null, null); - top: 0; - } - - // Only applies to deprecated way (surrounding). - ::ng-deep ion-input { - --padding-end: 56px !important; - } - - ::ng-deep ion-input.input-label-placement-stacked + ion-button { - top: 14px; - } - -} - -ion-button { - z-index: 5; - pointer-events: visible; -} diff --git a/src/core/components/show-password/show-password.ts b/src/core/components/show-password/show-password.ts index 506f50e6d..88bdcc81f 100644 --- a/src/core/components/show-password/show-password.ts +++ b/src/core/components/show-password/show-password.ts @@ -12,173 +12,80 @@ // See the License for the specific language governing permissions and // limitations under the License. -import { Component, OnInit, AfterViewInit, Input, ElementRef, ContentChild } from '@angular/core'; +import { Component, AfterViewInit, Input, ContentChild, ViewEncapsulation } from '@angular/core'; import { IonInput } from '@ionic/angular'; - -import { CorePlatform } from '@services/platform'; import { CoreDomUtils } from '@services/utils/dom'; + import { CoreUtils } from '@services/utils/utils'; import { CoreLogger } from '@singletons/logger'; /** * This component allows to show/hide a password. - * It's meant to be used with ion-input. - * It's recommended to use it as a slot of the input. + * It's meant to be used with ion-input as a slot of the input. * * @description * * There are 2 ways to use ths component: * - Slot it to start or end on the ion-input element. - * - Surround the ion-input with the password with this component. This is deprecated. - * - * In order to help finding the input you can specify the name of the input or the ion-input element. - * + * - Surround the ion-input with the password with this component. Not recommended. * * Example of new usage: * - * + * * * * - * Example deprecated usage: + * Example surrounding usage: * * - * + * * + * + * @deprecated since 4.5. Use instead. */ @Component({ selector: 'core-show-password', templateUrl: 'core-show-password.html', - styleUrls: ['show-password.scss'], + styles: 'core-show-password { display: contents; }', + encapsulation: ViewEncapsulation.None, }) -export class CoreShowPasswordComponent implements OnInit, AfterViewInit { - - @Input() initialShown?: boolean | string; // Whether the password should be shown at start. - - @Input() name = ''; // Deprecated. Not used anymore. - @ContentChild(IonInput) ionInput?: IonInput | HTMLIonInputElement; // Deprecated. Use slot instead. - - protected input?: HTMLInputElement; - protected hostElement: HTMLElement; - protected logger: CoreLogger; - - constructor(element: ElementRef) { - this.hostElement = element.nativeElement; - this.logger = CoreLogger.getInstance('CoreShowPasswordComponent'); - } - - get shown(): boolean { - return this.input?.type === 'text'; - } - - set shown(shown: boolean) { - if (!this.input) { - return; - } - - this.input.type = shown ? 'text' : 'password'; - } +export class CoreShowPasswordComponent implements AfterViewInit { /** - * @inheritdoc + * @deprecated since 4.5. Not used anymore. */ - ngOnInit(): void { - this.shown = CoreUtils.isTrueOrOne(this.initialShown); - } + @Input() initialShown = ''; + + /** + * @deprecated since 4.4. Not used anymore. + */ + @Input() name = ''; + + /** + * @deprecated since 4.4. Use slotted solution instead. + */ + @ContentChild(IonInput) ionInput?: IonInput | HTMLIonInputElement; /** * @inheritdoc */ async ngAfterViewInit(): Promise { - await this.setInputElement(); - - if (!this.input) { - return; - } - - // By default, don't autocapitalize and autocorrect. - if (!this.input.getAttribute('autocorrect')) { - this.input.setAttribute('autocorrect', 'off'); - } - if (!this.input.getAttribute('autocapitalize')) { - this.input.setAttribute('autocapitalize', 'none'); - } - } - - /** - * Set the input element to affect. - */ - protected async setInputElement(): Promise { - if (!this.ionInput) { - this.ionInput = this.hostElement.closest('ion-input') ?? undefined; - - this.hostElement.setAttribute('slot', 'end'); - } else { - // It's outside ion-input, warn devs. - this.logger.warn('Deprecated CoreShowPasswordComponent usage, it\'s not needed to surround ion-input anymore.'); - } + CoreLogger.getInstance('CoreShowPasswordComponent') + .warn('Deprecated component, use instead.'); + // eslint-disable-next-line deprecation/deprecation if (!this.ionInput) { return; } - try { - this.input = await this.ionInput.getInputElement(); - } catch { - // This should never fail, but it does in some testing environment because Ionic elements are not - // rendered properly. So in case this fails it will try to find through the name and ignore the error. - const name = this.ionInput.name; - if (!name) { - return; - } - this.input = this.hostElement.querySelector('input[name="' + name + '"]') ?? undefined; - } - } - - /** - * Toggle show/hide password. - * - * @param event The mouse event. - */ - toggle(event: Event): void { - if (event.type === 'keyup' && !this.isValidKeyboardKey(event)) { + // eslint-disable-next-line deprecation/deprecation + const input = await CoreUtils.ignoreErrors(this.ionInput.getInputElement()); + if (!input) { return; } - event.preventDefault(); - event.stopPropagation(); - - const isFocused = document.activeElement === this.input; - this.shown = !this.shown; - - // In Android, the keyboard is closed when the input type changes. Focus it again. - if (this.input && isFocused && CorePlatform.isAndroid()) { - CoreDomUtils.focusElement(this.input); - } - } - - /** - * Do not loose focus. - * - * @param event The mouse event. - */ - doNotBlur(event: Event): void { - if (event.type === 'keydown' && !this.isValidKeyboardKey(event)) { - return; - } - - event.preventDefault(); - event.stopPropagation(); - } - - /** - * Checks if Space or Enter have been pressed. - * - * @param event Keyboard Event. - * @returns Wether space or enter have been pressed. - */ - protected isValidKeyboardKey(event: KeyboardEvent): boolean { - return event.key === ' ' || event.key === 'Enter'; + const toggle = CoreDomUtils.convertToElement(''); + input.parentElement?.appendChild(toggle.children[0]); } } diff --git a/src/core/features/compile/services/compile.ts b/src/core/features/compile/services/compile.ts index 63849d3d0..b253c6149 100644 --- a/src/core/features/compile/services/compile.ts +++ b/src/core/features/compile/services/compile.ts @@ -77,7 +77,6 @@ import { Md5 } from 'ts-md5/dist/md5'; // Import core classes that can be useful for site plugins. import { CoreSyncBaseProvider } from '@classes/base-sync'; import { CoreArray } from '@singletons/array'; -import { CoreComponentsRegistry } from '@singletons/components-registry'; import { CoreDirectivesRegistry } from '@singletons/directives-registry'; import { CoreDom } from '@singletons/dom'; import { CoreForms } from '@singletons/form'; @@ -295,12 +294,13 @@ export class CoreCompileProvider { instance['CoreLoggerProvider'] = CoreLogger; instance['moment'] = moment; instance['Md5'] = Md5; - instance['Network'] = CoreNetwork.instance; // @deprecated since 4.1, plugins should use CoreNetwork instead. - instance['Platform'] = CorePlatform.instance; // @deprecated since 4.1, plugins should use CorePlatform instead. + /** + * @deprecated since 4.1, plugins should use CoreNetwork instead. + * Keeping this a bit more to avoid plugins breaking. + */ + instance['Network'] = CoreNetwork.instance; instance['CoreSyncBaseProvider'] = CoreSyncBaseProvider; instance['CoreArray'] = CoreArray; - // eslint-disable-next-line deprecation/deprecation - instance['CoreComponentsRegistry'] = CoreComponentsRegistry; instance['CoreDirectivesRegistry'] = CoreDirectivesRegistry; instance['CoreNetwork'] = CoreNetwork.instance; instance['CorePlatform'] = CorePlatform.instance; diff --git a/src/core/features/course/components/module-description/module-description.ts b/src/core/features/course/components/module-description/module-description.ts index d0bb74b58..738e89f9d 100644 --- a/src/core/features/course/components/module-description/module-description.ts +++ b/src/core/features/course/components/module-description/module-description.ts @@ -31,7 +31,8 @@ import { Component, HostBinding, Input } from '@angular/core'; * * * - * @deprecated since 4.0 use core-course-module-info + * @deprecated since 4.0 use core-course-module-info instead. + * Keeping this a bit more to avoid plugins breaking. */ @Component({ selector: 'core-course-module-description', diff --git a/src/core/features/course/components/module-navigation/module-navigation.scss b/src/core/features/course/components/module-navigation/module-navigation.scss index c43abc36f..71e9200c8 100644 --- a/src/core/features/course/components/module-navigation/module-navigation.scss +++ b/src/core/features/course/components/module-navigation/module-navigation.scss @@ -50,6 +50,6 @@ height: 0 !important; } -:host-context(html.dark) { +:host-context(:root.dark) { --button-color: var(--gray-100); } diff --git a/src/core/features/course/components/module/module.scss b/src/core/features/course/components/module/module.scss index be33f3f6e..19f40ee3c 100644 --- a/src/core/features/course/components/module/module.scss +++ b/src/core/features/course/components/module/module.scss @@ -198,7 +198,7 @@ } -:host-context(html.dark) { +:host-context(:root.dark) { .activity-description-availabilityinfo { .core-module-availabilityinfo { background: var(--gray-800); diff --git a/src/core/features/courses/components/components.module.ts b/src/core/features/courses/components/components.module.ts index 591dc709d..a4444767f 100644 --- a/src/core/features/courses/components/components.module.ts +++ b/src/core/features/courses/components/components.module.ts @@ -16,14 +16,11 @@ import { NgModule } from '@angular/core'; import { CoreSharedModule } from '@/core/shared.module'; import { CoreCoursesCourseListItemComponent } from './course-list-item/course-list-item'; -import { CoreCoursesCourseProgressComponent } from './course-progress/course-progress'; import { CoreCoursesCourseOptionsMenuComponent } from './course-options-menu/course-options-menu'; @NgModule({ declarations: [ CoreCoursesCourseListItemComponent, - // eslint-disable-next-line deprecation/deprecation - CoreCoursesCourseProgressComponent, CoreCoursesCourseOptionsMenuComponent, ], imports: [ @@ -31,8 +28,6 @@ import { CoreCoursesCourseOptionsMenuComponent } from './course-options-menu/cou ], exports: [ CoreCoursesCourseListItemComponent, - // eslint-disable-next-line deprecation/deprecation - CoreCoursesCourseProgressComponent, CoreCoursesCourseOptionsMenuComponent, ], }) diff --git a/src/core/features/courses/components/course-list-item/course-list-item.scss b/src/core/features/courses/components/course-list-item/course-list-item.scss index c11f469ad..0f8ab669e 100644 --- a/src/core/features/courses/components/course-list-item/course-list-item.scss +++ b/src/core/features/courses/components/course-list-item/course-list-item.scss @@ -29,7 +29,7 @@ } -:host-context(html.dark) { +:host-context(:root.dark) { --button-background: rgb(0 0 0 / 30%); } diff --git a/src/core/features/courses/components/course-progress/core-courses-course-progress.html b/src/core/features/courses/components/course-progress/core-courses-course-progress.html deleted file mode 100644 index 94f024f2c..000000000 --- a/src/core/features/courses/components/course-progress/core-courses-course-progress.html +++ /dev/null @@ -1,2 +0,0 @@ - diff --git a/src/core/features/courses/components/course-progress/course-progress.ts b/src/core/features/courses/components/course-progress/course-progress.ts deleted file mode 100644 index 463456237..000000000 --- a/src/core/features/courses/components/course-progress/course-progress.ts +++ /dev/null @@ -1,42 +0,0 @@ -// (C) Copyright 2015 Moodle Pty Ltd. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -import { Component, HostBinding, Input } from '@angular/core'; -import { CoreCourseListItem } from '@features/courses/services/courses'; - -/** - * This component is meant to display a course for a list of courses with progress. - * - * Example usage: - * - * - * - * - * @deprecated since 4.0. Use core-courses-course-list-item instead. - */ -@Component({ - selector: 'core-courses-course-progress', - templateUrl: 'core-courses-course-progress.html', -}) -export class CoreCoursesCourseProgressComponent { - - @Input() course!: CoreCourseListItem; // The course to render. - @Input() showAll = false; // If true, will show all actions, options, star and progress. - @Input() showDownload = true; // If true, will show download button. Only works if the options menu is not shown. - - @HostBinding('class.deprecated') get isDeprecated(): boolean { - return true; - } - -} diff --git a/src/core/features/courses/pages/my/my.html b/src/core/features/courses/pages/my/my.html index de4cf18de..933afcc04 100644 --- a/src/core/features/courses/pages/my/my.html +++ b/src/core/features/courses/pages/my/my.html @@ -27,7 +27,7 @@
-