Merge pull request #3807 from crazyserver/MOBILE-4362

Mobile 4362
main
Dani Palou 2023-10-06 15:29:35 +02:00 committed by GitHub
commit ec7a3ea9b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 201 additions and 133 deletions

View File

@ -1630,7 +1630,6 @@
"core.course.warningmanualcompletionmodified": "local_moodlemobileapp", "core.course.warningmanualcompletionmodified": "local_moodlemobileapp",
"core.course.warningofflinemanualcompletiondeleted": "local_moodlemobileapp", "core.course.warningofflinemanualcompletiondeleted": "local_moodlemobileapp",
"core.course.youmust": "completion", "core.course.youmust": "completion",
"core.coursedetails": "moodle",
"core.coursenogroups": "local_moodlemobileapp", "core.coursenogroups": "local_moodlemobileapp",
"core.courses.addtofavourites": "block_myoverview", "core.courses.addtofavourites": "block_myoverview",
"core.courses.aria:coursecategory": "course", "core.courses.aria:coursecategory": "course",

View File

@ -203,7 +203,6 @@ export class AddonModDataActionComponent implements OnInit {
await CoreDomUtils.openPopover({ await CoreDomUtils.openPopover({
component: AddonModDataActionsMenuComponent, component: AddonModDataActionsMenuComponent,
componentProps: { items }, componentProps: { items },
showBackdrop: true,
id: 'actionsmenu-popover', id: 'actionsmenu-popover',
event, event,
}); });

View File

@ -22,6 +22,7 @@
--border-color: var(--core-combobox-border-color); --border-color: var(--core-combobox-border-color);
--border-style: solid; --border-style: solid;
--border-width: var(--core-combobox-border-width); --border-width: var(--core-combobox-border-width);
--border-radius: var(--radius-xs);
--box-shadow: var(--core-combobox-box-shadow); --box-shadow: var(--core-combobox-box-shadow);

View File

@ -185,7 +185,6 @@ export class CoreContextMenuComponent implements OnInit, OnDestroy {
title: this.title, title: this.title,
items: this.items, items: this.items,
}, },
showBackdrop: true,
id: this.uniqueId, id: this.uniqueId,
}); });

View File

