forked from CIT/Vmeda.Online
		
	Merge pull request #2529 from crazyserver/MOBILE-3546
MOBILE-3546 login: Add options to customize site listing
This commit is contained in:
		
						commit
						59d4e189c8
					
				@ -81,6 +81,7 @@
 | 
			
		||||
    "siteurl": "",
 | 
			
		||||
    "sitename": "",
 | 
			
		||||
    "multisitesdisplay": "",
 | 
			
		||||
    "sitefindersettings": {},
 | 
			
		||||
    "onlyallowlistedsites": false,
 | 
			
		||||
    "skipssoconfirmation": false,
 | 
			
		||||
    "forcedefaultlanguage": false,
 | 
			
		||||
 | 
			
		||||
@ -14,77 +14,72 @@
 | 
			
		||||
        <div text-center padding margin-bottom [class.hidden]="hasSites || enteredSiteUrl" class="core-login-site-logo">
 | 
			
		||||
            <img src="assets/img/login_logo.png" class="avatar-full login-logo" role="presentation">
 | 
			
		||||
        </div>
 | 
			
		||||
        <form ion-list [formGroup]="siteForm" (ngSubmit)="connect($event, siteForm.value.siteUrl)" *ngIf="!fixedSites || siteSelector == 'select'" #siteFormEl>
 | 
			
		||||
        <form ion-list [formGroup]="siteForm" (ngSubmit)="connect($event, siteForm.value.siteUrl)" *ngIf="!fixedSites" #siteFormEl>
 | 
			
		||||
            <!-- Form to input the site URL if there are no fixed sites. -->
 | 
			
		||||
            <ng-container *ngIf="!fixedSites">
 | 
			
		||||
                <ng-container *ngIf="siteSelector == 'url'">
 | 
			
		||||
                    <ion-item>
 | 
			
		||||
                        <ion-label stacked><h2>{{ 'core.login.siteaddress' | translate }}</h2></ion-label>
 | 
			
		||||
                        <ion-input name="url" type="url" placeholder="{{ 'core.login.siteaddressplaceholder' | translate }}" formControlName="siteUrl" [core-auto-focus]="showKeyboard && !showScanQR"></ion-input>
 | 
			
		||||
                    </ion-item>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
                <ng-container *ngIf="siteSelector != 'url'">
 | 
			
		||||
                    <ion-item>
 | 
			
		||||
                        <ion-label stacked><h2>{{ 'core.login.siteaddress' | translate }}</h2></ion-label>
 | 
			
		||||
                        <ion-input name="url" placeholder="{{ 'core.login.siteaddressplaceholder' | translate }}" formControlName="siteUrl" [core-auto-focus]="showKeyboard && !showScanQR" (ionChange)="searchSite($event, siteForm.value.siteUrl)"></ion-input>
 | 
			
		||||
                    </ion-item>
 | 
			
		||||
            <ng-container *ngIf="siteSelector == 'url'">
 | 
			
		||||
                <ion-item>
 | 
			
		||||
                    <ion-label stacked><h2>{{ 'core.login.siteaddress' | translate }}</h2></ion-label>
 | 
			
		||||
                    <ion-input name="url" type="url" placeholder="{{ 'core.login.siteaddressplaceholder' | translate }}" formControlName="siteUrl" [core-auto-focus]="showKeyboard && !showScanQR"></ion-input>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
            </ng-container>
 | 
			
		||||
            <ng-container *ngIf="siteSelector != 'url'">
 | 
			
		||||
                <ion-item>
 | 
			
		||||
                    <ion-label stacked><h2>{{ 'core.login.siteaddress' | translate }}</h2></ion-label>
 | 
			
		||||
                    <ion-input name="url" placeholder="{{ 'core.login.siteaddressplaceholder' | translate }}" formControlName="siteUrl" [core-auto-focus]="showKeyboard && !showScanQR" (ionChange)="searchSite($event, siteForm.value.siteUrl)"></ion-input>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
 | 
			
		||||
                    <ion-list [class.hidden]="!hasSites && !enteredSiteUrl" class="core-login-site-list">
 | 
			
		||||
                        <ion-item no-lines class="core-login-site-list-title"><h2 class="item-heading">{{ 'core.login.selectsite' | translate }}</h2></ion-item>
 | 
			
		||||
                        <button ion-item *ngIf="enteredSiteUrl" (click)="connect($event, enteredSiteUrl.url)" [attr.aria-label]="'core.login.connect' | translate" detail-push class="core-login-entered-site">
 | 
			
		||||
                            <ion-thumbnail item-start>
 | 
			
		||||
                                <core-icon name="fa-pencil"></core-icon>
 | 
			
		||||
                <ion-list [class.hidden]="!hasSites && !enteredSiteUrl" class="core-login-site-list">
 | 
			
		||||
                    <ion-item no-lines class="core-login-site-list-title"><h2 class="item-heading">{{ 'core.login.selectsite' | translate }}</h2></ion-item>
 | 
			
		||||
                    <button ion-item *ngIf="enteredSiteUrl" (click)="connect($event, enteredSiteUrl.url)" [attr.aria-label]="'core.login.connect' | translate" detail-push class="core-login-entered-site">
 | 
			
		||||
                        <ion-thumbnail item-start>
 | 
			
		||||
                            <core-icon name="fa-pencil"></core-icon>
 | 
			
		||||
                        </ion-thumbnail>
 | 
			
		||||
                        <h2 text-wrap>{{ 'core.login.yourenteredsite' | translate }}</h2>
 | 
			
		||||
                        <p>{{enteredSiteUrl.noProtocolUrl}}</p>
 | 
			
		||||
                    </button>
 | 
			
		||||
 | 
			
		||||
                    <div class="core-login-site-list-found" [class.hidden]="!hasSites" [class.dimmed]="loadingSites">
 | 
			
		||||
                        <div *ngIf="loadingSites" class="core-login-site-list-loading"><ion-spinner></ion-spinner></div>
 | 
			
		||||
                        <button ion-item *ngFor="let site of sites" (click)="connect($event, site.url, site)" [attr.aria-label]="site.name" detail-push>
 | 
			
		||||
                            <ion-thumbnail item-start *ngIf="siteFinderSettings.displayimage">
 | 
			
		||||
                                <img [src]="site.imageurl" *ngIf="site.imageurl" onError="this.src='assets/icon/icon.png'">
 | 
			
		||||
                                <img src="assets/icon/icon.png" *ngIf="!site.imageurl" class="core-login-default-icon">
 | 
			
		||||
                            </ion-thumbnail>
 | 
			
		||||
                            <h2 text-wrap>{{ 'core.login.yourenteredsite' | translate }}</h2>
 | 
			
		||||
                            <p>{{enteredSiteUrl.noProtocolUrl}}</p>
 | 
			
		||||
                            <h2 *ngIf="site.title" text-wrap>{{site.title}}</h2>
 | 
			
		||||
                            <p *ngIf="site.noProtocolUrl">{{site.noProtocolUrl}}</p>
 | 
			
		||||
                            <p *ngIf="site.location">{{site.location}}</p>
 | 
			
		||||
                        </button>
 | 
			
		||||
                    </div>
 | 
			
		||||
                </ion-list>
 | 
			
		||||
 | 
			
		||||
                        <div class="core-login-site-list-found" [class.hidden]="!hasSites" [class.dimmed]="loadingSites">
 | 
			
		||||
                            <div *ngIf="loadingSites" class="core-login-site-list-loading"><ion-spinner></ion-spinner></div>
 | 
			
		||||
                            <button ion-item *ngFor="let site of sites" (click)="connect($event, site.url, site)" [attr.aria-label]="site.name" detail-push>
 | 
			
		||||
                                <ion-thumbnail item-start>
 | 
			
		||||
                                    <img [src]="site.imageurl" *ngIf="site.imageurl" onError="this.src='assets/icon/icon.png'">
 | 
			
		||||
                                    <img src="assets/icon/icon.png" *ngIf="!site.imageurl" class="core-login-default-icon">
 | 
			
		||||
                                </ion-thumbnail>
 | 
			
		||||
                                <h2 text-wrap>{{site.name}}<ng-container *ngIf="site.alias"> ({{site.alias}})</ng-container></h2>
 | 
			
		||||
                                <p>{{site.noProtocolUrl}}</p>
 | 
			
		||||
                                <p *ngIf="site.country || site.city" text-wrap><ng-container *ngIf="site.city">{{site.city}} - </ng-container>{{site.country}}</p>
 | 
			
		||||
                            </button>
 | 
			
		||||
                        </div>
 | 
			
		||||
                    </ion-list>
 | 
			
		||||
 | 
			
		||||
                    <div *ngIf="!hasSites && loadingSites" class="core-login-site-nolist-loading"><ion-spinner></ion-spinner></div>
 | 
			
		||||
                </ng-container>
 | 
			
		||||
                <div *ngIf="!hasSites && loadingSites" class="core-login-site-nolist-loading"><ion-spinner></ion-spinner></div>
 | 
			
		||||
            </ng-container>
 | 
			
		||||
 | 
			
		||||
            <!-- Pick the site from a list of fixed sites. -->
 | 
			
		||||
            <ion-item *ngIf="fixedSites && siteSelector == 'select'" margin-vertical text-wrap>
 | 
			
		||||
                <ion-label stacked for="siteSelect">{{ 'core.login.selectsite' | translate }}</ion-label>
 | 
			
		||||
                <ion-select formControlName="siteUrl" name="url" placeholder="{{ 'core.login.siteaddress' | translate }}" interface="action-sheet">
 | 
			
		||||
                    <ion-option *ngFor="let site of fixedSites" [value]="site.url">{{site.name}}</ion-option>
 | 
			
		||||
                </ion-select>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
 | 
			
		||||
            <ion-item *ngIf="(fixedSites && siteSelector == 'select') || (!fixedSites && siteSelector == 'url')" no-lines>
 | 
			
		||||
            <ion-item *ngIf="siteSelector == 'url'" no-lines>
 | 
			
		||||
                <button ion-button block [disabled]="!siteForm.valid" text-wrap>{{ 'core.login.connect' | translate }}</button>
 | 
			
		||||
            </ion-item>
 | 
			
		||||
        </form>
 | 
			
		||||
 | 
			
		||||
        <ng-container *ngIf="fixedSites">
 | 
			
		||||
            <!-- Pick the site from a list of fixed sites. -->
 | 
			
		||||
            <ion-list *ngIf="siteSelector == 'list' || siteSelector == 'listnourl'">
 | 
			
		||||
            <ion-list *ngIf="siteSelector == 'list'">
 | 
			
		||||
                <ion-item no-lines><h2 class="item-heading">{{ 'core.login.selectsite' | translate }}</h2></ion-item>
 | 
			
		||||
                <ion-searchbar *ngIf="fixedSites.length > 4" [(ngModel)]="filter" (ionInput)="filterChanged($event)" (ionCancel)="filterChanged()" [placeholder]="'core.login.findyoursite' | translate"></ion-searchbar>
 | 
			
		||||
                <ion-item *ngFor="let site of filteredSites" (click)="connect($event, site.url)" [title]="site.name" detail-push text-wrap>
 | 
			
		||||
                    <h2>{{site.name}}</h2>
 | 
			
		||||
                    <p *ngIf="siteSelector == 'list'">{{site.url}}</p>
 | 
			
		||||
                <ion-item *ngFor="let site of filteredSites" (click)="connect($event, site.url)" [title]="site.name" detail-push>
 | 
			
		||||
                    <ion-thumbnail item-start *ngIf="siteFinderSettings.displayimage">
 | 
			
		||||
                        <img [src]="site.imageurl" *ngIf="site.imageurl" onError="this.src='assets/icon/icon.png'">
 | 
			
		||||
                        <img src="assets/icon/icon.png" *ngIf="!site.imageurl" class="core-login-default-icon">
 | 
			
		||||
                    </ion-thumbnail>
 | 
			
		||||
                    <h2 *ngIf="site.title" text-wrap>{{site.title}}</h2>
 | 
			
		||||
                    <p *ngIf="site.noProtocolUrl">{{site.noProtocolUrl}}</p>
 | 
			
		||||
                    <p *ngIf="site.location">{{site.location}}</p>
 | 
			
		||||
                </ion-item>
 | 
			
		||||
            </ion-list>
 | 
			
		||||
 | 
			
		||||
            <!-- Display them using buttons. -->
 | 
			
		||||
            <div *ngIf="siteSelector == 'buttons'">
 | 
			
		||||
                <p class="padding no-padding-bottom">{{ 'core.login.selectsite' | translate }}</p>
 | 
			
		||||
                <a *ngFor="let site of fixedSites" ion-button block (click)="connect($event, site.url)" [title]="site.name" margin-bottom>{{site.name}}</a>
 | 
			
		||||
                <a *ngFor="let site of fixedSites" text-wrap ion-button block (click)="connect($event, site.url)" [title]="site.name" margin-bottom>{{site.title}}</a>
 | 
			
		||||
            </div>
 | 
			
		||||
        </ng-container>
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
@ -35,7 +35,17 @@ import { TranslateService } from '@ngx-translate/core';
 | 
			
		||||
 */
 | 
			
		||||
