MOBILE-3807 usermenu: Change UI and texts

main
Pau Ferrer Ocaña 2021-10-29 12:36:42 +02:00
parent b9bf018966
commit d3ffc45be3
10 changed files with 71 additions and 88 deletions

View File

@ -2255,6 +2255,7 @@
"core.user.participants": "moodle",
"core.user.phone1": "moodle",
"core.user.phone2": "moodle",
"core.user.profile": "moodle",
"core.user.roles": "moodle",
"core.user.sendemail": "local_moodlemobileapp",
"core.user.student": "moodle/defaultcoursestudent",

View File

@ -26,7 +26,8 @@
<core-format-text [text]="accountsList.currentSite.siteName" clean="true"
[siteId]="accountsList.currentSite.id"></core-format-text>
</h2>
<p><a [href]="accountsList.currentSite.siteUrl" core-link autoLogin="yes">{{ accountsList.currentSite.siteUrl }}</a>
<p><a [href]="accountsList.currentSite.siteUrl" core-link autoLogin="yes">{{
accountsList.currentSite.siteUrlWithoutProtocol }}</a>
</p>
</ion-label>
</ion-item-divider>
@ -52,7 +53,7 @@
<h2>
<core-format-text [text]="sites[0].siteName" clean="true" [siteId]="sites[0].id"></core-format-text>
</h2>
<p><a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrl }}</a></p>
<p><a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrlWithoutProtocol }}</a></p>
</ion-label>
</ion-item-divider>

View File

@ -26,7 +26,7 @@
<h2>
<core-format-text [text]="sites[0].siteName" clean="true" [siteId]="sites[0].id"></core-format-text>
</h2>
<p><a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrl }}</a></p>
<p><a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrlWithoutProtocol }}</a></p>
</ion-label>
</ion-item-divider>

View File