@ -4,6 +4,9 @@
position: relative; position: relative;
width: var(--core-avatar-size); width: var(--core-avatar-size);
height: var(--core-avatar-size); height: var(--core-avatar-size);
--contact-status-size: 14px;
--margin-end-on-item: 8px;
--margin-vertical-on-item: 8px;
img { img {
border-radius: var(--core-avatar-radius); border-radius: var(--core-avatar-radius);
@ -53,8 +56,8 @@
position: absolute; position: absolute;
right: 0; right: 0;
bottom: 0; bottom: 0;
width: 14px; width: var(--contact-status-size);
height: 14px; height: var(--contact-status-size);
border-radius: 50%; border-radius: 50%;
&.online { &.online {
border: 1px solid white; border: 1px solid white;
@ -92,7 +95,7 @@
} }
:host-context(ion-item) { :host-context(ion-item) {
@include margin(6px, 8px, 6px, 0px); @include margin(var(--margin-vertical-on-item), var(--margin-end-on-item), var(--margin-vertical-on-item), 0px);
img { img {
min-width: var(--core-avatar-size); min-width: var(--core-avatar-size);
min-height: var(--core-avatar-size); min-height: var(--core-avatar-size);

View File

@ -4,6 +4,10 @@
flex-direction: column; flex-direction: column;
background: var(--background); background: var(--background);
ion-card {
--border-radius: var(--radius-sm);
}
::ng-deep ion-item-divider { ::ng-deep ion-item-divider {
min-height: var(--item-divider-min-height); min-height: var(--item-divider-min-height);
} }

View File

@ -1,7 +1,7 @@
<ng-container *ngIf="showCompletionInfo && completion"> <ng-container *ngIf="showCompletionInfo && completion">
<ng-container *ngIf="completion.istrackeduser"> <ng-container *ngIf="completion.istrackeduser">
<ng-container *ngIf="completion.isautomatic"> <ng-container *ngIf="completion.isautomatic">
<ion-button class="completioninfo completion_incomplete ion-text-wrap chip" *ngIf="!completed" fill="outline" <ion-button class="completioninfo completion_incomplete chip" *ngIf="!completed" fill="outline"
(click)="completionClicked($event)"> (click)="completionClicked($event)">
{{ 'core.course.todo' | translate }} {{ 'core.course.todo' | translate }}
<div class="select-icon" role="presentation" aria-hidden="true"> <div class="select-icon" role="presentation" aria-hidden="true">
@ -9,7 +9,7 @@
</div> </div>
</ion-button> </ion-button>
<ion-button class="completioninfo completion_complete ion-text-wrap chip" color="success" (click)="completionClicked($event)" <ion-button class="completioninfo completion_complete chip" color="success" (click)="completionClicked($event)"
*ngIf="completed"> *ngIf="completed">
<ion-icon name="fas-check" slot="start" aria-hidden="true"></ion-icon> <ion-icon name="fas-check" slot="start" aria-hidden="true"></ion-icon>
{{'core.course.done' | translate }} {{'core.course.done' | translate }}
@ -21,14 +21,14 @@
<ng-container *ngIf="!completion.isautomatic"> <ng-container *ngIf="!completion.isautomatic">
<ion-button *ngIf="completed" color="success" [attr.aria-label]="accessibleDescription" (click)="completionClicked($event)" <ion-button *ngIf="completed" color="success" [attr.aria-label]="accessibleDescription" (click)="completionClicked($event)"
class="completioninfo completion_complete ion-text-wrap chip"> class="completioninfo completion_complete chip">
<ion-icon name="fas-check" slot="start" aria-hidden="true"></ion-icon> <ion-icon name="fas-check" slot="start" aria-hidden="true"></ion-icon>
{{ 'core.course.completion_manual:done' | translate }} {{ 'core.course.completion_manual:done' | translate }}
<ion-icon *ngIf="completion.offline" name="fas-arrows-rotate" <ion-icon *ngIf="completion.offline" name="fas-arrows-rotate"
[attr.aria-label]="'core.course.manualcompletionnotsynced' | translate" slot="end"></ion-icon> [attr.aria-label]="'core.course.manualcompletionnotsynced' | translate" slot="end"></ion-icon>
</ion-button> </ion-button>
<ion-button *ngIf="!completed" fill="outline" [attr.aria-label]="accessibleDescription" (click)="completionClicked($event)" <ion-button *ngIf="!completed" fill="outline" [attr.aria-label]="accessibleDescription" (click)="completionClicked($event)"
class="completioninfo completion_incomplete ion-text-wrap chip"> class="completioninfo completion_incomplete chip">
{{ 'core.course.completion_manual:markdone' | translate }} {{ 'core.course.completion_manual:markdone' | translate }}
<ion-icon *ngIf="completion.offline" name="fas-arrows-rotate" <ion-icon *ngIf="completion.offline" name="fas-arrows-rotate"
[attr.aria-label]="'core.course.manualcompletionnotsynced' | translate" slot="end"></ion-icon> [attr.aria-label]="'core.course.manualcompletionnotsynced' | translate" slot="end"></ion-icon>
@ -36,7 +36,7 @@
</ng-container> </ng-container>
</ng-container> </ng-container>
<ion-button *ngIf="!completion.istrackeduser" fill="outline" class="ion-text-wrap chip" (click)="completionClicked($event)"> <ion-button *ngIf="!completion.istrackeduser" fill="outline" class="chip" (click)="completionClicked($event)">
{{ 'core.course.completionmenuitem' | translate }} {{ 'core.course.completionmenuitem' | translate }}
<div class="select-icon" role="presentation" aria-hidden="true"> <div class="select-icon" role="presentation" aria-hidden="true">
<div class="select-icon-inner"></div> <div class="select-icon-inner"></div>

View File

@ -139,7 +139,6 @@ export class CoreCourseModuleCompletionComponent
componentProps: { componentProps: {
completion: this.completion, completion: this.completion,
}, },
showBackdrop: true,
event: { target } as Event, event: { target } as Event,
}); });
} else { } else {

View File

@ -55,7 +55,7 @@
flex-flow: row; flex-flow: row;
align-items: center; align-items: center;
z-index: 1; z-index: 1;
justify-content: space-around; justify-content: flex-end;
align-content: center; align-content: center;
ion-button.core-module-button-more { ion-button.core-module-button-more {

View File

@ -75,7 +75,8 @@ Feature: Test signup in app
When I press the user menu button in the app When I press the user menu button in the app
And I press "User Test" in the app And I press "User Test" in the app
Then I should find "Barcelona, Spain" in the app Then I should find "Barcelona" in the app
Then I should find "Spain" in the app
And I should find "u1@u1.com" in the app And I should find "u1@u1.com" in the app
@lms_from3.10 @lms_from3.10

View File

@ -47,8 +47,8 @@
{{ 'core.settings.colorscheme-' + scheme | translate }}</ion-select-option> {{ 'core.settings.colorscheme-' + scheme | translate }}</ion-select-option>
</ion-select> </ion-select>
</ion-item> </ion-item>
<ion-item text-wrap *ngIf="colorSchemes.length > 0 && selectedScheme=='system' && isAndroid" lines="none"> <ion-item *ngIf="colorSchemes.length> 0 && selectedScheme=='system' && isAndroid" lines="none">
<ion-label> <ion-label class="ion-text-wrap">
<p>{{ 'core.settings.colorscheme-system-notice' | translate }}</p> <p>{{ 'core.settings.colorscheme-system-notice' | translate }}</p>
</ion-label> </ion-label>
</ion-item> </ion-item>

View File

@ -14,7 +14,7 @@
</ion-refresher> </ion-refresher>
<core-loading [hideUntil]="userLoaded"> <core-loading [hideUntil]="userLoaded">
<ion-list *ngIf="user"> <ion-list *ngIf="user">
<ion-item class="ion-text-center core-user-profile-maininfo ion-text-wrap" lines="full"> <ion-item class="ion-text-center core-user-profile-maininfo ion-text-wrap" [lines]="user.description ? null : 'full'">
<core-user-avatar [user]="user" [userId]="user.id" [linkProfile]="false" [checkOnline]="!canChangeProfilePicture"> <core-user-avatar [user]="user" [userId]="user.id" [linkProfile]="false" [checkOnline]="!canChangeProfilePicture">
<ion-button class="edit-avatar" *ngIf="canChangeProfilePicture" (click)="changeProfilePicture()" <ion-button class="edit-avatar" *ngIf="canChangeProfilePicture" (click)="changeProfilePicture()"
[attr.aria-label]="'core.user.newpicture' | translate" fill="clear"> [attr.aria-label]="'core.user.newpicture' | translate" fill="clear">
@ -23,8 +23,14 @@
</core-user-avatar> </core-user-avatar>
<ion-label> <ion-label>
<h2>{{ user.fullname }}</h2> <h2>{{ user.fullname }}</h2>
<p *ngIf="user.address"> </ion-label>
<ion-icon name="fas-location-dot" [attr.aria-hidden]="true"></ion-icon> {{ user.address }} </ion-item>
<ion-item class="ion-text-wrap" *ngIf="user.description" lines="full">
<ion-label>
<p>
<core-format-text [text]="user.description" contextLevel="user" [contextInstanceId]="user.id">
</core-format-text>
</p> </p>
</ion-label> </ion-label>
</ion-item> </ion-item>
@ -32,7 +38,7 @@
<ion-item-group *ngIf="hasContact"> <ion-item-group *ngIf="hasContact">
<ion-item-divider> <ion-item-divider>
<ion-label> <ion-label>
<p class="item-heading">{{ 'core.user.contact' | translate}}</p> <h3>{{ 'core.user.contact' | translate}}</h3>
</ion-label> </ion-label>
</ion-item-divider> </ion-item-divider>
<ion-item class="ion-text-wrap" *ngIf="user.email"> <ion-item class="ion-text-wrap" *ngIf="user.email">
@ -43,6 +49,24 @@
</a></p> </a></p>
</ion-label> </ion-label>
</ion-item> </ion-item>
<ion-item class="ion-text-wrap" *ngIf="user.country">
<ion-label>
<p class="item-heading">{{ 'core.user.country' | translate}}</p>
<p>{{ user.country }}</p>
</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="user.city">
<ion-label>
<p class="item-heading">{{ 'core.user.city' | translate}}</p>
<p>{{ user.city }}</p>
</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="displayTimezone && user.timezone">
<ion-label>
<p class="item-heading">{{ 'core.timezone' | translate}}</p>
<p>{{ user.timezone }}</p>
</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="user.phone1"> <ion-item class="ion-text-wrap" *ngIf="user.phone1">
<ion-label> <ion-label>
<p class="item-heading">{{ 'core.user.phone1' | translate}}</p> <p class="item-heading">{{ 'core.user.phone1' | translate}}</p>
@ -59,31 +83,9 @@
</a></p> </a></p>
</ion-label> </ion-label>
</ion-item> </ion-item>
<ion-item class="ion-text-wrap" *ngIf="user.city">
<ion-label>
<p class="item-heading">{{ 'core.user.city' | translate}}</p>
<p>{{ user.city }}</p>
</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="user.country">
<ion-label>
<p class="item-heading">{{ 'core.user.country' | translate}}</p>
<p>{{ user.country }}</p>
</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="displayTimezone && user.timezone">
<ion-label>
<p class="item-heading">{{ 'core.timezone' | translate}}</p>
<p>{{ user.timezone }}</p>
</ion-label>
</ion-item>
<ng-container *ngIf="canShowDepartment"> <ng-container *ngIf="canShowDepartment">
<ion-item class="ion-text-wrap" *ngIf="user.idnumber">
<ion-label>
<p class="item-heading">{{ 'core.user.idnumber' | translate }}</p>
<p>{{ user.idnumber }}</p>
</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="user.institution"> <ion-item class="ion-text-wrap" *ngIf="user.institution">
<ion-label> <ion-label>
<p class="item-heading">{{ 'core.user.institution' | translate }}</p> <p class="item-heading">{{ 'core.user.institution' | translate }}</p>
@ -96,12 +98,18 @@
<p>{{ user.department }}</p> <p>{{ user.department }}</p>
</ion-label> </ion-label>
</ion-item> </ion-item>
<ion-item class="ion-text-wrap" *ngIf="user.idnumber">
<ion-label>
<p class="item-heading">{{ 'core.user.idnumber' | translate }}</p>
<p>{{ user.idnumber }}</p>
</ion-label>
</ion-item>
</ng-container> </ng-container>
</ion-item-group> </ion-item-group>
<ion-item-group *ngIf="hasDetails"> <ion-item-group *ngIf="hasDetails">
<ion-item-divider> <ion-item-divider>
<ion-label> <ion-label>
<p class="item-heading">{{ 'core.userdetails' | translate}}</p> <h3>{{ 'core.userdetails' | translate}}</h3>
</ion-label> </ion-label>
</ion-item-divider> </ion-item-divider>
<ion-item class="ion-text-wrap" *ngIf="user.url"> <ion-item class="ion-text-wrap" *ngIf="user.url">
@ -124,21 +132,6 @@
[contextInstanceId]="courseId" [courseId]="courseId"> [contextInstanceId]="courseId" [courseId]="courseId">
</core-user-profile-field> </core-user-profile-field>
</ion-item-group> </ion-item-group>
<ion-item-group *ngIf="user.description">
<ion-item-divider>
<ion-label>
<p class="item-heading">{{ 'core.user.description' | translate}}</p>
</ion-label>
</ion-item-divider>
<ion-item class="ion-text-wrap">
<ion-label>
<p>
<core-format-text [text]="user.description" contextLevel="user" [contextInstanceId]="user.id">
</core-format-text>
</p>
</ion-label>
</ion-item>
</ion-item-group>
</ion-list> </ion-list>
<core-empty-box *ngIf="!user || (!hasContact && !hasDetails && !user.description)" icon="fas-user" <core-empty-box *ngIf="!user || (!hasContact && !hasDetails && !user.description)" icon="fas-user"

View File

@ -1,27 +1,20 @@
:host { :host {
.core-user-profile-maininfo::part(native) { .core-user-profile-maininfo::part(native) {
flex-direction: column; flex-direction: column;
} }
::ng-deep {
core-user-avatar { core-user-avatar {
display: block;
--core-avatar-size: var(--core-large-avatar-size); --core-avatar-size: var(--core-large-avatar-size);
height: calc(var(--core-avatar-size) + 16px); --contact-status-size: 24px;
--margin-end-on-item: 0px;
img { --margin-vertical-on-item: 0px;
margin: 8px auto;
}
.contact-status { .contact-status {
width: 24px !important;
height: 24px !important;
right: calc(50% - 12px - var(--core-avatar-size) / 2) !important; right: calc(50% - 12px - var(--core-avatar-size) / 2) !important;
} }
.edit-avatar { .edit-avatar {
position: absolute; position: absolute;
right: calc(50% - 15px - var(--core-avatar-size) / 2); right: calc(50% - 24px - var(--core-avatar-size) / 2);
bottom: -12px; bottom: -12px;
:host-context([dir="rtl"]) & { :host-context([dir="rtl"]) & {
@ -34,8 +27,13 @@
} }
} }
} }
}
h2 {
font-size: 24px;
}
h3 {
font-size: 20px;
}
.core-user-profile-interests { .core-user-profile-interests {
ion-badge { ion-badge {
cursor: pointer; cursor: pointer;
@ -46,7 +44,7 @@
} }
:host-context([dir="rtl"]) ::ng-deep core-user-avatar .edit-avatar { :host-context([dir="rtl"]) core-user-avatar .edit-avatar {
left: -24px; left: -24px;
right: unset; right: unset;
} }

View File

@ -75,7 +75,6 @@ export class CoreUserAboutPage implements OnInit, OnDestroy {
} }
this.user.email = data.user.email; this.user.email = data.user.email;
this.user.address = CoreUserHelper.formatAddress('', data.user.city, data.user.country);
}, CoreSites.getCurrentSiteId()); }, CoreSites.getCurrentSiteId());
} }
@ -118,13 +117,7 @@ export class CoreUserAboutPage implements OnInit, OnDestroy {
this.user = user; this.user = user;
this.title = user.fullname; this.title = user.fullname;
this.user.address = CoreUserHelper.formatAddress('', user.city, user.country); this.fillTimezone();
const serverTimezone = CoreSites.getCurrentSite()?.getStoredConfig('timezone');
this.displayTimezone = !!serverTimezone;
if (this.displayTimezone && this.user.timezone === USER_PROFILE_SERVER_TIMEZONE) {
this.user.timezone = serverTimezone;
}
await this.checkUserImageUpdated(); await this.checkUserImageUpdated();
} catch (error) { } catch (error) {
@ -261,6 +254,30 @@ export class CoreUserAboutPage implements OnInit, OnDestroy {
return avatarUrl; return avatarUrl;
} }
/**
* Fill user timezone depending on the server and fix the legacy timezones.
*/
protected fillTimezone(): void {
if (!this.user) {
return;
}
const serverTimezone = CoreSites.getRequiredCurrentSite().getStoredConfig('timezone');
this.displayTimezone = !!serverTimezone;
if (!this.displayTimezone) {
return;
}
if (this.user.timezone === USER_PROFILE_SERVER_TIMEZONE) {
this.user.timezone = serverTimezone;
}
if (this.user.timezone) {
this.user.timezone = CoreUserHelper.translateLegacyTimezone(this.user.timezone);
}
}
/** /**
* Open a user interest. * Open a user interest.
* *

View File

@ -1,4 +1,4 @@
<ion-header> <ion-header collapsible>
<ion-toolbar> <ion-toolbar>
<ion-buttons slot="start"> <ion-buttons slot="start">
<ion-back-button [text]="'core.back' | translate"></ion-back-button> <ion-back-button [text]="'core.back' | translate"></ion-back-button>
@ -14,11 +14,11 @@
</ion-refresher> </ion-refresher>
<core-loading [hideUntil]="userLoaded"> <core-loading [hideUntil]="userLoaded">
<ion-list *ngIf="user && !isDeleted && isEnrolled"> <ion-list *ngIf="user && !isDeleted && isEnrolled">
<ion-item class="ion-text-center core-user-profile-maininfo ion-text-wrap"> <ion-item class="core-user-profile-maininfo ion-text-wrap" collapsible>
<core-user-avatar [user]="user" [userId]="user.id" [linkProfile]="false" [checkOnline]="true"> <core-user-avatar [user]="user" [userId]="user.id" [linkProfile]="false" [checkOnline]="true" slot="start">
</core-user-avatar> </core-user-avatar>
<ion-label> <ion-label>
<h2>{{ user.fullname }}</h2> <h1>{{ user.fullname }}</h1>
<p *ngIf="user.address"> <p *ngIf="user.address">
<ion-icon name="fas-location-dot" [attr.aria-hidden]="true"></ion-icon> {{ user.address }} <ion-icon name="fas-location-dot" [attr.aria-hidden]="true"></ion-icon> {{ user.address }}
</p> </p>

View File

@ -1,29 +1,10 @@
:host { :host {
.core-user-profile-maininfo::part(native) {
flex-direction: column;
}
::ng-deep {
core-user-avatar { core-user-avatar {
display: block;
--core-avatar-size: var(--core-large-avatar-size); --core-avatar-size: var(--core-large-avatar-size);
height: calc(var(--core-avatar-size) + 16px); --contact-status-size: 24px;
--margin-end-on-item: 16px;
img {
margin: 8px auto;
}
.contact-status { .contact-status {
width: 24px !important;
height: 24px !important;
right: calc(50% - 12px - var(--core-avatar-size) / 2) !important; right: calc(50% - 12px - var(--core-avatar-size) / 2) !important;
} }
} }
} }
}
:host-context([dir="rtl"]) ::ng-deep core-user-avatar .edit-avatar {
left: -24px;
right: unset;
}

View File

@ -74,7 +74,6 @@ export class CoreUserProfilePage implements OnInit, OnDestroy {
} }
this.user.email = data.user.email; this.user.email = data.user.email;
this.user.address = CoreUserHelper.formatAddress('', data.user.city, data.user.country);
}, CoreSites.getCurrentSiteId()); }, CoreSites.getCurrentSiteId());
this.logView = CoreTime.once(async (user) => { this.logView = CoreTime.once(async (user) => {
@ -151,7 +150,6 @@ export class CoreUserProfilePage implements OnInit, OnDestroy {
try { try {
const user = await CoreUser.getProfile(this.userId, this.courseId); const user = await CoreUser.getProfile(this.userId, this.courseId);
user.address = CoreUserHelper.formatAddress('', user.city, user.country);
this.rolesFormatted = 'roles' in user ? CoreUserHelper.formatRoleList(user.roles) : ''; this.rolesFormatted = 'roles' in user ? CoreUserHelper.formatRoleList(user.roles) : '';
this.user = user; this.user = user;

View File

@ -25,6 +25,63 @@ import { CoreUserProfile, CoreUserRole } from './user';
@Injectable({ providedIn: 'root' }) @Injectable({ providedIn: 'root' })
export class CoreUserHelperProvider { export class CoreUserHelperProvider {
protected static readonly LEGACY_TIMEZONES = {
'-13.0': 'Australia/Perth',
'-12.5': 'Etc/GMT+12',
'-12.0': 'Etc/GMT+12',
'-11.5': 'Etc/GMT+11',
'-11.0': 'Etc/GMT+11',
'-10.5': 'Etc/GMT+10',
'-10.0': 'Etc/GMT+10',
'-9.5': 'Etc/GMT+9',
'-9.0': 'Etc/GMT+9',
'-8.5': 'Etc/GMT+8',
'-8.0': 'Etc/GMT+8',
'-7.5': 'Etc/GMT+7',
'-7.0': 'Etc/GMT+7',
'-6.5': 'Etc/GMT+6',
'-6.0': 'Etc/GMT+6',
'-5.5': 'Etc/GMT+5',
'-5.0': 'Etc/GMT+5',
'-4.5': 'Etc/GMT+4',
'-4.0': 'Etc/GMT+4',
'-3.5': 'Etc/GMT+3',
'-3.0': 'Etc/GMT+3',
'-2.5': 'Etc/GMT+2',
'-2.0': 'Etc/GMT+2',
'-1.5': 'Etc/GMT+1',
'-1.0': 'Etc/GMT+1',
'-0.5': 'Etc/GMT',
'0': 'Etc/GMT',
'0.0': 'Etc/GMT',
'0.5': 'Etc/GMT',
'1.0': 'Etc/GMT-1',
'1.5': 'Etc/GMT-1',
'2.0': 'Etc/GMT-2',
'2.5': 'Etc/GMT-2',
'3.0': 'Etc/GMT-3',
'3.5': 'Etc/GMT-3',
'4.0': 'Etc/GMT-4',
'4.5': 'Asia/Kabul',
'5.0': 'Etc/GMT-5',
'5.5': 'Asia/Kolkata',
'6.0': 'Etc/GMT-6',
'6.5': 'Asia/Rangoon',
'7.0': 'Etc/GMT-7',
'7.5': 'Etc/GMT-7',
'8.0': 'Etc/GMT-8',
'8.5': 'Etc/GMT-8',
'9.0': 'Etc/GMT-9',
'9.5': 'Australia/Darwin',
'10.0': 'Etc/GMT-10',
'10.5': 'Etc/GMT-10',
'11.0': 'Etc/GMT-11',
'11.5': 'Etc/GMT-11',
'12.0': 'Etc/GMT-12',
'12.5': 'Etc/GMT-12',
'13.0': 'Etc/GMT-13',
};
/** /**
* Formats a user address, concatenating address, city and country. * Formats a user address, concatenating address, city and country.
* *
@ -32,6 +89,7 @@ export class CoreUserHelperProvider {
* @param city City. * @param city City.
* @param country Country. * @param country Country.
* @returns Formatted address. * @returns Formatted address.
* @deprecated since 4.3 Not used anymore.
*/ */
formatAddress(address?: string, city?: string, country?: string): string { formatAddress(address?: string, city?: string, country?: string): string {
const separator = Translate.instant('core.listsep'); const separator = Translate.instant('core.listsep');
@ -98,6 +156,16 @@ export class CoreUserHelperProvider {
return (user.firstname?.charAt(0) || '') + (user.lastname?.charAt(0) || ''); return (user.firstname?.charAt(0) || '') + (user.lastname?.charAt(0) || '');
} }
/**
* Translates legacy timezone names.
*
* @param tz Timezone name.
* @returns Readable timezone name.
*/
translateLegacyTimezone(tz: string): string {
return CoreUserHelperProvider.LEGACY_TIMEZONES[tz] ?? tz;
}
} }
export const CoreUserHelper = makeSingleton(CoreUserHelperProvider); export const CoreUserHelper = makeSingleton(CoreUserHelperProvider);

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

