@sumaris-net/ngx-components 0.25.2 → 0.25.6

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.
@@ -9212,6 +9212,24 @@
9212
9212
  path: noTrailingSlash(url.pathname)
9213
9213
  });
9214
9214
  };
9215
+ Peer.path = function (peer) {
9216
+ var _a;
9217
+ var paths = [];
9218
+ for (var _i = 1; _i < arguments.length; _i++) {
9219
+ paths[_i - 1] = arguments[_i];
9220
+ }
9221
+ if (!peer)
9222
+ throw new Error('Missing required argument \'peer\'!');
9223
+ // Remove starting slashes
9224
+ paths = (paths || []).map(function (path) {
9225
+ if (path.startsWith('./'))
9226
+ return path.substring(2);
9227
+ if (path.startsWith('/'))
9228
+ return path.substring(1);
9229
+ return path;
9230
+ }).filter(isNotNilOrBlank);
9231
+ return (_a = [noTrailingSlash(Peer_1.fromObject(peer).url)]).concat.apply(_a, __spread(paths)).join('/');
9232
+ };
9215
9233
  Peer.prototype.asObject = function (options) {
9216
9234
  return _super.prototype.asObject.call(this, options);
9217
9235
  };
@@ -15660,6 +15678,7 @@
15660
15678
  this.browser = browser;
15661
15679
  this.downloader = downloader;
15662
15680
  this._started = false;
15681
+ this._downloadingPromise = new Map();
15663
15682
  this._debug = !environment.production;
15664
15683
  if (this._debug)
15665
15684
  console.debug('[platform] Creating service');
@@ -15789,21 +15808,35 @@
15789
15808
  window.open(url, target, features, replace);
15790
15809
  }
15791
15810
  };
15811
+ PlatformService.prototype.getDownloadingPromise = function (uri) {
15812
+ return __awaiter(this, void 0, void 0, function () {
15813
+ return __generator(this, function (_a) {
15814
+ return [2 /*return*/, this._downloadingPromise.get(uri)];
15815
+ });
15816
+ });
15817
+ };
15792
15818
  PlatformService.prototype.download = function (request) {
15793
15819
  return __awaiter(this, void 0, void 0, function () {
15794
- var location, err_1;
15820
+ var promise, location, err_1;
15795
15821
  return __generator(this, function (_a) {
15796
15822
  switch (_a.label) {
15797
15823
  case 0:
15798
15824
  if (!request || !request.uri)
15799
15825
  throw new Error('Missing argument \'request\' or \'request.uri\'');
15800
- if (!(this._android && this.downloader)) return [3 /*break*/, 5];
15801
- request = Object.assign({ visibleInDownloadsUi: true, notificationVisibility: ngx$6.NotificationVisibility.VisibleNotifyCompleted }, request);
15826
+ if (!(this._android && this.downloader)) return [3 /*break*/, 6];
15827
+ promise = this._downloadingPromise.get(request.uri);
15828
+ if (promise)
15829
+ return [2 /*return*/, promise];
15830
+ request = Object.assign({ visibleInDownloadsUi: true, notificationVisibility: ngx$6.NotificationVisibility.VisibleNotifyCompleted, title: request.title || request.filename }, request);
15802
15831
  _a.label = 1;
15803
15832
  case 1:
15804
- _a.trys.push([1, 3, , 4]);
15833
+ _a.trys.push([1, 3, 4, 5]);
15805
15834
  console.debug('[platform] Downloading, using request: ' + JSON.stringify(request));
15806
- return [4 /*yield*/, this.downloader.download(request)];
15835
+ // Start download
15836
+ promise = this.downloader.download(request);
15837
+ // Remember this request uri
15838
+ this._downloadingPromise.set(request.uri, promise);
15839
+ return [4 /*yield*/, promise];
15807
15840
  case 2:
15808
15841
  location = _a.sent();
15809
15842
  console.info('[platform] File successfully downloaded at:' + location);
@@ -15812,12 +15845,16 @@
15812
15845
  err_1 = _a.sent();
15813
15846
  console.error('[platform] Unable to download: ' + (err_1 && err_1.message || err_1));
15814
15847
  throw err_1;
15815
- case 4: return [3 /*break*/, 6];
15816
- case 5:
15817
- console.warn('[platform] Cannot use Cordova downloader: using browser open()');
15848
+ case 4:
15849
+ // Forget the request
15850
+ this._downloadingPromise.delete(request.uri);
15851
+ return [7 /*endfinally*/];
15852
+ case 5: return [3 /*break*/, 7];
15853
+ case 6:
15854
+ console.warn('[platform] Cannot use Android downloader: using browser open()');
15818
15855
  this.open(request.uri, '_system', 'location=no', true);
15819
15856
  return [2 /*return*/, undefined];
15820
- case 6: return [2 /*return*/];
15857
+ case 7: return [2 /*return*/];
15821
15858
  }
15822
15859
  });
15823
15860
  });
@@ -21279,10 +21316,11 @@
21279
21316
  ANDROID_APK: 'application/vnd.android.package-archive'
21280
21317
  });
