2
0
Fork 0

MOBILE-4081 settings: Divide space usage in sites

main
Pau Ferrer Ocaña 2022-11-23 14:13:29 +01:00
parent 2a1493b649
commit f61bd0f550
2 changed files with 154 additions and 57 deletions

View File

@ -17,31 +17,70 @@
<ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content> <ion-refresher-content pullingText="{{ 'core.pulltorefresh' | translate }}"></ion-refresher-content>
</ion-refresher> </ion-refresher>
<core-loading [hideUntil]="loaded"> <core-loading [hideUntil]="loaded">
<ion-list> <ion-list class="core-sitelist limited-width">
<ion-item *ngFor="let site of sites" [class.item-current]="site.id == currentSiteId"> <ion-card *ngIf="accountsList.currentSite">
<ion-label class="ion-text-wrap"> <ion-item-divider sticky="true" class="core-sitelist-sitename">
<ion-label>
<p class="item-heading"> <p class="item-heading">
<core-format-text [text]="site.siteName" clean="true" [siteId]="site.id"></core-format-text> <core-format-text [text]="accountsList.currentSite.siteName" clean="true"
[siteId]="accountsList.currentSite.id"></core-format-text>
</p>
<p><a [href]="accountsList.currentSite.siteUrl" core-link autoLogin="yes">{{
accountsList.currentSite.siteUrlWithoutProtocol }}</a>
</p> </p>
<p class="ion-text-wrap">{{ site.fullName }}</p>
<p>{{ site.siteUrlWithoutProtocol }}</p>
<ion-badge color="light" *ngIf="site.spaceUsage !== undefined">{{ site.spaceUsage | coreBytesToSize }}</ion-badge>
</ion-label> </ion-label>
<ion-button fill="clear" color="danger" slot="end" (click)="deleteSiteStorage(site)" </ion-item-divider>
[hidden]="site.spaceUsage! + site.cacheEntries! <= 0">
<ion-icon name="fas-trash" slot="icon-only" <ion-item class="item-current">
[attr.aria-label]="'addon.storagemanager.deletedatafrom' | translate: { name: site.siteName }"> <ng-container *ngTemplateOutlet="siteUsage; context: {site: accountsList.currentSite}"></ng-container>
</ion-icon>
</ion-button>
</ion-item> </ion-item>
<ion-item *ngFor="let site of accountsList.sameSite">
<ng-container *ngTemplateOutlet="siteUsage; context: {site: site}"></ng-container>
</ion-item>
</ion-card>
<ion-card *ngFor="let sites of accountsList.otherSites">
<ion-item-divider sticky="true" *ngIf="sites[0]" class="core-sitelist-sitename">
<ion-label>
<p class="item-heading">
<core-format-text [text]="sites[0].siteName" clean="true" [siteId]="sites[0].id"></core-format-text>
</p>
<p><a [href]="sites[0].siteUrl" core-link autoLogin="no">{{ sites[0].siteUrlWithoutProtocol }}</a></p>
</ion-label>
</ion-item-divider>
<ion-item *ngFor="let site of sites">
<ng-container *ngTemplateOutlet="siteUsage; context: {site: site}"></ng-container>
</ion-item>
</ion-card>
<ion-item-divider> <ion-item-divider>
<ion-label> <ion-label>
<h2>{{ 'core.settings.total' | translate }}</h2> <h2>{{ 'core.settings.total' | translate }}</h2>
</ion-label> </ion-label>
<p slot="end" class="ion-margin-end"> <p slot="end" class="ion-margin-end">
{{ totals.spaceUsage | coreBytesToSize }} {{ totalSpaceUsage | coreBytesToSize }}
</p> </p>
</ion-item-divider> </ion-item-divider>
</ion-list> </ion-list>
</core-loading> </core-loading>
</ion-content> </ion-content>
<!-- Template to render a site space usage. -->
<ng-template #siteUsage let-site="site">
<ion-avatar slot="start">
<img [src]="site.avatar" core-external-content [siteId]="site.id" alt="{{ 'core.pictureof' | translate:{$a: site.fullName} }}"
onError="this.src='assets/img/user-avatar.png'">
</ion-avatar>
<ion-label class="ion-text-wrap">
<p class="item-heading">{{site.fullName}}</p>
<ion-badge color="light" *ngIf="site.spaceUsage !== undefined">{{ site.spaceUsage | coreBytesToSize }}</ion-badge>
</ion-label>
<ion-button fill="clear" color="danger" slot="end" (click)="deleteSiteStorage(site)"
[hidden]="site.spaceUsage <= 0 && !site.hasCacheEntries">
<ion-icon name="fas-trash" slot="icon-only"
[attr.aria-label]="'addon.storagemanager.deletedatafrom' | translate: { name: site.siteName }">
</ion-icon>
</ion-button>
</ng-template>