After

Width:  |  Height:  |  Size: 29 KiB

View File

@ -61,7 +61,6 @@
"copiedtoclipboard": "Text copied to clipboard", "copiedtoclipboard": "Text copied to clipboard",
"copytoclipboard": "Copy to clipboard", "copytoclipboard": "Copy to clipboard",
"course": "Course", "course": "Course",
"coursedetails": "Course details",
"coursenogroups": "You are not a member of any group of this course.", "coursenogroups": "You are not a member of any group of this course.",
"currentdevice": "Current device", "currentdevice": "Current device",
"custom": "Custom", "custom": "Custom",

View File

@ -2191,7 +2191,7 @@ export const CoreDomUtils = makeSingleton(CoreDomUtilsProvider);
/** /**
* Options for the openPopover function. * Options for the openPopover function.
*/ */
export type OpenPopoverOptions = PopoverOptions & { export type OpenPopoverOptions = Omit<PopoverOptions, 'showBackdrop'> & {
waitForDismissCompleted?: boolean; waitForDismissCompleted?: boolean;
}; };

View File

@ -1236,6 +1236,7 @@ ion-chip {
ion-searchbar { ion-searchbar {
height: var(--height) !important; height: var(--height) !important;
--border-radius: var(--radius-xs);
.searchbar-input-container { .searchbar-input-container {
color: var(--color) !important; color: var(--color) !important;
@ -1243,6 +1244,8 @@ ion-searchbar {
} }
.searchbar-input { .searchbar-input {
--border-radius: var(--radius-xs);
height: var(--height) !important; height: var(--height) !important;
border: 1px solid var(--border-color) !important; border: 1px solid var(--border-color) !important;
box-shadow: none !important; box-shadow: none !important;
@ -1869,13 +1872,15 @@ video::-webkit-media-text-track-display {
} }
ion-modal { ion-modal {
.modal-wrapper { &.show-modal {
@media only screen and (min-width: 768px) and (min-height: 600px) {
--border-radius: var(--modal-radius); --border-radius: var(--modal-radius);
} }
}
&.core-modal-lateral, &.core-modal-lateral,
&.core-modal-fullscreen { &.core-modal-fullscreen {
--modal-radius: 0px; --border-radius: 0px;
} }
&.core-modal-no-background { &.core-modal-no-background {
@ -1897,6 +1902,10 @@ ion-popover {
margin-top: 2px; margin-top: 2px;
margin-bottom: 2px; margin-bottom: 2px;
} }
// Never show backdrop on popovers
ion-backdrop {
background: transparent;
}
} }
/* /*