type CoreLoginSiteInfoExtended = CoreLoginSiteInfo & {
 | 
			
		||||
    noProtocolUrl?: string; // Url wihtout protocol.
 | 
			
		||||
    country?: string; // Based on countrycode.
 | 
			
		||||
    location?: string; // City + country.
 | 
			
		||||
    title?: string; // Name + alias.
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
type SiteFinderSettings = {
 | 
			
		||||
    displayalias: boolean,
 | 
			
		||||
    displaycity: boolean,
 | 
			
		||||
    displaycountry: boolean,
 | 
			
		||||
    displayimage: boolean,
 | 
			
		||||
    displaysitename: boolean,
 | 
			
		||||
    displayurl: boolean
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -51,8 +61,8 @@ export class CoreLoginSitePage {
 | 
			
		||||
    @ViewChild('siteFormEl') formElement: ElementRef;
 | 
			
		||||
 | 
			
		||||
    siteForm: FormGroup;
 | 
			
		||||
    fixedSites: CoreLoginSiteInfo[];
 | 
			
		||||
    filteredSites: CoreLoginSiteInfo[];
 | 
			
		||||
    fixedSites: CoreLoginSiteInfoExtended[];
 | 
			
		||||
    filteredSites: CoreLoginSiteInfoExtended[];
 | 
			
		||||
    siteSelector = 'sitefinder';
 | 
			
		||||
    showKeyboard = false;
 | 
			
		||||
    filter = '';
 | 
			
		||||
@ -62,6 +72,7 @@ export class CoreLoginSitePage {
 | 
			
		||||
    searchFnc: Function;
 | 
			
		||||
    showScanQR: boolean;
 | 
			
		||||
    enteredSiteUrl: CoreLoginSiteInfoExtended;
 | 
			
		||||
    siteFinderSettings: SiteFinderSettings;
 | 
			
		||||
 | 
			
		||||
    constructor(navParams: NavParams,
 | 
			
		||||
            protected navCtrl: NavController,
 | 
			
		||||
@ -84,13 +95,37 @@ export class CoreLoginSitePage {
 | 
			
		||||
        let url = '';
 | 
			
		||||
        this.siteSelector = CoreConfigConstants.multisitesdisplay;
 | 
			
		||||
 | 
			
		||||
        const siteFinderSettings: Partial<SiteFinderSettings> = CoreConfigConstants['sitefindersettings'] || {};
 | 
			
		||||
        this.siteFinderSettings = {
 | 
			
		||||
            displaysitename: true,
 | 
			
		||||
            displayimage: true,
 | 
			
		||||
            displayalias: true,
 | 
			
		||||
            displaycity: true,
 | 
			
		||||
            displaycountry: true,
 | 
			
		||||
            displayurl: true,
 | 
			
		||||
            ...siteFinderSettings
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
        // Load fixed sites if they're set.
 | 
			
		||||
        if (this.loginHelper.hasSeveralFixedSites()) {
 | 
			
		||||
            this.fixedSites = <any[]> this.loginHelper.getFixedSites();
 | 
			
		||||
            // Autoselect if not defined.
 | 
			
		||||
            if (['list', 'listnourl', 'select', 'buttons'].indexOf(this.siteSelector) < 0) {
 | 
			
		||||
                this.siteSelector = this.fixedSites.length > 8 ? 'list' : (this.fixedSites.length > 3 ? 'select' : 'buttons');
 | 
			
		||||
            // Deprecate listnourl on 3.9.3, remove this block on the following release.
 | 
			
		||||
            if (this.siteSelector == 'listnourl') {
 | 
			
		||||
                this.siteSelector = 'list';
 | 
			
		||||
                this.siteFinderSettings.displayurl = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.fixedSites = this.extendCoreLoginSiteInfo(<CoreLoginSiteInfoExtended[]> this.loginHelper.getFixedSites());
 | 
			
		||||
 | 
			
		||||
            // Do not show images if none are set.
 | 
			
		||||
            if (!this.fixedSites.some((site) => !!site.imageurl)) {
 | 
			
		||||
                this.siteFinderSettings.displayimage = false;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            // Autoselect if not defined.
 | 
			
		||||
            if (this.siteSelector != 'list' && this.siteSelector != 'buttons') {
 | 
			
		||||
                this.siteSelector = this.fixedSites.length > 3 ? 'list' : 'buttons';
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            this.filteredSites = this.fixedSites;
 | 
			
		||||
            url = this.fixedSites[0].url;
 | 
			
		||||
        } else if (CoreConfigConstants.enableonboarding && !this.appProvider.isIOS() && !this.appProvider.isMac()) {
 | 
			
		||||
@ -116,11 +151,8 @@ export class CoreLoginSitePage {
 | 
			
		||||
                // Update the sites list.
 | 
			
		||||
                this.sites = await this.sitesProvider.findSites(search);
 | 
			
		||||
 | 
			
		||||
                // UI tweaks.
 | 
			
		||||
                this.sites.forEach((site) => {
 | 
			
		||||
                    site.noProtocolUrl = CoreUrl.removeProtocol(site.url);
 | 
			
		||||
                    site.country = this.utils.getCountryName(site.countrycode);
 | 
			
		||||
                });
 | 
			
		||||
                // Add UI tweaks.
 | 
			
		||||
                this.sites = this.extendCoreLoginSiteInfo(this.sites);
 | 
			
		||||
 | 
			
		||||
                this.hasSites = !!this.sites.length;
 | 
			
		||||
            } else {
 | 
			
		||||
@ -132,6 +164,34 @@ export class CoreLoginSitePage {
 | 
			
		||||
        }, 1000);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Extend info of Login Site Info to get UI tweaks.
 | 
			
		||||
     *
 | 
			
		||||
     * @param  sites Sites list.
 | 
			
		||||
     * @return Sites list with extended info.
 | 
			
		||||
     */
 | 
			
		||||
    protected extendCoreLoginSiteInfo(sites: CoreLoginSiteInfoExtended[]): CoreLoginSiteInfoExtended[] {
 | 
			
		||||
        return sites.map((site) => {
 | 
			
		||||
            site.noProtocolUrl = this.siteFinderSettings.displayurl && site.url ? CoreUrl.removeProtocol(site.url) : '';
 | 
			
		||||
 | 
			
		||||
            const name = this.siteFinderSettings.displaysitename ? site.name : '';
 | 
			
		||||
            const alias = this.siteFinderSettings.displayalias && site.alias ? site.alias : '';
 | 
			
		||||
 | 
			
		||||
            // Set title with parenthesis if both name and alias are present.
 | 
			
		||||
            site.title = name && alias ? name + ' (' + alias + ')' : name + alias;
 | 
			
		||||
 | 
			
		||||
            const country = this.siteFinderSettings.displaycountry && site.countrycode ?
 | 
			
		||||
                this.utils.getCountryName(site.countrycode) : '';
 | 
			
		||||
            const city = this.siteFinderSettings.displaycity && site.city ?
 | 
			
		||||
                site.city : '';
 | 
			
		||||
 | 
			
		||||
            // Separate location with hiphen if both country and city are present.
 | 
			
		||||
            site.location = city && country ? city + ' - ' + country : city + country;
 | 
			
		||||
 | 
			
		||||
            return site;
 | 
			
		||||
        });
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /**
 | 
			
		||||
     * Try to connect to a site.
 | 
			
		||||
     *
 | 
			
		||||
@ -224,7 +284,8 @@ export class CoreLoginSitePage {
 | 
			
		||||
            this.filteredSites = this.fixedSites;
 | 
			
		||||
        } else {
 | 
			
		||||
            this.filteredSites = this.fixedSites.filter((site) => {
 | 
			
		||||
                return site.name.toLowerCase().indexOf(newValue) > -1 || site.url.toLowerCase().indexOf(newValue) > -1;
 | 
			
		||||
                return site.title.toLowerCase().indexOf(newValue) > -1 || site.noProtocolUrl.toLowerCase().indexOf(newValue) > -1 ||
 | 
			
		||||
                    site.location.toLowerCase().indexOf(newValue) > -1;
 | 
			
		||||
            });
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
@ -21,7 +21,7 @@ import { CoreConfigProvider } from '@providers/config';
 | 
			
		||||
import { CoreEventsProvider } from '@providers/events';
 | 
			
		||||
import { CoreInitDelegate } from '@providers/init';
 | 
			
		||||
import { CoreLoggerProvider } from '@providers/logger';
 | 
			
		||||
import { CoreSitesProvider } from '@providers/sites';
 | 
			
		||||
import { CoreSitesProvider, CoreLoginSiteInfo } from '@providers/sites';
 | 
			
		||||
import { CoreWSProvider } from '@providers/ws';
 | 
			
		||||
import { CoreDomUtilsProvider } from '@providers/utils/dom';
 | 
			
		||||
import { CoreTextUtilsProvider } from '@providers/utils/text';
 | 
			
		||||
@ -463,7 +463,7 @@ export class CoreLoginHelperProvider {
 | 
			
		||||
     *
 | 
			
		||||
     * @return Fixed site or list of fixed sites.
 | 
			
		||||
     */
 | 
			
		||||
    getFixedSites(): string | any[] {
 | 
			
		||||
    getFixedSites(): string | CoreLoginSiteInfo[] {
 | 
			
		||||
        return CoreConfigConstants.siteurl;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user