21281
21318
  var AppInstallUpgradeCard = /** @class */ (function () {
21282
- function AppInstallUpgradeCard(modalCtrl, configService, toastController, translate, cd, platform, network, environment) {
21319
+ function AppInstallUpgradeCard(modalCtrl, configService, toastController, alertController, translate, cd, platform, network, environment) {
21283
21320
  this.modalCtrl = modalCtrl;
21284
21321
  this.configService = configService;
21285
21322
  this.toastController = toastController;
21323
+ this.alertController = alertController;
21286
21324
  this.translate = translate;
21287
21325
  this.cd = cd;
21288
21326
  this.platform = platform;
@@ -21322,7 +21360,7 @@
21322
21360
  this.offline = this.network.offline;
21323
21361
  // Listen pod config
21324
21362
  this._subscription.add(this.configService.config
21325
- .pipe(operators.debounceTime(1000))
21363
+ .pipe(operators.debounceTime(1000), operators.filter(function () { return _this.network.online; }))
21326
21364
  .subscribe(function (config) { return _this.checkNeedInstallOrUpdate(config); }));
21327
21365
  // Listen network changes
21328
21366
  this._subscription.add(this.network.onNetworkStatusChanges
@@ -21343,47 +21381,24 @@
21343
21381
  };
21344
21382
  AppInstallUpgradeCard.prototype.ngOnDestroy = function () {
21345
21383
  this._subscription.unsubscribe();
21384
+ this._subscription = null;
21385
+ this.onUpdateOfflineModeClick.complete();
21386
+ this.installLinks = null;
21387
+ this.upgradeLinks = null;
21346
21388
  };
21347
21389
  AppInstallUpgradeCard.prototype.download = function (event, link) {
21348
21390
  return __awaiter(this, void 0, void 0, function () {
21349
- var location;
21350
21391
  return __generator(this, function (_a) {
21351
21392
  if (!link || !link.url) {
21352
21393
  console.error('[install-upgrade-card] Missing required argument \'link.url\'');
21353
21394
  return [2 /*return*/]; // Skip
21354
21395
  }
21355
- this.downloading = true;
21356
- try {
21357
- console.info('[install-upgrade-card] User ask download of: ' + link.url);
21358
- location = this.platform.download({
21396
+ return [2 /*return*/, this.listenDownloadPromise(link.url, this.platform.download({
21359
21397
  uri: link.url,
21360
- title: link.name,
21361
- filename: link.downloadFilename,
21398
+ title: link.title,
21399
+ filename: link.filename,
21362
21400
  mimeType: link.mimeType
21363
- });
21364
- console.info('[install-upgrade-card] File downloaded at: ' + location);
21365
- }
21366
- // Failed: display a toast
21367
- catch (err) {
21368
- console.error('[install-upgrade] Download failed: ' + (err && err.message || err));
21369
- this.showToast({
21370
- message: 'ERROR.DOWNLOAD_FAILED',
21371
- messageParams: { error: err },
21372
- type: 'error',
21373
- showCloseButton: true
21374
- });
21375
- return [2 /*return*/]; // Stop here
21376
- }
21377
- finally {
21378
- this.downloading = false;
21379
- this.markForCheck();
21380
- }
21381
- this.showToast({
21382
- message: 'INFO.DOWNLOAD_UPDATE_SUCCEED',
21383
- type: 'info',
21384
- showCloseButton: true
21385
- });
21386
- return [2 /*return*/];
21401
+ }))];
21387
21402
  });
21388
21403
  });
21389
21404
  };
@@ -21430,7 +21445,8 @@
21430
21445
  /* -- private method -- */
21431
21446
  AppInstallUpgradeCard.prototype.checkNeedInstallOrUpdate = function (config) {
21432
21447
  return __awaiter(this, void 0, void 0, function () {
21433
- var installLinks;
21448
+ var links;
21449
+ var _this = this;
21434
21450
  return __generator(this, function (_a) {
21435
21451
  switch (_a.label) {
21436
21452
  case 0:
@@ -21438,12 +21454,12 @@
21438
21454
  _a.label = 1;
21439
21455
  case 1:
21440
21456
  _a.trys.push([1, , 3, 4]);
21441
- installLinks = this.getAllInstallLinks(config);
21457
+ links = this.getLinks(config);
21442
21458
  // Check for upgrade
21443
- this.updateLinks = this.getCompatibleUpgradeLinks(installLinks, config);
21459
+ this.upgradeLinks = this.getCompatibleUpgradeLinks(links, config);
21444
21460
  // Check for install links (if no upgrade need)
21445
- this.installLinks = !this.updateLinks && this.getCompatibleInstallLinks(installLinks);
21446
- return [4 /*yield*/, sleep(500)];
21461
+ this.installLinks = !this.upgradeLinks && this.getCompatibleInstallLinks(links);
21462
+ return [4 /*yield*/, sleep(1000)];
21447
21463
  case 2:
21448
21464
  _a.sent(); // Add a delay, for animation
21449
21465
  return [3 /*break*/, 4];
@@ -21451,7 +21467,14 @@
21451
21467
  this.loading = false;
21452
21468
  this.markForCheck();
21453
21469
  return [7 /*endfinally*/];
21454
- case 4: return [2 /*return*/];
21470
+ case 4:
21471
+ // Listening downloading promise, if exists
21472
+ (this.upgradeLinks || []).forEach(function (link) {
21473
+ var promise = _this.platform.getDownloadingPromise(link.url);
21474
+ if (promise)
21475
+ _this.listenDownloadPromise(link.url, promise);
21476
+ });
21477
+ return [2 /*return*/];
21455
21478
  }
21456
21479
  });
21457
21480
  });
@@ -21485,7 +21508,7 @@
21485
21508
  });
21486
21509
  return isNotEmptyArray(upgradeLinks) ? upgradeLinks : undefined;
21487
21510
  };
21488
- AppInstallUpgradeCard.prototype.getAllInstallLinks = function (config) {
21511
+ AppInstallUpgradeCard.prototype.getLinks = function (config) {
21489
21512
  var result = [];
21490
21513
  // Android
21491
21514
  {
@@ -21493,16 +21516,20 @@
21493
21516
  var url = config.getProperty(CORE_CONFIG_OPTIONS.ANDROID_INSTALL_URL);
21494
21517
  if (isNilOrBlank(url))
21495
21518
  url = this.environment.defaultAndroidInstallUrl || null;
21519
+ // Resolve relative URL
21520
+ var peer = this.network.peer;
21521
+ if (peer && (url.startsWith('./') || url.startsWith('/'))) {
21522
+ url = exports.Peer.path(peer, url);
21523
+ }
21496
21524
  var minVersion = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);
21497
21525
  // Compute App name
21498
21526
  var name = isNotNilOrBlank(url) && config.label || this.environment.defaultAppName || 'SUMARiS';
21499
21527
  if (url) {
21500
- var downloadFilename = void 0;
21501
- var version = void 0;
21528
+ var title = void 0;
21502
21529
  var mimeType = void 0;
21503
21530
  // Get file name
21504
21531
  var filename = this.getFilename(url);
21505
- version = minVersion || 'latest';
21532
+ var version = minVersion || 'latest';
21506
21533
  // OK, this is a downloadable APK file (e.g. NOT a link to a playstore)
21507
21534
  if (filename === null || filename === void 0 ? void 0 : filename.endsWith('.apk')) {
21508
21535
  // Define mime type
@@ -21511,18 +21538,18 @@
21511
21538
  var versionMatches = /-v([1-9][0-9]*\.[0-9]+\.(:?(:?alpha|beta|rc)?[0-9]*))/i.exec(filename);
21512
21539
  version = versionMatches && versionMatches[1] || version;
21513
21540
  // Compute a new file name, with the version
21514
- if (isNotNilOrBlank(name)) {
21515
- downloadFilename = (name + "-v" + version + ".apk").toLowerCase();
21541
+ if (isNotNilOrBlank(name) && version !== 'latest') {
21542
+ filename = (name + "-v" + version + ".apk").toLowerCase();
21543
+ title = name + " v" + version;
21516
21544
  }
21517
21545
  else {
21518
- downloadFilename = filename;
21519
21546
  // Replace 'latest' with the app version, if present
21520
- if (downloadFilename.indexOf('latest')) {
21521
- downloadFilename = downloadFilename.replace('latest', version);
21547
+ if (filename.indexOf('latest')) {
21548
+ filename = filename.replace('latest', version);
21522
21549
  }
21523
21550
  }
21524
21551
  }
21525
- result.push({ name: name, url: url, platform: 'android', version: version, downloadFilename: downloadFilename, mimeType: mimeType });
21552
+ result.push({ name: name, url: url, platform: 'android', version: version, filename: filename, title: title, mimeType: mimeType });
21526
21553
  }
21527
21554
  }
21528
21555
  // iOS - TODO
@@ -21558,12 +21585,94 @@
21558
21585
  });
21559
21586
  });
21560
21587
  };
