@sumaris-net/ngx-components 0.25.0 → 0.25.4

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.
@@ -7816,6 +7816,13 @@
7816
7816
  enumerable: false,
7817
7817
  configurable: true
7818
7818
  });
7819
+ Object.defineProperty(StartableService.prototype, "starting", {
7820
+ get: function () {
7821
+ return !!this._startPromise;
7822
+ },
7823
+ enumerable: false,
7824
+ configurable: true
7825
+ });
7819
7826
  StartableService.prototype.ready = function () {
7820
7827
  if (this._started)
7821
7828
  return Promise.resolve(this._data);
@@ -9205,6 +9212,24 @@
9205
9212
  path: noTrailingSlash(url.pathname)
9206
9213
  });
9207
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
+ };
9208
9233
  Peer.prototype.asObject = function (options) {
9209
9234
  return _super.prototype.asObject.call(this, options);
9210
9235
  };
@@ -10939,7 +10964,7 @@
10939
10964
  var _this = this;
10940
10965
  this._listeners[name] = this._listeners[name] || [];
10941
10966
  this._listeners[name].push(callback);
10942
- // When unsubcribe, remove from the listener
10967
+ // When unsubscribe, remove from the listener
10943
10968
  return new rxjs.Subscription(function () {
10944
10969
  var index = _this._listeners[name].indexOf(callback);
10945
10970
  if (index !== -1) {
@@ -12705,7 +12730,7 @@
12705
12730
  var GraphqlService = /** @class */ (function (_super) {
12706
12731
  __extends(GraphqlService, _super);
12707
12732
  function GraphqlService(platform, apollo, httpLink, network, storage, cryptoService, environment, typePolicies) {
12708
- var _this = _super.call(this, network) || this;
12733
+ var _this = _super.call(this, platform) || this;
12709
12734
  _this.platform = platform;
12710
12735
  _this.apollo = apollo;
12711
12736
  _this.httpLink = httpLink;
@@ -12720,22 +12745,6 @@
12720
12745
  _this.customErrors = {};
12721
12746
  _this._debug = !environment.production;
12722
12747
  _this._defaultFetchPolicy = environment.apolloFetchPolicy;
12723
- // Restart if network restart
12724
- _this.network.on('start', function () { return _this.restart(); });
12725
- // Clear cache
12726
- _this.network.on('resetCache', function () { return __awaiter(_this, void 0, void 0, function () {
12727
- return __generator(this, function (_a) {
12728
- switch (_a.label) {
12729
- case 0: return [4 /*yield*/, this.ready()];
12730
- case 1:
12731
- _a.sent();
12732
- return [4 /*yield*/, this.clearCache()];
12733
- case 2:
12734
- _a.sent();
12735
- return [2 /*return*/];
12736
- }
12737
- });
12738
- }); });
12739
12748
  // Listen network status
12740
12749
  _this._networkStatusChanged$ = network.onNetworkStatusChanges
12741
12750
  .pipe(operators.filter(isNotNil), operators.distinctUntilChanged());
@@ -13196,12 +13205,14 @@
13196
13205
  return __generator(this, function (_a) {
13197
13206
  switch (_a.label) {
13198
13207
  case 0:
13199
- client = (client || this.apollo.client);
13208
+ client = (client || this.client);
13200
13209
  if (!client) return [3 /*break*/, 2];
13201
- now = this._debug && Date.now();
13202
13210
  console.info('[graphql] Clearing Apollo client\'s cache... ');
13211
+ now = this._debug && Date.now();
13212
+ // Clearing the cache
13203
13213
  return [4 /*yield*/, client.cache.reset()];
13204
13214
  case 1:
13215
+ // Clearing the cache
13205
13216
  _a.sent();
13206
13217
  if (this._debug)
13207
13218
  console.debug("[graphql] Apollo client's cache cleared, in " + (Date.now() - now) + "ms");
@@ -13221,7 +13232,9 @@
13221
13232
  var _this = this;
13222
13233
  return __generator(this, function (_a) {
13223
13234
  switch (_a.label) {
13224
- case 0:
13235
+ case 0: return [4 /*yield*/, this.network.ready()];
13236
+ case 1:
13237
+ _a.sent();
13225
13238
  console.info('[graphql] Starting graphql...');
13226
13239
  mobile = this.platform.is('mobile') || this.platform.is('mobileweb');
13227
13240
  enableTrackMutationQueries = !mobile;
@@ -13241,7 +13254,7 @@
13241
13254
  }, webSocketImpl: AppWebSocket, uri: wsUri });
13242
13255
  storage = new apollo3CachePersist.IonicStorageWrapper(this.storage);
13243
13256
  client = this.apollo.client;
13244
- if (!!client) return [3 /*break*/, 3];
13257
+ if (!!client) return [3 /*break*/, 4];
13245
13258
  console.debug('[apollo] Creating GraphQL client...');
13246
13259
  wsLink = new ws.WebSocketLink(this.wsParams);
13247
13260
  retryLink = new retry.RetryLink();
@@ -13267,7 +13280,7 @@
13267
13280
  cache = new core.InMemoryCache({
13268
13281
  typePolicies: this.typePolicies
13269
13282
  });
13270
- if (!this.environment.persistCache) return [3 /*break*/, 2];
13283
+ if (!this.environment.persistCache) return [3 /*break*/, 3];
13271
13284
  console.debug('[graphql] Starting persistence cache...');
13272
13285
  return [4 /*yield*/, apollo3CachePersist.persistCache({
13273
13286
  cache: cache,
@@ -13276,10 +13289,10 @@
13276
13289
  debounce: 1000,
13277
13290
  debug: true
13278
13291
  })];
13279
- case 1:
13280
- _a.sent();
13281
- _a.label = 2;
13282
13292
  case 2:
13293
+ _a.sent();
13294
+ _a.label = 3;
13295
+ case 3:
13283
13296
  mutationLinks = void 0;
13284
13297
  // Add queue to store tracked queries, when offline
13285
13298
  if (enableTrackMutationQueries) {
@@ -13339,25 +13352,29 @@
13339
13352
  connectToDevTools: !this.environment.production
13340
13353
  });
13341
13354
  this.apollo.client = client;
13342
- _a.label = 3;
13343
- case 3:
13344
- if (!(enableTrackMutationQueries && this.environment.persistCache)) return [3 /*break*/, 7];
13345
13355
  _a.label = 4;
13346
13356
  case 4:
13347
- _a.trys.push([4, 6, , 7]);
13357
+ if (!(enableTrackMutationQueries && this.environment.persistCache)) return [3 /*break*/, 8];
13358
+ _a.label = 5;
13359
+ case 5:
13360
+ _a.trys.push([5, 7, , 8]);
13348
13361
  return [4 /*yield*/, restoreTrackedQueries({
13349
13362
  apolloClient: client,
13350
13363
  storage: storage,
13351
13364
  debug: true
13352
13365
  })];
13353
- case 5:
13354
- _a.sent();
13355
- return [3 /*break*/, 7];
13356
13366
  case 6:
13367
+ _a.sent();
13368
+ return [3 /*break*/, 8];
13369
+ case 7:
13357
13370
  err_2 = _a.sent();
13358
13371
  console.error('[graphql] Failed to restore tracked queries from storage: ' + (err_2 && err_2.message || err_2), err_2);
13359
- return [3 /*break*/, 7];
13360
- case 7:
13372
+ return [3 /*break*/, 8];
13373
+ case 8:
13374
+ // Listen for network restart
13375
+ this._subscription.add(this.network.on('start', function () { return _this.restart(); }));
13376
+ // Listen for clear cache request, from network
13377
+ this._subscription.add(this.network.on('resetCache', function () { return _this.clearCache(); }));
13361
13378
  console.info('[graphql] Starting graphql [OK]');
13362
13379
  return [2 /*return*/, client];
13363
13380
  }
@@ -15661,6 +15678,7 @@
15661
15678
  this.browser = browser;
15662
15679
  this.downloader = downloader;
15663
15680
  this._started = false;
15681
+ this._downloadingPromise = new Map();
15664
15682
  this._debug = !environment.production;
15665
15683
  if (this._debug)
15666
15684
  console.debug('[platform] Creating service');
@@ -15693,6 +15711,13 @@
15693
15711
  PlatformService.prototype.isAndroidCordova = function () {
15694
15712
  return this._android && this._cordova;
15695
15713
  };
15714
+ Object.defineProperty(PlatformService.prototype, "canDownload", {
15715
+ get: function () {
15716
+ return this._android && !!this.downloader;
15717
+ },
15718
+ enumerable: false,
15719
+ configurable: true
15720
+ });
15696
15721
  PlatformService.prototype.width = function () {
15697
15722
  return this.platform.width();
15698
15723
  };
@@ -15735,7 +15760,7 @@
15735
15760
  .then(function () {
15736
15761
  _this._started = true;
15737
15762
  _this._startPromise = undefined;
15738
- console.info("[platform] Starting platform [OK] {mobile: " + _this._mobile + ", touchUi: " + _this.touchUi + ", downloader: " + !!_this.downloader + " in " + (Date.now() - now) + "ms");
15763
+ console.info("[platform] Starting platform [OK] {mobile: " + _this._mobile + ", touchUi: " + _this.touchUi + ", canDownload: " + _this.canDownload + "} in " + (Date.now() - now) + "ms");
15739
15764
  // Update cache configuration when network changed
15740
15765
  _this.networkService.onNetworkStatusChanges.subscribe(function (type) { return _this.configureCache(type !== 'none'); });
15741
15766
  // Update authentication type
@@ -15783,35 +15808,53 @@
15783
15808
  window.open(url, target, features, replace);
15784
15809
  }
15785
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
+ };
15786
15818
  PlatformService.prototype.download = function (request) {
15787
15819
  return __awaiter(this, void 0, void 0, function () {
15788
- var downloader, location, err_1;
15820
+ var promise, location, err_1;
15789
15821
  return __generator(this, function (_a) {
15790
15822
  switch (_a.label) {
15791
15823
  case 0:
15792
15824
  if (!request || !request.uri)
15793
15825
  throw new Error('Missing argument \'request\' or \'request.uri\'');
15794
- downloader = this.downloader || window.plugins.Downloader;
15795
- if (!(downloader && this._android && this._cordova)) return [3 /*break*/, 5];
15796
- request = Object.assign(Object.assign({ visibleInDownloadsUi: true, notificationVisibility: ngx$6.NotificationVisibility.VisibleNotifyCompleted, title: request.filename || '' }, request), { destinationInExternalFilesDir: Object.assign({ dirType: 'Downloads', subPath: request.filename || request.title || '' }, request.destinationInExternalFilesDir) });
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);
15797
15831
  _a.label = 1;
15798
15832
  case 1:
15799
- _a.trys.push([1, 3, , 4]);
15800
- return [4 /*yield*/, downloader.download(request)];
15833
+ _a.trys.push([1, 3, 4, 5]);
15834
+ console.debug('[platform] Downloading, using request: ' + JSON.stringify(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];
15801
15840
  case 2:
15802
15841
  location = _a.sent();
15803
15842
  console.info('[platform] File successfully downloaded at:' + location);
15804
15843
  return [2 /*return*/, location];
15805
15844
  case 3:
15806
15845
  err_1 = _a.sent();
15807
- console.error('[platform] Error while downloading: ' + (err_1 && err_1.message || err_1), err_1);
15846
+ console.error('[platform] Unable to download: ' + (err_1 && err_1.message || err_1));
15808
15847
  throw err_1;
15809
- case 4: return [3 /*break*/, 6];
15810
- case 5:
15811
- 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()');
15812
15855
  this.open(request.uri, '_system', 'location=no', true);
15813
15856
  return [2 /*return*/, undefined];
15814
- case 6: return [2 /*return*/];
15857
+ case 7: return [2 /*return*/];
15815
15858
  }
15816
15859
  });
15817
15860
  });
@@ -15928,8 +15971,8 @@
15928
15971
  case 1:
15929
15972
  keys = _a.sent();
15930
15973
  if (!isEmptyArray(keys)) return [3 /*break*/, 3];
15931
- // Drop the old instance
15932
- console.info("[platform] Drop old storage {name: '" + forage.config().name + "', driver: '" + oldForage.driver() + "'}");
15974
+ // Drop the old instance (not need anymore)
15975
+ console.debug("[platform] Old storage is empty: dropping unused instance {name: '" + forage.config().name + "', driver: '" + oldForage.driver() + "'}");
15933
15976
  return [4 /*yield*/, oldForage.dropInstance()];
15934
15977
  case 2:
15935
15978
  _a.sent();
@@ -21273,11 +21316,14 @@
21273
21316
  ANDROID_APK: 'application/vnd.android.package-archive'
21274
21317
  });
21275
21318
  var AppInstallUpgradeCard = /** @class */ (function () {
21276
- function AppInstallUpgradeCard(modalCtrl, configService, platform, cd, network, environment) {
21319
+ function AppInstallUpgradeCard(modalCtrl, configService, toastController, alertController, translate, cd, platform, network, environment) {
21277
21320
  this.modalCtrl = modalCtrl;
21278
21321
  this.configService = configService;
21279
- this.platform = platform;
21322
+ this.toastController = toastController;
21323
+ this.alertController = alertController;
21324
+ this.translate = translate;
21280
21325
  this.cd = cd;
21326
+ this.platform = platform;
21281
21327
  this.network = network;
21282
21328
  this.environment = environment;
21283
21329
  this._subscription = new rxjs.Subscription();
@@ -21288,7 +21334,6 @@
21288
21334
  this.showOfflineWarning = true;
21289
21335
  this.showInstallButton = false;
21290
21336
  this.onUpdateOfflineModeClick = new i0.EventEmitter();
21291
- this.isAndroidCordova = platform.isAndroidCordova();
21292
21337
  }
21293
21338
  Object.defineProperty(AppInstallUpgradeCard.prototype, "showUpdateOfflineFeature", {
21294
21339
  get: function () {
@@ -21314,18 +21359,8 @@
21314
21359
  this.offline = this.network.offline;
21315
21360
  // Listen pod config
21316
21361
  this._subscription.add(this.configService.config
21317
- .subscribe(function (config) {
21318
- console.info('[install] Checking if upgrade or install is need...');
21319
- var installLinks = _this.getAllInstallLinks(config);
21320
- // Check for upgrade
21321
- _this.updateLinks = _this.getCompatibleUpgradeLinks(installLinks, config);
21322
- // Check for install links (if no upgrade need)
21323
- _this.installLinks = !_this.updateLinks && _this.getCompatibleInstallLinks(installLinks);
21324
- setTimeout(function () {
21325
- _this.loading = false;
21326
- _this.markForCheck();
21327
- }, 2000); // Add a delay, for animation
21328
- }));
21362
+ .pipe(operators.debounceTime(1000))
21363
+ .subscribe(function (config) { return _this.checkNeedInstallOrUpdate(config); }));
21329
21364
  // Listen network changes
21330
21365
  this._subscription.add(this.network.onNetworkStatusChanges
21331
21366
  .pipe(
@@ -21333,8 +21368,10 @@
21333
21368
  //tap(() => this.waitingNetwork = false),
21334
21369
  operators.map(function (connectionType) { return connectionType === 'none'; }), operators.distinctUntilChanged())
21335
21370
  .subscribe(function (offline) {
21336
- _this.offline = offline;
21337
- _this.markForCheck();
21371
+ if (_this.offline !== offline) {
21372
+ _this.offline = offline;
21373
+ _this.markForCheck();
21374
+ }
21338
21375
  }));
21339
21376
  return [2 /*return*/];
21340
21377
  }
@@ -21343,29 +21380,54 @@
21343
21380
  };
21344
21381
  AppInstallUpgradeCard.prototype.ngOnDestroy = function () {
21345
21382
  this._subscription.unsubscribe();
21383
+ this._subscription = null;
21384
+ this.onUpdateOfflineModeClick.complete();
21385
+ this.installLinks = null;
21386
+ this.upgradeLinks = null;
21346
21387
  };
21347
- AppInstallUpgradeCard.prototype.downloadLink = function (event, link) {
21348
- if (!link || !link.url)
21349
- return; // Skip
21350
- console.info("[install-upgrade-card] Downloading '" + link.url + "' ...");
21351
- this.platform.download({
21352
- uri: link.url,
21353
- filename: link.downloadFilename,
21354
- mimeType: link.mimeType
21388
+ AppInstallUpgradeCard.prototype.download = function (event, link) {
21389
+ return __awaiter(this, void 0, void 0, function () {
21390
+ var job;
21391
+ return __generator(this, function (_a) {
21392
+ if (!link || !link.url) {
21393
+ console.error('[install-upgrade-card] Missing required argument \'link.url\'');
21394
+ return [2 /*return*/]; // Skip
21395
+ }
21396
+ job = this.platform.download({
21397
+ uri: link.url,
21398
+ title: link.title,
21399
+ filename: link.filename,
21400
+ mimeType: link.mimeType
21401
+ });
21402
+ return [2 /*return*/, this.listenDownloadPromise(link, job)];
21403
+ });
21355
21404
  });
21356
21405
  };
21357
21406
  AppInstallUpgradeCard.prototype.tryOnline = function () {
21358
- var _this = this;
21359
- this.waitingNetwork = true;
21360
- this.markForCheck();
21361
- this.network.tryOnline({
21362
- showLoadingToast: false,
21363
- showOnlineToast: true,
21364
- showOfflineToast: false
21365
- })
21366
- .then(function () {
21367
- _this.waitingNetwork = false;
21368
- _this.markForCheck();
21407
+ return __awaiter(this, void 0, void 0, function () {
21408
+ return __generator(this, function (_a) {
21409
+ switch (_a.label) {
21410
+ case 0:
21411
+ this.waitingNetwork = true;
21412
+ this.markForCheck();
21413
+ _a.label = 1;
21414
+ case 1:
21415
+ _a.trys.push([1, , 3, 4]);
21416
+ return [4 /*yield*/, this.network.tryOnline({
21417
+ showLoadingToast: false,
21418
+ showOnlineToast: true,
21419
+ showOfflineToast: false
21420
+ })];
21421
+ case 2:
21422
+ _a.sent();
21423
+ return [3 /*break*/, 4];
21424
+ case 3:
21425
+ this.waitingNetwork = false;
21426
+ this.markForCheck();
21427
+ return [7 /*endfinally*/];
21428
+ case 4: return [2 /*return*/];
21429
+ }
21430
+ });
21369
21431
  });
21370
21432
  };
21371
21433
  AppInstallUpgradeCard.prototype.getPlatformName = function (platform) {
@@ -21382,6 +21444,34 @@
21382
21444
  return value;
21383
21445
  };
21384
21446
  /* -- private method -- */
21447
+ AppInstallUpgradeCard.prototype.checkNeedInstallOrUpdate = function (config) {
21448
+ return __awaiter(this, void 0, void 0, function () {
21449
+ var links;
21450
+ return __generator(this, function (_a) {
21451
+ switch (_a.label) {
21452
+ case 0:
21453
+ console.info('[install] Check if need to install or upgrade...');
21454
+ _a.label = 1;
21455
+ case 1:
21456
+ _a.trys.push([1, , 3, 4]);
21457
+ links = this.getLinks(config);
21458
+ // Check for upgrade
21459
+ this.upgradeLinks = this.getCompatibleUpgradeLinks(links, config);
21460
+ // Check for install links (if no upgrade need)
21461
+ this.installLinks = !this.upgradeLinks && this.getCompatibleInstallLinks(links);
21462
+ return [4 /*yield*/, sleep(500)];
21463
+ case 2:
21464
+ _a.sent(); // Add a delay, for animation
21465
+ return [3 /*break*/, 4];
21466
+ case 3:
21467
+ this.loading = false;
21468
+ this.markForCheck();
21469
+ return [7 /*endfinally*/];
21470
+ case 4: return [2 /*return*/];
21471
+ }
21472
+ });
21473
+ });
21474
+ };
21385
21475
  AppInstallUpgradeCard.prototype.getCompatibleInstallLinks = function (installLinks) {
21386
21476
  // Cordova already running: not need to install
21387
21477
  if (this.platform.is('cordova'))
@@ -21408,10 +21498,16 @@
21408
21498
  // Use min version as default version
21409
21499
  upgradeLinks.forEach(function (link) {
21410
21500
  link.version = link.version || appMinVersionFromPod;
21501
+ var promise = _this.platform.getDownloadingPromise(link.url);
21502
+ // Listening download promise, if exists
21503
+ if (promise) {
21504
+ console.info("[install-upgrade-card] Platform is already downloading this file '" + link.url + "': listening promise...");
21505
+ _this.listenDownloadPromise(link, promise);
21506
+ }
21411
21507
  });
21412
21508
  return isNotEmptyArray(upgradeLinks) ? upgradeLinks : undefined;
21413
21509
  };
21414
- AppInstallUpgradeCard.prototype.getAllInstallLinks = function (config) {
21510
+ AppInstallUpgradeCard.prototype.getLinks = function (config) {
21415
21511
  var result = [];
21416
21512
  // Android
21417
21513
  {
@@ -21419,16 +21515,20 @@
21419
21515
  var url = config.getProperty(CORE_CONFIG_OPTIONS.ANDROID_INSTALL_URL);
21420
21516
  if (isNilOrBlank(url))
21421
21517
  url = this.environment.defaultAndroidInstallUrl || null;
21518
+ // Resolve relative URL
21519
+ var peer = this.network.peer;
21520
+ if (peer && (url.startsWith('./') || url.startsWith('/'))) {
21521
+ url = exports.Peer.path(peer, url);
21522
+ }
21422
21523
  var minVersion = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);
21423
21524
  // Compute App name
21424
21525
  var name = isNotNilOrBlank(url) && config.label || this.environment.defaultAppName || 'SUMARiS';
21425
21526
  if (url) {
21426
- var downloadFilename = void 0;
21427
- var version = void 0;
21527
+ var title = void 0;
21428
21528
  var mimeType = void 0;
21429
21529
  // Get file name
21430
21530
  var filename = this.getFilename(url);
21431
- version = minVersion || 'latest';
21531
+ var version = minVersion || 'latest';
21432
21532
  // OK, this is a downloadable APK file (e.g. NOT a link to a playstore)
21433
21533
  if (filename === null || filename === void 0 ? void 0 : filename.endsWith('.apk')) {
21434
21534
  // Define mime type
@@ -21437,18 +21537,18 @@
21437
21537
  var versionMatches = /-v([1-9][0-9]*\.[0-9]+\.(:?(:?alpha|beta|rc)?[0-9]*))/i.exec(filename);
21438
21538
  version = versionMatches && versionMatches[1] || version;
21439
21539
  // Compute a new file name, with the version
21440
- if (isNotNilOrBlank(name)) {
21441
- downloadFilename = (name + "-v" + version + ".apk").toLowerCase();
21540
+ if (isNotNilOrBlank(name) && version !== 'latest') {
21541
+ filename = (name + "-v" + version + ".apk").toLowerCase();
21542
+ title = name + " v" + version;
21442
21543
  }
21443
21544
  else {
21444
- downloadFilename = filename;
21445
21545
  // Replace 'latest' with the app version, if present
21446
- if (downloadFilename.indexOf('latest')) {
21447
- downloadFilename = downloadFilename.replace('latest', version);
21546
+ if (filename.indexOf('latest')) {
21547
+ filename = filename.replace('latest', version);
21448
21548
  }
21449
21549
  }
21450
21550
  }
21451
- result.push({ name: name, url: url, platform: 'android', version: version, downloadFilename: downloadFilename, mimeType: mimeType });
21551
+ result.push({ name: name, url: url, platform: 'android', version: version, filename: filename, title: title, mimeType: mimeType });
21452
21552
  }
21453
21553
  }
21454
21554
  // iOS - TODO
@@ -21472,12 +21572,105 @@
21472
21572
  AppInstallUpgradeCard.prototype.markForCheck = function () {
21473
21573
  this.cd.markForCheck();
21474
21574
  };
21575
+ AppInstallUpgradeCard.prototype.showToast = function (opts) {
21576
+ return __awaiter(this, void 0, void 0, function () {
21577
+ return __generator(this, function (_a) {
21578
+ switch (_a.label) {
21579
+ case 0: return [4 /*yield*/, Toasts.show(this.toastController, this.translate, opts)];
21580
+ case 1:
21581
+ _a.sent();
21582
+ return [2 /*return*/];
21583
+ }
21584
+ });
21585
+ });
21586
+ };
21587
+ AppInstallUpgradeCard.prototype.listenDownloadPromise = function (link, promise) {
21588
+ return __awaiter(this, void 0, void 0, function () {
21589
+ var location, err_1;
21590
+ return __generator(this, function (_a) {
21591
+ switch (_a.label) {
21592
+ case 0:
21593
+ if (!link || !promise)
21594
+ return [2 /*return*/]; // Skip
21595
+ if (!link.downloading) {
21596
+ link.downloading = true;
21597
+ this.markForCheck();
21598
+ }
21599
+ _a.label = 1;
21600
+ case 1:
21601
+ _a.trys.push([1, 3, 4, 5]);
21602
+ return [4 /*yield*/, promise];
21603
+ case 2:
21604
+ location = _a.sent();
21605
+ console.info('[install-upgrade-card] File downloaded at: ' + location);
21606
+ return [3 /*break*/, 5];
21607
+ case 3:
21608
+ err_1 = _a.sent();
21609
+ console.error('[install-upgrade] Download failed: ' + (err_1 && err_1.message || err_1));
21610
+ this.showDownloadFailedToast(err_1);
21611
+ return [3 /*break*/, 5];
21612
+ case 4:
21613
+ link.downloading = false;
21614
+ this.markForCheck();
21615
+ return [7 /*endfinally*/];
21616
+ case 5: return [2 /*return*/, this.showDownloadCompleteDialog()];
21617
+ }
21618
+ });
21619
+ });
21620
+ };
21621
+ AppInstallUpgradeCard.prototype.showDownloadFailedToast = function (err) {
21622
+ return this.showToast({
21623
+ message: 'ERROR.DOWNLOAD_FAILED',
21624
+ messageParams: { error: err },
21625
+ type: 'error',
21626
+ showCloseButton: true
21627
+ });
21628
+ };
21629
+ AppInstallUpgradeCard.prototype.showDownloadCompleteDialog = function () {
21630
+ return __awaiter(this, void 0, void 0, function () {
21631
+ var translations, alert;
21632
+ return __generator(this, function (_a) {
21633
+ switch (_a.label) {
21634
+ case 0:
21635
+ if (!this._subscription)
21636
+ return [2 /*return*/]; // Skip if component has been destroyed
21637
+ return [4 /*yield*/, this.translate.get([
21638
+ 'INFO.ALERT_HEADER',
21639
+ 'INFO.DOWNLOAD_UPDATE_SUCCEED',
21640
+ 'COMMON.BTN_CLOSE'
21641
+ ]).toPromise()];
21642
+ case 1:
21643
+ translations = _a.sent();
21644
+ return [4 /*yield*/, this.alertController.create({
21645
+ header: translations['INFO.ALERT_HEADER'],
21646
+ message: translations['INFO.DOWNLOAD_UPDATE_SUCCEED'],
21647
+ buttons: [
21648
+ {
21649
+ text: translations['COMMON.BTN_CLOSE'],
21650
+ role: 'cancel',
21651
+ cssClass: 'secondary'
21652
+ }
21653
+ ]
21654
+ })];
21655
+ case 2:
21656
+ alert = _a.sent();
21657
+ return [4 /*yield*/, alert.present()];
21658
+ case 3:
21659
+ _a.sent();
21660
+ return [4 /*yield*/, alert.onDidDismiss()];
21661
+ case 4:
21662
+ _a.sent();
21663
+ return [2 /*return*/];
21664
+ }
21665
+ });
21666
+ });
21667
+ };
21475
21668
  return AppInstallUpgradeCard;
21476
21669
  }());
21477
21670
  AppInstallUpgradeCard.decorators = [
21478
21671
  { type: i0.Component, args: [{
21479
21672
  selector: 'app-install-upgrade-card',
21480
- 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\n <!-- Download button -->\n <ion-button *ngIf=\"link.downloadFilename; else redirectButton\"\n [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\n <!-- 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\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 <!-- Cordova download button -->\n <ion-button *ngIf=\"isAndroidCordova; else webDownloadButton\"\n (click)=\"downloadLink($event, asLink(link))\"\n color=\"tertiary\" class=\"ion-float-end\" >\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",
21673
+ 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",
21481
21674
  changeDetection: i0.ChangeDetectionStrategy.OnPush,
21482
21675
  animations: [slideUpDownAnimation],
21483
21676
  styles: ["ion-text small{font-size:85%}"]
@@ -21486,8 +21679,11 @@
21486
21679
  AppInstallUpgradeCard.ctorParameters = function () { return [
21487
21680
  { type: i1$5.ModalController },
21488
21681
  { type: ConfigService },
21489
- { type: PlatformService },
21682
+ { type: i1$5.ToastController },
21683
+ { type: i1$5.AlertController },
21684
+ { type: i1$2.TranslateService },
21490
21685
  { type: i0.ChangeDetectorRef },
21686
+ { type: PlatformService },
21491
21687
  { type: NetworkService },
21492
21688
  { type: undefined, decorators: [{ type: i0.Inject, args: [ENVIRONMENT,] }] }
21493
21689
  ]; };