View File

@ -16,9 +16,10 @@ import { Component, OnDestroy, OnInit } from '@angular/core';
import { IonRefresher } from '@ionic/angular'; import { IonRefresher } from '@ionic/angular';
import { CoreSiteBasicInfo, CoreSites } from '@services/sites'; import { CoreSiteBasicInfo, CoreSites } from '@services/sites';
import { CoreUtils } from '@services/utils/utils';
import { CoreEventObserver, CoreEvents } from '@singletons/events'; import { CoreEventObserver, CoreEvents } from '@singletons/events';
import { CoreSettingsHelper, CoreSiteSpaceUsage } from '../../services/settings-helper'; import { CoreSettingsHelper } from '../../services/settings-helper';
/** /**
* Page that displays the space usage settings. * Page that displays the space usage settings.
@ -30,37 +31,52 @@ import { CoreSettingsHelper, CoreSiteSpaceUsage } from '../../services/settings-
export class CoreSettingsSpaceUsagePage implements OnInit, OnDestroy { export class CoreSettingsSpaceUsagePage implements OnInit, OnDestroy {
loaded = false; loaded = false;
sites: CoreSiteBasicInfoWithUsage[] = []; totalSpaceUsage = 0;
currentSiteId = '';
totals: CoreSiteSpaceUsage = { accountsList: CoreAccountsListWithUsage = {
cacheEntries: 0, sameSite: [],
spaceUsage: 0, otherSites: [],
}; };
protected sitesObserver: CoreEventObserver; protected sitesObserver: CoreEventObserver;
constructor() { constructor() {
this.currentSiteId = CoreSites.getCurrentSiteId();
this.sitesObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, async (data) => { this.sitesObserver = CoreEvents.on(CoreEvents.SITE_UPDATED, async (data) => {
const site = await CoreSites.getSite(data.siteId); const siteId = data.siteId;
const siteEntry = this.sites.find((siteEntry) => siteEntry.id == site.id); let siteEntry = siteId === this.accountsList.currentSite?.id
if (siteEntry) { ? this.accountsList.currentSite
: undefined;
if (!siteEntry) {
siteEntry = this.accountsList.sameSite.find((siteEntry) => siteEntry.id === siteId);
}
if (!siteEntry) {
this.accountsList.otherSites.some((sites) => {
siteEntry = sites.find((siteEntry) => siteEntry.id === siteId);
return siteEntry;
});
}
if (!siteEntry) {
return;
}
const site = await CoreSites.getSite(siteId);
const siteInfo = site.getInfo(); const siteInfo = site.getInfo();
siteEntry.siteName = site.getSiteName(); siteEntry.siteName = site.getSiteName();
if (siteInfo) { if (siteInfo) {
siteEntry.siteUrl = siteInfo.siteurl; siteEntry.siteUrl = siteInfo.siteurl;
siteEntry.fullName = siteInfo.fullname; siteEntry.fullName = siteInfo.fullname;
} }
}
}); });
} }
/** /**
* View loaded. * @inheritdoc
*/ */
ngOnInit(): void { ngOnInit(): void {
this.loadSiteData().finally(() => { this.loadSiteData().finally(() => {
@ -76,31 +92,65 @@ export class CoreSettingsSpaceUsagePage implements OnInit, OnDestroy {
protected async loadSiteData(): Promise<void> { protected async loadSiteData(): Promise<void> {
// Calculate total usage. // Calculate total usage.
let totalSize = 0; let totalSize = 0;
let totalEntries = 0;
this.sites = await CoreSites.getSortedSites(); const sites = await CoreUtils.ignoreErrors(CoreSites.getSortedSites(), [] as CoreSiteBasicInfo[]);
const sitesWithUsage = await Promise.all(sites.map((site) => this.getSiteWithUsage(site)));
const settingsHelper = CoreSettingsHelper.instance; let siteUrl = '';
const currentSiteId = CoreSites.getCurrentSiteId();
if (currentSiteId) {
const index = sitesWithUsage.findIndex((site) => site.id === currentSiteId);
const siteWithUsage = sitesWithUsage.splice(index, 1)[0];
this.accountsList.currentSite = siteWithUsage;
totalSize += siteWithUsage.spaceUsage || 0;
siteUrl = this.accountsList.currentSite.siteUrlWithoutProtocol;
}
const otherSites: Record<string, CoreSiteBasicInfoWithUsage[]> = {};
// Get space usage. // Get space usage.
await Promise.all(this.sites.map(async (site) => { sitesWithUsage.forEach((siteWithUsage) => {
const siteInfo = await settingsHelper.getSiteSpaceUsage(site.id); totalSize += siteWithUsage.spaceUsage || 0;
site.cacheEntries = siteInfo.cacheEntries; if (siteWithUsage.siteUrlWithoutProtocol === siteUrl) {
site.spaceUsage = siteInfo.spaceUsage; this.accountsList.sameSite.push(siteWithUsage);
} else {
if (otherSites[siteWithUsage.siteUrlWithoutProtocol] === undefined) {
otherSites[siteWithUsage.siteUrlWithoutProtocol] = [];
}
totalSize += site.spaceUsage || 0; otherSites[siteWithUsage.siteUrlWithoutProtocol].push(siteWithUsage);
totalEntries += site.cacheEntries || 0; }
})); });
this.totals.spaceUsage = totalSize; this.accountsList.otherSites = CoreUtils.objectToArray(otherSites);
this.totals.cacheEntries = totalEntries;
this.totalSpaceUsage = totalSize;
}
/**
* Get site with space usage.
*
* @param site Site to check.
* @return Site with usage.
*/
protected async getSiteWithUsage(site: CoreSiteBasicInfo): Promise<CoreSiteBasicInfoWithUsage> {
const siteInfo = await CoreSettingsHelper.getSiteSpaceUsage(site.id);
return Object.assign(site, {
hasCacheEntries: siteInfo.cacheEntries > 0,
spaceUsage: siteInfo.spaceUsage,
});
} }
/** /**
* Refresh the data. * Refresh the data.
* *
* @param event Refresher event. * @param refresher Refresher event.
*/ */
refreshData(refresher?: IonRefresher): void { refreshData(refresher?: IonRefresher): void {
this.loadSiteData().finally(() => { this.loadSiteData().finally(() => {
@ -117,21 +167,20 @@ export class CoreSettingsSpaceUsagePage implements OnInit, OnDestroy {
try { try {
const newInfo = await CoreSettingsHelper.deleteSiteStorage(siteData.siteName || '', siteData.id); const newInfo = await CoreSettingsHelper.deleteSiteStorage(siteData.siteName || '', siteData.id);
this.totals.spaceUsage -= siteData.spaceUsage! - newInfo.spaceUsage; this.totalSpaceUsage -= siteData.spaceUsage - newInfo.spaceUsage;
this.totals.spaceUsage -= siteData.cacheEntries! - newInfo.cacheEntries;
siteData.spaceUsage = newInfo.spaceUsage; siteData.spaceUsage = newInfo.spaceUsage;
siteData.cacheEntries = newInfo.cacheEntries; siteData.hasCacheEntries = newInfo.cacheEntries > 0;
} catch { } catch {
// Ignore cancelled confirmation modal. // Ignore cancelled confirmation modal.
} }
} }
/** /**
* Page destroyed. * @inheritdoc
*/ */
ngOnDestroy(): void { ngOnDestroy(): void {
this.sitesObserver?.off(); this.sitesObserver.off();
} }
} }
@ -139,7 +188,16 @@ export class CoreSettingsSpaceUsagePage implements OnInit, OnDestroy {
/** /**
* Basic site info with space usage and cache entries that can be erased. * Basic site info with space usage and cache entries that can be erased.
*/ */
export interface CoreSiteBasicInfoWithUsage extends CoreSiteBasicInfo { interface CoreSiteBasicInfoWithUsage extends CoreSiteBasicInfo {
cacheEntries?: number; // Number of cached entries that can be cleared. hasCacheEntries: boolean; // If has cached entries that can be cleared.
spaceUsage?: number; // Space used in this site. spaceUsage: number; // Space used in this site.
} }
/**
* Accounts list for selecting sites interfaces.
*/
type CoreAccountsListWithUsage = {
currentSite?: CoreSiteBasicInfoWithUsage; // If logged in, current site info.
sameSite: CoreSiteBasicInfoWithUsage[]; // If logged in, accounts info on the same site.
otherSites: CoreSiteBasicInfoWithUsage[][]; // Other accounts in other sites.
};