21588
+ AppInstallUpgradeCard.prototype.listenDownloadPromise = function (url, promise) {
21589
+ return __awaiter(this, void 0, void 0, function () {
21590
+ var location, err_1;
21591
+ return __generator(this, function (_a) {
21592
+ switch (_a.label) {
21593
+ case 0:
21594
+ if (!url || !promise)
21595
+ return [2 /*return*/]; // Skip
21596
+ _a.label = 1;
21597
+ case 1:
21598
+ _a.trys.push([1, 3, 4, 5]);
21599
+ // Mark as downloading
21600
+ if (!this.downloading) {
21601
+ console.info("[install-upgrade-card] Platform is downloading '" + url + "' ...");
21602
+ this.downloading = true;
21603
+ this.markForCheck();
21604
+ }
21605
+ return [4 /*yield*/, promise];
21606
+ case 2:
21607
+ location = _a.sent();
21608
+ console.info('[install-upgrade-card] File downloaded at: ' + location);
21609
+ return [3 /*break*/, 5];
21610
+ case 3:
21611
+ err_1 = _a.sent();
21612
+ console.error('[install-upgrade] Download failed: ' + (err_1 && err_1.message || err_1));
21613
+ return [2 /*return*/, this.showDownloadFailedToast(err_1)];
21614
+ case 4:
21615
+ this.downloading = false;
21616
+ this.markForCheck();
21617
+ return [7 /*endfinally*/];
21618
+ case 5: return [2 /*return*/, this.showDownloadCompleteDialog()];
21619
+ }
21620
+ });
21621
+ });
21622
+ };
21623
+ AppInstallUpgradeCard.prototype.showDownloadFailedToast = function (err) {
21624
+ return this.showToast({
21625
+ message: 'ERROR.DOWNLOAD_FAILED',
21626
+ messageParams: { error: err },
21627
+ type: 'error',
21628
+ showCloseButton: true
21629
+ });
21630
+ };
21631
+ AppInstallUpgradeCard.prototype.showDownloadCompleteDialog = function () {
21632
+ return __awaiter(this, void 0, void 0, function () {
21633
+ var translations, alert;
21634
+ return __generator(this, function (_a) {
21635
+ switch (_a.label) {
21636
+ case 0:
21637
+ if (!this._subscription)
21638
+ return [2 /*return*/]; // Skip if component has been destroyed
21639
+ return [4 /*yield*/, this.translate.get([
21640
+ 'INFO.ALERT_HEADER',
21641
+ 'INFO.DOWNLOAD_UPDATE_SUCCEED',
21642
+ 'COMMON.BTN_CLOSE'
21643
+ ]).toPromise()];
21644
+ case 1:
21645
+ translations = _a.sent();
21646
+ return [4 /*yield*/, this.alertController.create({
21647
+ header: translations['INFO.ALERT_HEADER'],
21648
+ message: translations['INFO.DOWNLOAD_UPDATE_SUCCEED'],
21649
+ buttons: [
21650
+ {
21651
+ text: translations['COMMON.BTN_CLOSE'],
21652
+ role: 'cancel',
21653
+ cssClass: 'secondary'
21654
+ }
21655
+ ]
21656
+ })];
21657
+ case 2:
21658
+ alert = _a.sent();
21659
+ return [4 /*yield*/, alert.present()];
21660
+ case 3:
21661
+ _a.sent();
21662
+ return [4 /*yield*/, alert.onDidDismiss()];
21663
+ case 4:
21664
+ _a.sent();
21665
+ return [2 /*return*/];
21666
+ }
21667
+ });
21668
+ });
21669
+ };
21561
21670
  return AppInstallUpgradeCard;
21562
21671
  }());
21563
21672
  AppInstallUpgradeCard.decorators = [
21564
21673
  { type: i0.Component, args: [{
21565
21674
  selector: 'app-install-upgrade-card',
21566
- 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",
21675
+ 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 && upgradeLinks\"\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 upgradeLinks; 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 (click)=\"download($event, asLink(link))\"\n [disabled]=\"link.downloading\"\n color=\"tertiary\" class=\"ion-float-end\">\n <ion-icon slot=\"start\" *ngIf=\"!link.downloading\" name=\"download\"></ion-icon>\n <ion-spinner slot=\"start\" class=\"ion-no-padding\" *ngIf=\"link.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",
21567
21676
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
21568
21677
  animations: [slideUpDownAnimation],
21569
21678
  styles: ["ion-text small{font-size:85%}"]
@@ -21573,6 +21682,7 @@
21573
21682
  { type: i1$5.ModalController },
21574
21683
  { type: ConfigService },
21575
21684
  { type: i1$5.ToastController },
21685
+ { type: i1$5.AlertController },
21576
21686
  { type: i1$2.TranslateService },
21577
21687
  { type: i0.ChangeDetectorRef },
21578
21688
  { type: PlatformService },