@ -1357,25 +1357,23 @@ export class CoreLoginHelperProvider {
const index = sites.findIndex((site) => site.id == currentSiteId);
accountsList.currentSite = sites.splice(index, 1)[0];
siteUrl = accountsList.currentSite.siteUrl.replace(/^https?:\/\//, '').toLowerCase();
accountsList.currentSite.siteUrl = siteUrl;
siteUrl = accountsList.currentSite.siteUrlWithoutProtocol;
}
const otherSites: Record<string, CoreSiteBasicInfo[]> = {};
// Add site counter and classify sites.
await Promise.all(sites.map(async (site) => {
site.siteUrl = site.siteUrl.replace(/^https?:\/\//, '').toLowerCase();
site.badge = await CoreUtils.ignoreErrors(CorePushNotifications.getSiteCounter(site.id)) || 0;
if (site.siteUrl == siteUrl) {
if (site.siteUrlWithoutProtocol == siteUrl) {
accountsList.sameSite.push(site);
} else {
if (!otherSites[site.siteUrl]) {
otherSites[site.siteUrl] = [];
if (!otherSites[site.siteUrlWithoutProtocol]) {
otherSites[site.siteUrlWithoutProtocol] = [];
}
otherSites[site.siteUrl].push(site);
otherSites[site.siteUrlWithoutProtocol].push(site);
}
return;
@ -1396,11 +1394,11 @@ export class CoreLoginHelperProvider {
async deleteAccountFromList(accountsList: CoreAccountsList, site: CoreSiteBasicInfo): Promise<void> {
await CoreSites.deleteSite(site.id);
const siteUrl = site.siteUrl;
const siteUrl = site.siteUrlWithoutProtocol;
let index = 0;
// Found on same site.
if (accountsList.sameSite.length > 0 && accountsList.sameSite[0].siteUrl == siteUrl) {
if (accountsList.sameSite.length > 0 && accountsList.sameSite[0].siteUrlWithoutProtocol == siteUrl) {
index = accountsList.sameSite.findIndex((listedSite) => listedSite.id == site.id);
if (index >= 0) {
accountsList.sameSite.splice(index, 1);
@ -1410,7 +1408,8 @@ export class CoreLoginHelperProvider {
return;
}
const otherSiteIndex = accountsList.otherSites.findIndex((sites) => sites.length > 0 && sites[0].siteUrl == siteUrl);
const otherSiteIndex = accountsList.otherSites.findIndex((sites) =>
sites.length > 0 && sites[0].siteUrlWithoutProtocol == siteUrl);
if (otherSiteIndex < 0) {
// Site Url not found.
return;

View File

@ -8,32 +8,19 @@
<h1>
{{'core.user.account' | translate}}
</h1>
<ion-buttons slot="end" *ngIf="loaded">
<ion-button fill="clear" *ngIf="moreSites" (click)="switchAccounts($event)"
[attr.aria-label]="'core.mainmenu.changeaccount' | translate">
<ion-icon name="fas-exchange-alt" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
<ion-button fill="clear" *ngIf="!moreSites" (click)="addAccount($event)"
[attr.aria-label]="'core.login.add' | translate">
<ion-icon name="fas-user-plus" slot="icon-only" aria-hidden="true"></ion-icon>
</ion-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content>
<ion-list>
<ion-item class="ion-text-center core-user-profile-maininfo" *ngIf="siteInfo" lines="none">
<core-user-avatar [user]="siteInfo" [userId]="siteInfo.userid" [linkProfile]="false"></core-user-avatar>
<ion-item button class="core-user-profile-maininfo" *ngIf="siteInfo" lines="full" (click)="switchAccounts($event)" detail="true"
[attr.aria-label]="'core.mainmenu.switchaccount' | translate">
<core-user-avatar [user]="siteInfo" [userId]="siteInfo.userid" [linkProfile]="false" slot="start"></core-user-avatar>
<ion-label>
<h2>{{ siteInfo.fullname }}</h2>
<p class="core-usermenu-siteinfo core-usermenu-sitename">
<core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0"
[wsNotFiltered]="true">
<core-format-text [text]="siteName" contextLevel="system" [contextInstanceId]="0" [wsNotFiltered]="true">
</core-format-text>
</p>
<p class="core-usermenu-siteinfo core-usermenu-siteurl">
<a [href]="siteUrl" core-link autoLogin="yes">{{ siteUrl }}</a>
</p>
</ion-label>
</ion-item>
@ -41,7 +28,7 @@
[attr.aria-label]="'core.user.details' | translate" detail="true" lines="none">
<ion-icon name="fas-user" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<p class="item-heading">{{ 'core.user.details' | translate }}</p>
<p class="item-heading">{{ 'core.user.profile' | translate }}</p>
</ion-label>
</ion-item>
@ -51,17 +38,17 @@
</ion-label>
</ion-item>
<ion-item button *ngFor="let handler of handlers" class="ion-text-wrap"
(click)="handlerClicked($event, handler)" [ngClass]="['core-user-menu-handler', handler.class || '']"
[hidden]="handler.hidden" [attr.aria-label]="handler.title | translate" detail="true" lines="none">
<ion-item button *ngFor="let handler of handlers" class="ion-text-wrap" (click)="handlerClicked($event, handler)"
[ngClass]="['core-user-menu-handler', handler.class || '']" [hidden]="handler.hidden"
[attr.aria-label]="handler.title | translate" detail="true" lines="none">
<ion-icon *ngIf="handler.icon" [name]="handler.icon" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<p class="item-heading">{{ handler.title | translate }}</p>
</ion-label>
</ion-item>
<ion-item button (click)="openPreferences($event)" [attr.aria-label]="'core.settings.preferences' | translate"
detail="true" class="core-user-menu-preferences">
<ion-item button (click)="openPreferences($event)" [attr.aria-label]="'core.settings.preferences' | translate" detail="true"
class="core-user-menu-preferences">
<ion-icon name="fas-wrench" slot="start" aria-hidden="true"></ion-icon>
<ion-label>
<p class="item-heading">{{ 'core.settings.preferences' | translate }}</p>
@ -70,8 +57,8 @@
</ion-list>
</ion-content>
<ion-footer class="ion-padding">
<ion-button (click)="logout($event)" expand="block" color="danger"
[attr.aria-label]="'core.mainmenu.logout' | translate" class="ion-text-wrap">
<ion-button (click)="logout($event)" expand="block" color="danger" [attr.aria-label]="'core.mainmenu.logout' | translate"
class="ion-text-wrap">
<ion-icon name="fas-sign-out-alt" slot="start" aria-hidden="true"></ion-icon>
{{ 'core.mainmenu.logout' | translate }}
</ion-button>

View File

@ -1,22 +1,6 @@
@import "~theme/globals";
:host {
.core-user-profile-maininfo::part(native) {
flex-direction: column;
}
::ng-deep {
core-user-avatar {
display: block;
--core-avatar-size: var(--core-large-avatar-size);
height: calc(var(--core-avatar-size) + 16px);
img {
margin: 8px auto;
}
}
}
.core-user-menu-preferences {
--inner-border-width: 0;
--border-width: 1px 0 0 0;

View File

@ -25,7 +25,7 @@
<core-format-text [text]="site.siteName" clean="true" [siteId]="site.id"></core-format-text>
</p>
<p class="ion-text-wrap">{{ site.fullName }}</p>
<p>{{ site.siteUrl }}</p>
<p>{{ site.siteUrlWithoutProtocol }}</p>
</ion-label>
<p *ngIf="site.spaceUsage !== undefined" slot="end">
{{ site.spaceUsage | coreBytesToSize }}

View File

@ -37,7 +37,7 @@
<core-format-text [text]="site.siteName" clean="true" [siteId]="site.id"></core-format-text>
</p>
<p>{{ site.fullName }}</p>
<p>{{ site.siteUrl }}</p>
<p>{{ site.siteUrlWithoutProtocol }}</p>
</ion-label>
<core-button-with-spinner [loading]="isSynchronizing(site.id)" slot="end">
<ion-button fill="clear" (click)="synchronize(site.id)" [title]="site.siteName"

View File

@ -3,7 +3,7 @@
<ion-buttons slot="start">
<ion-back-button [text]="'core.back' | translate"></ion-back-button>
</ion-buttons>
<h1>{{ 'core.user.details' | translate }}</h1>
<h1>{{ 'core.user.profile' | translate }}</h1>
</ion-toolbar>
</ion-header>
<ion-content>
@ -14,56 +14,55 @@
<ion-list *ngIf="user">
<ion-item class="ion-text-center core-user-profile-maininfo" lines="full">
<core-user-avatar [user]="user" [userId]="user.id" [linkProfile]="false" [checkOnline]="true">
<ion-button
class="edit-avatar"
*ngIf="canChangeProfilePicture"
(click)="changeProfilePicture()"
[attr.aria-label]="'core.user.newpicture' | translate"
fill="clear"
color="dark"
>
<ion-button class="edit-avatar" *ngIf="canChangeProfilePicture" (click)="changeProfilePicture()"
[attr.aria-label]="'core.user.newpicture' | translate" fill="clear" color="dark">
<ion-icon slot="icon-only" name="fas-pen" aria-hidden="true"></ion-icon>
</ion-button>
</core-user-avatar>
<ion-label>
<h2>{{ user.fullname }}</h2>
<p *ngIf="user.address"><ion-icon name="fas-map-marker-alt" [attr.aria-hidden]="true"></ion-icon> {{ user.address }}</p>
<p *ngIf="user.address">
<ion-icon name="fas-map-marker-alt" [attr.aria-hidden]="true"></ion-icon> {{ user.address }}
</p>
</ion-label>
</ion-item>
<ion-item-group *ngIf="hasContact">
<ion-item-divider><ion-label><h2>{{ 'core.user.contact' | translate}}</h2></ion-label></ion-item-divider>
<ion-item-divider>
<ion-label>
<h2>{{ 'core.user.contact' | translate}}</h2>
</ion-label>
</ion-item-divider>
<ion-item class="ion-text-wrap" *ngIf="user.email">
<ion-label>
<h2>{{ 'core.user.email' | translate }}</h2>
<p><a class="core-anchor" href="mailto:{{user.email}}" core-link auto-login="no"
[showBrowserWarning]="false">
{{ user.email }}
</a></p>
<p><a class="core-anchor" href="mailto:{{user.email}}" core-link auto-login="no" [showBrowserWarning]="false">
{{ user.email }}
</a></p>
</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="user.phone1">
<ion-label>
<h2>{{ 'core.user.phone1' | translate}}</h2>
<p><a class="core-anchor" href="tel:{{user.phone1}}" core-link auto-login="no" [showBrowserWarning]="false">
{{ user.phone1 }}
</a></p>
{{ user.phone1 }}
</a></p>
</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="user.phone2">
<ion-label>
<h2>{{ 'core.user.phone2' | translate}}</h2>
<p><a class="core-anchor" href="tel:{{user.phone2}}" core-link auto-login="no" [showBrowserWarning]="false">
{{ user.phone2 }}
</a></p>
{{ user.phone2 }}
</a></p>
</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="formattedAddress">
<ion-label>
<h2>{{ 'core.user.address' | translate}}</h2>
<p><a class="core-anchor" [href]="encodedAddress" core-link auto-login="no" [showBrowserWarning]="false">
{{ formattedAddress }}
</a></p>
{{ formattedAddress }}
</a></p>
</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="user.city && !formattedAddress">
@ -80,13 +79,17 @@
</ion-item>
</ion-item-group>
<ion-item-group *ngIf="hasDetails">
<ion-item-divider><ion-label><h2>{{ 'core.userdetails' | translate}}</h2></ion-label></ion-item-divider>
<ion-item-divider>
<ion-label>
<h2>{{ 'core.userdetails' | translate}}</h2>
</ion-label>
</ion-item-divider>
<ion-item class="ion-text-wrap" *ngIf="user.url">
<ion-label>
<h2>{{ 'core.user.webpage' | translate}}</h2>
<p><a class="core-anchor" href="{{user.url}}" core-link>
{{ user.url }}
</a></p>
{{ user.url }}
</a></p>
</ion-label>
</ion-item>
<ion-item class="ion-text-wrap" *ngIf="user.interests">
@ -100,11 +103,17 @@
</core-user-profile-field>
</ion-item-group>
<ion-item-group *ngIf="user.description">
<ion-item-divider><ion-label><h2>{{ 'core.user.description' | translate}}</h2></ion-label></ion-item-divider>
<ion-item-divider>
<ion-label>
<h2>{{ 'core.user.description' | translate}}</h2>
</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>
<p>
<core-format-text [text]="user.description" contextLevel="user" [contextInstanceId]="user.id">
</core-format-text>
</p>
</ion-label>
</ion-item>
</ion-item-group>

View File

@ -1052,8 +1052,10 @@ export class CoreSitesProvider {
* @param siteId The site ID. If not defined, current site (if available).
* @return Promise resolved with site home ID.
*/
getSiteHomeId(siteId?: string): Promise<number> {
return this.getSite(siteId).then((site) => site.getSiteHomeId());
async getSiteHomeId(siteId?: string): Promise<number> {
const site = await this.getSite(siteId);
return site.getSiteHomeId();
}
/**
@ -1074,6 +1076,7 @@ export class CoreSitesProvider {
const basicInfo: CoreSiteBasicInfo = {
id: site.id,
siteUrl: site.siteUrl,
siteUrlWithoutProtocol: site.siteUrl.replace(/^https?:\/\//, '').toLowerCase(),
fullName: siteInfo?.fullname,
siteName: CoreConstants.CONFIG.sitename == '' ? siteInfo?.sitename: CoreConstants.CONFIG.sitename,
avatar: siteInfo?.userpictureurl,
@ -1098,9 +1101,7 @@ export class CoreSitesProvider {
// Sort sites by url and fullname.
sites.sort((a, b) => {
// First compare by site url without the protocol.
const urlA = a.siteUrl.replace(/^https?:\/\//, '').toLowerCase();
const urlB = b.siteUrl.replace(/^https?:\/\//, '').toLowerCase();
const compare = urlA.localeCompare(urlB);
const compare = a.siteUrlWithoutProtocol.localeCompare(b.siteUrlWithoutProtocol);
if (compare !== 0) {
return compare;
@ -1756,6 +1757,7 @@ export type CoreSiteUserTokenResponse = {
export type CoreSiteBasicInfo = {
id: string; // Site ID.
siteUrl: string; // Site URL.
siteUrlWithoutProtocol: string; // Site URL without protocol.
fullName?: string; // User's full name.
siteName?: string; // Site's name.
avatar?: string; // User's avatar.