From 50b8fe2e988ec43826810905e737c037b65e3f17 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Wed, 13 Dec 2023 17:24:15 +0100 Subject: [PATCH 1/2] MOBILE-3947 ion-datetime: Fix timestamp supplied to datetime ion-datetime no longer uses time zone, it's always UTC now so we had to adapt the initial value supplied. No change needed when reading the value because moment automatically uses the user timezone if the value doesn't specify a timezone. --- src/core/services/utils/time.ts | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/core/services/utils/time.ts b/src/core/services/utils/time.ts index fb7865e04e5..24cb2857c84 100644 --- a/src/core/services/utils/time.ts +++ b/src/core/services/utils/time.ts @@ -208,7 +208,11 @@ export class CoreTimeUtilsProvider { * @returns Formatted time. */ toDatetimeFormat(timestamp?: number): string { - return moment(timestamp || Date.now()).toISOString(); + const isoString = moment(timestamp || Date.now()).toISOString(true); + + // Remove milliseconds and timezone for consistency with the values used by ion-datetime. + // ion-datetime no longer uses timezone, it always uses UTC. + return isoString.substring(0, isoString.indexOf('.')); } /** From df0cf232f6bf7137d9ddd8f440cc93c0a71b20e4 Mon Sep 17 00:00:00 2001 From: Dani Palou Date: Fri, 15 Dec 2023 10:42:31 +0100 Subject: [PATCH 2/2] MOBILE-3947 ion-datetime: Use right language and first day of week --- scripts/langindex.json | 1 + src/core/constants.ts | 3 ++ src/core/directives/datetime.ts | 62 ++++++++++++++++++++++++ src/core/directives/directives.module.ts | 3 ++ src/core/features/user/services/user.ts | 19 ++++++++ src/core/lang.json | 1 + 6 files changed, 89 insertions(+) create mode 100644 src/core/directives/datetime.ts diff --git a/scripts/langindex.json b/scripts/langindex.json index 614f7c5b078..3c3c3e1f993 100644 --- a/scripts/langindex.json +++ b/scripts/langindex.json @@ -1792,6 +1792,7 @@ "core.fileuploader.uploadingperc": "local_moodlemobileapp", "core.fileuploader.video": "local_moodlemobileapp", "core.filter": "moodle", + "core.firstdayofweek": "langconfig", "core.folder": "moodle", "core.forcepasswordchangenotice": "moodle", "core.fulllistofcourses": "moodle", diff --git a/src/core/constants.ts b/src/core/constants.ts index 35a26c3b0b3..a5d6ef786b0 100644 --- a/src/core/constants.ts +++ b/src/core/constants.ts @@ -153,6 +153,9 @@ export class CoreConstants { static readonly MOD_ARCHETYPE_ASSIGNMENT = 2; // Assignment module archetype. static readonly MOD_ARCHETYPE_SYSTEM = 3; // System (not user-addable) module archetype. + // Other constants. + static readonly CALENDAR_DEFAULT_STARTING_WEEKDAY = 1; + // Config & environment constants. static readonly CONFIG = { ...envJson.config } as unknown as EnvironmentConfig; // Data parsed from config.json files. static readonly BUILD = envJson.build as unknown as EnvironmentBuild; // Build info. diff --git a/src/core/directives/datetime.ts b/src/core/directives/datetime.ts new file mode 100644 index 00000000000..f2d1ca1f379 --- /dev/null +++ b/src/core/directives/datetime.ts @@ -0,0 +1,62 @@ +// (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 { Directive, OnInit } from '@angular/core'; +import { CoreLang } from '@services/lang'; +import { CoreUser } from '@features/user/services/user'; +import { IonDatetime } from '@ionic/angular'; + +/** + * Directive to automatically add language and starting week day to ion-datetime. + */ +@Directive({ + selector: 'ion-datetime', +}) +export class CoreIonDatetimeDirective implements OnInit { + + constructor(protected datetime: IonDatetime) {} + + /** + * @inheritdoc + */ + ngOnInit(): void { + this.setLanguage(); + this.setStartingWeekDay(); + } + + /** + * Set language to use. + */ + protected async setLanguage(): Promise { + if (this.datetime.locale) { + return; + } + + const language = await CoreLang.getCurrentLanguage(); + this.datetime.locale = language; + } + + /** + * Set starting week day. + */ + protected async setStartingWeekDay(): Promise { + if (this.datetime.firstDayOfWeek || this.datetime.firstDayOfWeek === 0) { + return; + } + + const startingDay = await CoreUser.getStartingWeekDay(); + this.datetime.firstDayOfWeek = startingDay; + } + +} diff --git a/src/core/directives/directives.module.ts b/src/core/directives/directives.module.ts index d004ce3cd24..6225f56a1b5 100644 --- a/src/core/directives/directives.module.ts +++ b/src/core/directives/directives.module.ts @@ -34,6 +34,7 @@ import { CoreCollapsibleFooterDirective } from './collapsible-footer'; import { CoreContentDirective } from './content'; import { CoreUpdateNonReactiveAttributesDirective } from './update-non-reactive-attributes'; import { CoreUserTourDirective } from './user-tour'; +import { CoreIonDatetimeDirective } from './datetime'; @NgModule({ declarations: [ @@ -57,6 +58,7 @@ import { CoreUserTourDirective } from './user-tour'; CoreContentDirective, CoreUpdateNonReactiveAttributesDirective, CoreUserTourDirective, + CoreIonDatetimeDirective, ], exports: [ CoreAutoFocusDirective, @@ -79,6 +81,7 @@ import { CoreUserTourDirective } from './user-tour'; CoreContentDirective, CoreUpdateNonReactiveAttributesDirective, CoreUserTourDirective, + CoreIonDatetimeDirective, ], }) export class CoreDirectivesModule {} diff --git a/src/core/features/user/services/user.ts b/src/core/features/user/services/user.ts index a577bd3337b..d603f6433df 100644 --- a/src/core/features/user/services/user.ts +++ b/src/core/features/user/services/user.ts @@ -29,6 +29,7 @@ import { USERS_TABLE_NAME, CoreUserDBRecord } from './database/user'; import { CoreUserHelper } from './user-helper'; import { CoreUrlUtils } from '@services/utils/url'; import { CoreSiteWSPreSets } from '@classes/sites/authenticated-site'; +import { CoreConstants } from '@/core/constants'; const ROOT_CACHE_KEY = 'mmUser:'; @@ -285,6 +286,24 @@ export class CoreUserProvider { } } + /** + * Get the starting week day based on the user preference. + * + * @returns Starting week day. + */ + async getStartingWeekDay(): Promise { + const preference = await CoreUtils.ignoreErrors(this.getUserPreference('calendar_startwday')); + + if (preference && !isNaN(Number(preference))) { + return Number(preference); + } + + const defaultValue = Number(CoreSites.getCurrentSite()?.getStoredConfig('calendar_startwday') ?? + Translate.instant('core.firstdayofweek')); + + return !isNaN(defaultValue) ? defaultValue % 7 : CoreConstants.CALENDAR_DEFAULT_STARTING_WEEKDAY; + } + /** * Get cache key for a user WS call. * diff --git a/src/core/lang.json b/src/core/lang.json index f917f292935..ca0e0007abe 100644 --- a/src/core/lang.json +++ b/src/core/lang.json @@ -131,6 +131,7 @@ "filenameexist": "File name already exists: {{$a}}", "filenotfound": "File not found, sorry.", "filter": "Filter", + "firstdayofweek": "1", "folder": "Folder", "forcepasswordchangenotice": "You must change your password to proceed.", "fulllistofcourses": "All courses",