@sumaris-net/ngx-components 0.25.2 → 0.25.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -8168,6 +8168,19 @@ let Peer = Peer_1 = class Peer extends Entity {
8168
8168
  path: noTrailingSlash(url.pathname)
8169
8169
  });
8170
8170
  }
8171
+ static path(peer, ...paths) {
8172
+ if (!peer)
8173
+ throw new Error('Missing required argument \'peer\'!');
8174
+ // Remove starting slashes
8175
+ paths = (paths || []).map(path => {
8176
+ if (path.startsWith('./'))
8177
+ return path.substring(2);
8178
+ if (path.startsWith('/'))
8179
+ return path.substring(1);
8180
+ return path;
8181
+ }).filter(isNotNilOrBlank);
8182
+ return [noTrailingSlash(Peer_1.fromObject(peer).url)].concat(...paths).join('/');
8183
+ }
8171
8184
  asObject(options) {
8172
8185
  return super.asObject(options);
8173
8186
  }
@@ -13646,6 +13659,7 @@ class PlatformService {
13646
13659
  this.browser = browser;
13647
13660
  this.downloader = downloader;
13648
13661
  this._started = false;
13662
+ this._downloadingPromise = new Map();
13649
13663
  this._debug = !environment.production;
13650
13664
  if (this._debug)
13651
13665
  console.debug('[platform] Creating service');
@@ -13766,10 +13780,18 @@ class PlatformService {
13766
13780
  if (!request || !request.uri)
13767
13781
  throw new Error('Missing argument \'request\' or \'request.uri\'');
13768
13782
  if (this._android && this.downloader) {
13769
- request = Object.assign({ visibleInDownloadsUi: true, notificationVisibility: NotificationVisibility.VisibleNotifyCompleted }, request);
13783
+ // Check if not already downloading file
13784
+ let promise = this._downloadingPromise.get(request.uri);
13785
+ if (promise)
13786
+ return promise;
13787
+ request = Object.assign({ visibleInDownloadsUi: true, notificationVisibility: NotificationVisibility.VisibleNotifyCompleted, title: request.title || request.filename }, request);
13770
13788
  try {
13771
13789
  console.debug('[platform] Downloading, using request: ' + JSON.stringify(request));
13772
- const location = yield this.downloader.download(request);
13790
+ // Start download
13791
+ promise = this.downloader.download(request);
13792
+ // Remember this request uri
13793
+ this._downloadingPromise.set(request.uri, promise);
13794
+ const location = yield promise;
13773
13795
  console.info('[platform] File successfully downloaded at:' + location);
13774
13796
  return location;
13775
13797
  }
@@ -13777,12 +13799,15 @@ class PlatformService {
13777
13799
  console.error('[platform] Unable to download: ' + (err && err.message || err));
13778
13800
  throw err;
13779
13801
  }
13802
+ finally {
13803
+ // Forget the request
13804
+ this._downloadingPromise.delete(request.uri);
13805
+ }
13780
13806
  }
13781
- // Fallback (no Cordova)
13782
- // Web mode: open URI using the browser
13807
+ // Fallback (if not Android and Cordova): opening the URI using the browser
13783
13808
  // TODO: find a way to download under iOS (see https://www.c-sharpcorner.com/article/how-to-download-a-file-using-file-transfer-plugin-in-ionic-3/)
13784
13809
  else {
13785
- console.warn('[platform] Cannot use Cordova downloader: using browser open()');
13810
+ console.warn('[platform] Cannot use Android downloader: using browser open()');
13786
13811
  this.open(request.uri, '_system', 'location=no', true);
13787
13812
  return undefined;
13788
13813
  }
@@ -18450,10 +18475,11 @@ const MimeTypes = Object.freeze({
18450
18475
  ANDROID_APK: 'application/vnd.android.package-archive'
18451
18476
  });
18452
18477
  class AppInstallUpgradeCard {
18453
- constructor(modalCtrl, configService, toastController, translate, cd, platform, network, environment) {
18478
+ constructor(modalCtrl, configService, toastController, alertController, translate, cd, platform, network, environment) {
18454
18479
  this.modalCtrl = modalCtrl;
18455
18480
  this.configService = configService;
18456
18481
  this.toastController = toastController;
18482
+ this.alertController = alertController;
18457
18483
  this.translate = translate;
18458
18484
  this.cd = cd;
18459
18485
  this.platform = platform;
@@ -18502,6 +18528,7 @@ class AppInstallUpgradeCard {
18502
18528
  }
18503
18529
  ngOnDestroy() {
18504
18530
  this._subscription.unsubscribe();
18531
+ this._subscription = null;
18505
18532
  }
18506
18533
  download(event, link) {
18507
18534
  return __awaiter(this, void 0, void 0, function* () {
@@ -18511,8 +18538,8 @@ class AppInstallUpgradeCard {
18511
18538
  }
18512
18539
  this.downloading = true;
18513
18540
  try {
18514
- console.info('[install-upgrade-card] User ask download of: ' + link.url);
18515
- const location = this.platform.download({
18541
+ console.info('[install-upgrade-card] User click to download file: ' + link.url);
18542
+ const location = yield this.platform.download({
18516
18543
  uri: link.url,
18517
18544
  title: link.name,
18518
18545
  filename: link.downloadFilename,
@@ -18535,11 +18562,9 @@ class AppInstallUpgradeCard {
18535
18562
  this.downloading = false;
18536
18563
  this.markForCheck();
18537
18564
  }
18538
- this.showToast({
18539
- message: 'INFO.DOWNLOAD_UPDATE_SUCCEED',
18540
- type: 'info',
18541
- showCloseButton: true
18542
- });
18565
+ if (!this._subscription)
18566
+ return; // Skip if component destroyed
18567
+ yield this.showDownloadCompleteDialog();
18543
18568
  });
18544
18569
  }
18545
18570
  tryOnline() {
@@ -18626,6 +18651,11 @@ class AppInstallUpgradeCard {
18626
18651
  let url = config.getProperty(CORE_CONFIG_OPTIONS.ANDROID_INSTALL_URL);
18627
18652
  if (isNilOrBlank(url))
18628
18653
  url = this.environment.defaultAndroidInstallUrl || null;
18654
+ // Resolve relative URL
18655
+ const peer = this.network.peer;
18656
+ if (peer && (url.startsWith('./') || url.startsWith('/'))) {
18657
+ url = Peer.path(peer, url);
18658
+ }
18629
18659
  const minVersion = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);
18630
18660
  // Compute App name
18631
18661
  const name = isNotNilOrBlank(url) && config.label || this.environment.defaultAppName || 'SUMARiS';
@@ -18684,11 +18714,33 @@ class AppInstallUpgradeCard {
18684
18714
  yield Toasts.show(this.toastController, this.translate, opts);
18685
18715
  });
18686
18716
  }
18717
+ showDownloadCompleteDialog() {
18718
+ return __awaiter(this, void 0, void 0, function* () {
18719
+ const translations = yield this.translate.get([
18720
+ 'INFO.ALERT_HEADER',
18721
+ 'INFO.DOWNLOAD_UPDATE_SUCCEED',
18722
+ 'COMMON.BTN_CLOSE'
18723
+ ]).toPromise();
18724
+ const alert = yield this.alertController.create({
18725
+ header: translations['INFO.ALERT_HEADER'],
18726
+ message: translations['INFO.DOWNLOAD_UPDATE_SUCCEED'],
18727
+ buttons: [
18728
+ {
18729
+ text: translations['COMMON.BTN_CLOSE'],
18730
+ role: 'cancel',
18731
+ cssClass: 'secondary'
18732
+ }
18733
+ ]
18734
+ });
18735
+ yield alert.present();
18736
+ yield alert.onDidDismiss();
18737
+ });
18738
+ }
18687
18739
  }
18688
18740
  AppInstallUpgradeCard.decorators = [
18689
18741
  { type: Component, args: [{
18690
18742
  selector: 'app-install-upgrade-card',
18691
- template: "\n\n<!-- Offline mode card-->\n<ion-card *ngIf=\"showOfflineWarning && (!loading && offline || waitingNetwork)\"\n color=\"accent\"\n class=\"main ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text class=\"ion-text-wrap\" *ngIf=\"!waitingNetwork; else waitingNetworkText\">\n <h4>\n <b *ngIf=\"isLogin; else notLogin\" [innerHTML]=\"'NETWORK.INFO.OFFLINE_OR_UNAUTHORIZED'| translate\"></b>\n <ng-template #notLogin>\n <b [innerHTML]=\"'NETWORK.INFO.OFFLINE'| translate\"></b>\n </ng-template>\n </h4>\n <h3>\n <small [innerHTML]=\"'NETWORK.INFO.OFFLINE_HELP'|translate\"></small>\n </h3>\n </ion-text>\n <ng-template #waitingNetworkText>\n <ion-text class=\"ion-text-wrap\" [innerHTML]=\"'NETWORK.INFO.RETRY_TO_CONNECT'| translate\"></ion-text>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\">\n\n <!-- Retry button -->\n <ion-button *ngIf=\"!waitingNetwork; else waitingSpinner\" color=\"tertiary\" class=\"ion-float-end\"\n (click)=\"tryOnline()\">\n <span translate>NETWORK.BTN_CHECK_ALIVE</span>\n </ion-button>\n\n <!-- Waiting spinner -->\n <ng-template #waitingSpinner>\n <ion-spinner *ngIf=\"waitingNetwork\" color=\"light\"></ion-spinner>\n </ng-template>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Upgrade links -->\n<ion-card *ngIf=\"showUpgradeWarning && !loading && !offline && updateLinks\"\n color=\"accent\"\n class=\"ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row *ngFor=\"let link of updateLinks; last as last\">\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h3>\n <span *ngIf=\"link.version\" [innerHTML]=\"'INFO.UPDATE_APP_TO_VERSION'| translate: link\"></span>\n <span *ngIf=\"!link.version\" [innerHTML]=\"'INFO.UPDATE_APP'| translate: link\"></span>\n </h3>\n <h4>\n <small *ngIf=\"last\" [innerHTML]=\"'INFO.UPDATE_APP_HELP'|translate\"></small>\n </h4>\n </ion-text>\n </ion-col>\n\n <ion-col size=\"auto\">\n <ng-container *ngTemplateOutlet=\"downloadButton; context: { $implicit: link }\"></ng-container>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Install links -->\n<ion-card *ngIf=\"showInstallButton && !loading && !offline && installLinks\"\n color=\"secondary\"\n class=\"ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row *ngFor=\"let link of installLinks; last as last\">\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h3 [innerHTML]=\"'INFO.DOWNLOAD_APP_TITLE'| translate: {name: link.name, platform: getPlatformName(link.platform) }\"></h3>\n <h4><small *ngIf=\"last\" [innerHTML]=\"'INFO.DOWNLOAD_APP_HELP'|translate\"></small></h4>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n <ng-container *ngTemplateOutlet=\"downloadButton; context: { $implicit: link }\"></ng-container>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Update offline feature card-->\n<ion-card *ngIf=\"showUpdateOfflineFeature && !loading && !offline\"\n color=\"accent\"\n class=\"main ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h4>\n <b [innerHTML]=\"'NETWORK.INFO.UPDATE_OFFLINE_MODE'| translate\"></b>\n </h4>\n <h3>\n <small [innerHTML]=\"'NETWORK.INFO.UPDATE_OFFLINE_MODE_HELP'|translate\"></small>\n </h3>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n\n <!-- Retry button -->\n <ion-button color=\"tertiary\" class=\"ion-float-end\"\n (click)=\"onUpdateOfflineModeClick.emit($event)\">\n <span translate>NETWORK.BTN_UPDATE</span>\n </ion-button>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Display a download button, depending on the link URL, and the device platform -->\n<ng-template #downloadButton let-link>\n\n <ng-container *ngIf=\"link.downloadFilename; else redirectButton\">\n\n <!-- Download using platform -->\n <ion-button *ngIf=\"platform.canDownload; else webDownloadButton\"\n (click)=\"download($event, asLink(link))\"\n [disabled]=\"downloading\"\n color=\"tertiary\" class=\"ion-float-end\">\n <ion-icon slot=\"start\" *ngIf=\"!downloading\" name=\"download\"></ion-icon>\n <ion-spinner slot=\"start\" class=\"ion-no-padding\" *ngIf=\"downloading\"></ion-spinner>\n <ion-label translate>COMMON.BTN_DOWNLOAD</ion-label>\n </ion-button>\n\n <!-- Web download button -->\n <ng-template #webDownloadButton>\n <ion-button [download]=\"link.downloadFilename\"\n [href]=\"link.url\"\n color=\"tertiary\" class=\"ion-float-end\" >\n <ion-label translate>COMMON.BTN_DOWNLOAD</ion-label>\n </ion-button>\n </ng-template>\n </ng-container>\n\n <!-- Web redirect button -->\n <ng-template #redirectButton>\n <ion-button [href]=\"link.url\" rel=\"external\" color=\"tertiary\" class=\"ion-float-end\" target=\"_blank\">\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n </ion-button>\n </ng-template>\n</ng-template>\n",
18743
+ template: "\n\n<!-- Offline mode card-->\n<ion-card *ngIf=\"showOfflineWarning && (!loading && offline || waitingNetwork)\"\n color=\"accent\"\n class=\"main ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text class=\"ion-text-wrap\" *ngIf=\"!waitingNetwork; else waitingNetworkText\">\n <h4>\n <b *ngIf=\"isLogin; else notLogin\" [innerHTML]=\"'NETWORK.INFO.OFFLINE_OR_UNAUTHORIZED'| translate\"></b>\n <ng-template #notLogin>\n <b [innerHTML]=\"'NETWORK.INFO.OFFLINE'| translate\"></b>\n </ng-template>\n </h4>\n <h3>\n <small [innerHTML]=\"'NETWORK.INFO.OFFLINE_HELP'|translate\"></small>\n </h3>\n </ion-text>\n <ng-template #waitingNetworkText>\n <ion-text class=\"ion-text-wrap\" [innerHTML]=\"'NETWORK.INFO.RETRY_TO_CONNECT'| translate\"></ion-text>\n </ng-template>\n </ion-col>\n <ion-col size=\"auto\">\n\n <!-- Retry button -->\n <ion-button *ngIf=\"!waitingNetwork; else waitingSpinner\" color=\"tertiary\" class=\"ion-float-end\"\n (click)=\"tryOnline()\">\n <span translate>NETWORK.BTN_CHECK_ALIVE</span>\n </ion-button>\n\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Upgrade links -->\n<ion-card *ngIf=\"showUpgradeWarning && !loading && !offline && updateLinks\"\n color=\"accent\"\n class=\"ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row *ngFor=\"let link of updateLinks; last as last\">\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h3>\n <span *ngIf=\"link.version\" [innerHTML]=\"'INFO.UPDATE_APP_TO_VERSION'| translate: link\"></span>\n <span *ngIf=\"!link.version\" [innerHTML]=\"'INFO.UPDATE_APP'| translate: link\"></span>\n </h3>\n <h4>\n <small *ngIf=\"last\" [innerHTML]=\"'INFO.UPDATE_APP_HELP'|translate\"></small>\n </h4>\n </ion-text>\n </ion-col>\n\n <ion-col size=\"auto\">\n <ng-container *ngTemplateOutlet=\"downloadButton; context: { $implicit: link }\"></ng-container>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Install links -->\n<ion-card *ngIf=\"showInstallButton && !loading && !offline && installLinks\"\n color=\"secondary\"\n class=\"ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row *ngFor=\"let link of installLinks; last as last\">\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h3 [innerHTML]=\"'INFO.DOWNLOAD_APP_TITLE'| translate: {name: link.name, platform: getPlatformName(link.platform) }\"></h3>\n <h4><small *ngIf=\"last\" [innerHTML]=\"'INFO.DOWNLOAD_APP_HELP'|translate\"></small></h4>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n <ng-container *ngTemplateOutlet=\"downloadButton; context: { $implicit: link }\"></ng-container>\n </ion-col>\n </ion-row>\n\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Update offline feature card-->\n<ion-card *ngIf=\"showUpdateOfflineFeature && !loading && !offline\"\n color=\"accent\"\n class=\"main ion-no-margin\"\n @slideUpDownAnimation>\n <ion-card-content class=\"ion-no-padding\">\n <ion-grid>\n <ion-row>\n <ion-col>\n <ion-text class=\"ion-text-wrap\">\n <h4>\n <b [innerHTML]=\"'NETWORK.INFO.UPDATE_OFFLINE_MODE'| translate\"></b>\n </h4>\n <h3>\n <small [innerHTML]=\"'NETWORK.INFO.UPDATE_OFFLINE_MODE_HELP'|translate\"></small>\n </h3>\n </ion-text>\n </ion-col>\n <ion-col size=\"auto\">\n\n <!-- Retry button -->\n <ion-button color=\"tertiary\" class=\"ion-float-end\"\n (click)=\"onUpdateOfflineModeClick.emit($event)\">\n <span translate>NETWORK.BTN_UPDATE</span>\n </ion-button>\n </ion-col>\n </ion-row>\n </ion-grid>\n\n </ion-card-content>\n</ion-card>\n\n<!-- Display a download button, depending on the link URL, and the device platform -->\n<ng-template #downloadButton let-link>\n\n <ng-container *ngIf=\"link.downloadFilename; else redirectButton\">\n\n <ng-container *ngIf=\"platform.canDownload; else webDownloadButton\">\n <!-- Download using platform -->\n <ion-button *ngIf=\"!downloading; else waitingSpinner\"\n (click)=\"download($event, asLink(link))\"\n [disabled]=\"downloading\"\n color=\"tertiary\" class=\"ion-float-end\">\n <ion-icon slot=\"start\" *ngIf=\"!downloading\" name=\"download\"></ion-icon>\n <ion-spinner slot=\"start\" class=\"ion-no-padding\" *ngIf=\"downloading\"></ion-spinner>\n <ion-label translate>COMMON.BTN_DOWNLOAD</ion-label>\n </ion-button>\n </ng-container>\n\n <!-- Web download button -->\n <ng-template #webDownloadButton>\n <ion-button [download]=\"link.downloadFilename\"\n [href]=\"link.url\"\n color=\"tertiary\" class=\"ion-float-end\" >\n <ion-label translate>COMMON.BTN_DOWNLOAD</ion-label>\n </ion-button>\n </ng-template>\n </ng-container>\n\n <!-- Web redirect button -->\n <ng-template #redirectButton>\n <ion-button [href]=\"link.url\" rel=\"external\" color=\"tertiary\" class=\"ion-float-end\" target=\"_blank\">\n <ion-label translate>COMMON.BTN_SHOW_MORE</ion-label>\n </ion-button>\n </ng-template>\n</ng-template>\n\n\n<!-- Waiting spinner -->\n<ng-template #waitingSpinner>\n <ion-spinner color=\"light\"></ion-spinner>\n</ng-template>\n",
18692
18744
  changeDetection: ChangeDetectionStrategy.OnPush,
18693
18745
  animations: [slideUpDownAnimation],
18694
18746
  styles: ["ion-text small{font-size:85%}"]
@@ -18698,6 +18750,7 @@ AppInstallUpgradeCard.ctorParameters = () => [
18698
18750
  { type: ModalController },
18699
18751
  { type: ConfigService },
18700
18752
  { type: ToastController },
18753
+ { type: AlertController },
18701
18754
  { type: TranslateService },
18702
18755
  { type: ChangeDetectorRef },
18703
18756
  { type: PlatformService },