@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.
- package/bundles/sumaris-net.ngx-components.umd.js +293 -97
- package/bundles/sumaris-net.ngx-components.umd.js.map +1 -1
- package/bundles/sumaris-net.ngx-components.umd.min.js +1 -1
- package/bundles/sumaris-net.ngx-components.umd.min.js.map +1 -1
- package/esm2015/src/app/core/graphql/graphql.service.js +10 -11
- package/esm2015/src/app/core/install/install-upgrade-card.component.js +152 -51
- package/esm2015/src/app/core/services/model/peer.model.js +15 -2
- package/esm2015/src/app/core/services/network.service.js +2 -2
- package/esm2015/src/app/core/services/platform.service.js +35 -13
- package/esm2015/src/app/shared/services/startable-service.class.js +4 -1
- package/fesm2015/sumaris-net.ngx-components.js +205 -70
- package/fesm2015/sumaris-net.ngx-components.js.map +1 -1
- package/package.json +1 -1
- package/src/app/core/install/install-upgrade-card.component.d.ts +20 -10
- package/src/app/core/services/model/peer.model.d.ts +1 -0
- package/src/app/core/services/platform.service.d.ts +3 -0
- package/src/app/shared/services/startable-service.class.d.ts +1 -0
- package/src/assets/i18n/fr.json +3 -0
- package/sumaris-net.ngx-components.metadata.json +1 -1
|
@@ -6944,6 +6944,9 @@ class StartableService {
|
|
|
6944
6944
|
get started() {
|
|
6945
6945
|
return this._started;
|
|
6946
6946
|
}
|
|
6947
|
+
get starting() {
|
|
6948
|
+
return !!this._startPromise;
|
|
6949
|
+
}
|
|
6947
6950
|
ready() {
|
|
6948
6951
|
if (this._started)
|
|
6949
6952
|
return Promise.resolve(this._data);
|
|
@@ -8165,6 +8168,19 @@ let Peer = Peer_1 = class Peer extends Entity {
|
|
|
8165
8168
|
path: noTrailingSlash(url.pathname)
|
|
8166
8169
|
});
|
|
8167
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
|
+
}
|
|
8168
8184
|
asObject(options) {
|
|
8169
8185
|
return super.asObject(options);
|
|
8170
8186
|
}
|
|
@@ -9593,7 +9609,7 @@ class NetworkService extends StartableService {
|
|
|
9593
9609
|
addListener(name, callback) {
|
|
9594
9610
|
this._listeners[name] = this._listeners[name] || [];
|
|
9595
9611
|
this._listeners[name].push(callback);
|
|
9596
|
-
// When
|
|
9612
|
+
// When unsubscribe, remove from the listener
|
|
9597
9613
|
return new Subscription(() => {
|
|
9598
9614
|
const index = this._listeners[name].indexOf(callback);
|
|
9599
9615
|
if (index !== -1) {
|
|
@@ -11035,7 +11051,7 @@ function restoreTrackedQueries(opts) {
|
|
|
11035
11051
|
const APP_GRAPHQL_TYPE_POLICIES = new InjectionToken('graphqlTypePolicies');
|
|
11036
11052
|
class GraphqlService extends StartableService {
|
|
11037
11053
|
constructor(platform, apollo, httpLink, network, storage, cryptoService, environment, typePolicies) {
|
|
11038
|
-
super(
|
|
11054
|
+
super(platform); // Wait network
|
|
11039
11055
|
this.platform = platform;
|
|
11040
11056
|
this.apollo = apollo;
|
|
11041
11057
|
this.httpLink = httpLink;
|
|
@@ -11050,13 +11066,6 @@ class GraphqlService extends StartableService {
|
|
|
11050
11066
|
this.customErrors = {};
|
|
11051
11067
|
this._debug = !environment.production;
|
|
11052
11068
|
this._defaultFetchPolicy = environment.apolloFetchPolicy;
|
|
11053
|
-
// Restart if network restart
|
|
11054
|
-
this.network.on('start', () => this.restart());
|
|
11055
|
-
// Clear cache
|
|
11056
|
-
this.network.on('resetCache', () => __awaiter(this, void 0, void 0, function* () {
|
|
11057
|
-
yield this.ready();
|
|
11058
|
-
yield this.clearCache();
|
|
11059
|
-
}));
|
|
11060
11069
|
// Listen network status
|
|
11061
11070
|
this._networkStatusChanged$ = network.onNetworkStatusChanges
|
|
11062
11071
|
.pipe(filter(isNotNil), distinctUntilChanged());
|
|
@@ -11461,10 +11470,11 @@ class GraphqlService extends StartableService {
|
|
|
11461
11470
|
}
|
|
11462
11471
|
clearCache(client) {
|
|
11463
11472
|
return __awaiter(this, void 0, void 0, function* () {
|
|
11464
|
-
client = (client || this.
|
|
11473
|
+
client = (client || this.client);
|
|
11465
11474
|
if (client) {
|
|
11466
|
-
const now = this._debug && Date.now();
|
|
11467
11475
|
console.info('[graphql] Clearing Apollo client\'s cache... ');
|
|
11476
|
+
const now = this._debug && Date.now();
|
|
11477
|
+
// Clearing the cache
|
|
11468
11478
|
yield client.cache.reset();
|
|
11469
11479
|
if (this._debug)
|
|
11470
11480
|
console.debug(`[graphql] Apollo client's cache cleared, in ${Date.now() - now}ms`);
|
|
@@ -11477,6 +11487,7 @@ class GraphqlService extends StartableService {
|
|
|
11477
11487
|
/* -- protected methods -- */
|
|
11478
11488
|
ngOnStart() {
|
|
11479
11489
|
return __awaiter(this, void 0, void 0, function* () {
|
|
11490
|
+
yield this.network.ready();
|
|
11480
11491
|
console.info('[graphql] Starting graphql...');
|
|
11481
11492
|
const mobile = this.platform.is('mobile') || this.platform.is('mobileweb');
|
|
11482
11493
|
const enableTrackMutationQueries = !mobile;
|
|
@@ -11612,6 +11623,10 @@ class GraphqlService extends StartableService {
|
|
|
11612
11623
|
console.error('[graphql] Failed to restore tracked queries from storage: ' + (err && err.message || err), err);
|
|
11613
11624
|
}
|
|
11614
11625
|
}
|
|
11626
|
+
// Listen for network restart
|
|
11627
|
+
this._subscription.add(this.network.on('start', () => this.restart()));
|
|
11628
|
+
// Listen for clear cache request, from network
|
|
11629
|
+
this._subscription.add(this.network.on('resetCache', () => this.clearCache()));
|
|
11615
11630
|
console.info('[graphql] Starting graphql [OK]');
|
|
11616
11631
|
return client;
|
|
11617
11632
|
});
|
|
@@ -13644,6 +13659,7 @@ class PlatformService {
|
|
|
13644
13659
|
this.browser = browser;
|
|
13645
13660
|
this.downloader = downloader;
|
|
13646
13661
|
this._started = false;
|
|
13662
|
+
this._downloadingPromise = new Map();
|
|
13647
13663
|
this._debug = !environment.production;
|
|
13648
13664
|
if (this._debug)
|
|
13649
13665
|
console.debug('[platform] Creating service');
|
|
@@ -13668,6 +13684,9 @@ class PlatformService {
|
|
|
13668
13684
|
isAndroidCordova() {
|
|
13669
13685
|
return this._android && this._cordova;
|
|
13670
13686
|
}
|
|
13687
|
+
get canDownload() {
|
|
13688
|
+
return this._android && !!this.downloader;
|
|
13689
|
+
}
|
|
13671
13690
|
width() {
|
|
13672
13691
|
return this.platform.width();
|
|
13673
13692
|
}
|
|
@@ -13709,7 +13728,7 @@ class PlatformService {
|
|
|
13709
13728
|
.then(() => {
|
|
13710
13729
|
this._started = true;
|
|
13711
13730
|
this._startPromise = undefined;
|
|
13712
|
-
console.info(`[platform] Starting platform [OK] {mobile: ${this._mobile}, touchUi: ${this.touchUi},
|
|
13731
|
+
console.info(`[platform] Starting platform [OK] {mobile: ${this._mobile}, touchUi: ${this.touchUi}, canDownload: ${this.canDownload}} in ${Date.now() - now}ms`);
|
|
13713
13732
|
// Update cache configuration when network changed
|
|
13714
13733
|
this.networkService.onNetworkStatusChanges.subscribe((type) => this.configureCache(type !== 'none'));
|
|
13715
13734
|
// Update authentication type
|
|
@@ -13756,27 +13775,44 @@ class PlatformService {
|
|
|
13756
13775
|
window.open(url, target, features, replace);
|
|
13757
13776
|
}
|
|
13758
13777
|
}
|
|
13778
|
+
getDownloadingPromise(uri) {
|
|
13779
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
13780
|
+
return this._downloadingPromise.get(uri);
|
|
13781
|
+
});
|
|
13782
|
+
}
|
|
13759
13783
|
download(request) {
|
|
13760
13784
|
return __awaiter(this, void 0, void 0, function* () {
|
|
13761
13785
|
if (!request || !request.uri)
|
|
13762
13786
|
throw new Error('Missing argument \'request\' or \'request.uri\'');
|
|
13763
|
-
|
|
13764
|
-
|
|
13765
|
-
|
|
13787
|
+
if (this._android && this.downloader) {
|
|
13788
|
+
// Check if not already downloading file
|
|
13789
|
+
let promise = this._downloadingPromise.get(request.uri);
|
|
13790
|
+
if (promise)
|
|
13791
|
+
return promise;
|
|
13792
|
+
request = Object.assign({ visibleInDownloadsUi: true, notificationVisibility: NotificationVisibility.VisibleNotifyCompleted, title: request.title || request.filename }, request);
|
|
13766
13793
|
try {
|
|
13767
|
-
|
|
13794
|
+
console.debug('[platform] Downloading, using request: ' + JSON.stringify(request));
|
|
13795
|
+
// Start download
|
|
13796
|
+
promise = this.downloader.download(request);
|
|
13797
|
+
// Remember this request uri
|
|
13798
|
+
this._downloadingPromise.set(request.uri, promise);
|
|
13799
|
+
const location = yield promise;
|
|
13768
13800
|
console.info('[platform] File successfully downloaded at:' + location);
|
|
13769
13801
|
return location;
|
|
13770
13802
|
}
|
|
13771
13803
|
catch (err) {
|
|
13772
|
-
console.error('[platform]
|
|
13804
|
+
console.error('[platform] Unable to download: ' + (err && err.message || err));
|
|
13773
13805
|
throw err;
|
|
13774
13806
|
}
|
|
13807
|
+
finally {
|
|
13808
|
+
// Forget the request
|
|
13809
|
+
this._downloadingPromise.delete(request.uri);
|
|
13810
|
+
}
|
|
13775
13811
|
}
|
|
13776
|
-
// Fallback (
|
|
13777
|
-
//
|
|
13812
|
+
// Fallback (if not Android and Cordova): opening the URI using the browser
|
|
13813
|
+
// 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/)
|
|
13778
13814
|
else {
|
|
13779
|
-
console.warn('[platform] Cannot use
|
|
13815
|
+
console.warn('[platform] Cannot use Android downloader: using browser open()');
|
|
13780
13816
|
this.open(request.uri, '_system', 'location=no', true);
|
|
13781
13817
|
return undefined;
|
|
13782
13818
|
}
|
|
@@ -13877,13 +13913,14 @@ class PlatformService {
|
|
|
13877
13913
|
storeName: forage.config().storeName,
|
|
13878
13914
|
driver: [forage.INDEXEDDB, forage.WEBSQL]
|
|
13879
13915
|
});
|
|
13880
|
-
// IF data stored in the OLD storage: start migration
|
|
13881
13916
|
const keys = yield oldForage.keys();
|
|
13917
|
+
// No data in the odl storage: skip migration
|
|
13882
13918
|
if (isEmptyArray(keys)) {
|
|
13883
|
-
// Drop the old instance
|
|
13884
|
-
console.
|
|
13919
|
+
// Drop the old instance (not need anymore)
|
|
13920
|
+
console.debug(`[platform] Old storage is empty: dropping unused instance {name: '${forage.config().name}', driver: '${oldForage.driver()}'}`);
|
|
13885
13921
|
yield oldForage.dropInstance();
|
|
13886
13922
|
}
|
|
13923
|
+
// IF some data stored in the OLD storage: start migration
|
|
13887
13924
|
else {
|
|
13888
13925
|
const now = Date.now();
|
|
13889
13926
|
console.info(`[platform] Starting storage migration...`);
|
|
@@ -18443,11 +18480,14 @@ const MimeTypes = Object.freeze({
|
|
|
18443
18480
|
ANDROID_APK: 'application/vnd.android.package-archive'
|
|
18444
18481
|
});
|
|
18445
18482
|
class AppInstallUpgradeCard {
|
|
18446
|
-
constructor(modalCtrl, configService,
|
|
18483
|
+
constructor(modalCtrl, configService, toastController, alertController, translate, cd, platform, network, environment) {
|
|
18447
18484
|
this.modalCtrl = modalCtrl;
|
|
18448
18485
|
this.configService = configService;
|
|
18449
|
-
this.
|
|
18486
|
+
this.toastController = toastController;
|
|
18487
|
+
this.alertController = alertController;
|
|
18488
|
+
this.translate = translate;
|
|
18450
18489
|
this.cd = cd;
|
|
18490
|
+
this.platform = platform;
|
|
18451
18491
|
this.network = network;
|
|
18452
18492
|
this.environment = environment;
|
|
18453
18493
|
this._subscription = new Subscription();
|
|
@@ -18458,7 +18498,6 @@ class AppInstallUpgradeCard {
|
|
|
18458
18498
|
this.showOfflineWarning = true;
|
|
18459
18499
|
this.showInstallButton = false;
|
|
18460
18500
|
this.onUpdateOfflineModeClick = new EventEmitter();
|
|
18461
|
-
this.isAndroidCordova = platform.isAndroidCordova();
|
|
18462
18501
|
}
|
|
18463
18502
|
set showUpdateOfflineFeature(value) {
|
|
18464
18503
|
if (value === this._showUpdateOfflineFeature)
|
|
@@ -18475,18 +18514,8 @@ class AppInstallUpgradeCard {
|
|
|
18475
18514
|
this.offline = this.network.offline;
|
|
18476
18515
|
// Listen pod config
|
|
18477
18516
|
this._subscription.add(this.configService.config
|
|
18478
|
-
.
|
|
18479
|
-
|
|
18480
|
-
const installLinks = this.getAllInstallLinks(config);
|
|
18481
|
-
// Check for upgrade
|
|
18482
|
-
this.updateLinks = this.getCompatibleUpgradeLinks(installLinks, config);
|
|
18483
|
-
// Check for install links (if no upgrade need)
|
|
18484
|
-
this.installLinks = !this.updateLinks && this.getCompatibleInstallLinks(installLinks);
|
|
18485
|
-
setTimeout(() => {
|
|
18486
|
-
this.loading = false;
|
|
18487
|
-
this.markForCheck();
|
|
18488
|
-
}, 2000); // Add a delay, for animation
|
|
18489
|
-
}));
|
|
18517
|
+
.pipe(debounceTime(1000))
|
|
18518
|
+
.subscribe(config => this.checkNeedInstallOrUpdate(config)));
|
|
18490
18519
|
// Listen network changes
|
|
18491
18520
|
this._subscription.add(this.network.onNetworkStatusChanges
|
|
18492
18521
|
.pipe(
|
|
@@ -18494,35 +18523,50 @@ class AppInstallUpgradeCard {
|
|
|
18494
18523
|
//tap(() => this.waitingNetwork = false),
|
|
18495
18524
|
map(connectionType => connectionType === 'none'), distinctUntilChanged())
|
|
18496
18525
|
.subscribe(offline => {
|
|
18497
|
-
this.offline
|
|
18498
|
-
|
|
18526
|
+
if (this.offline !== offline) {
|
|
18527
|
+
this.offline = offline;
|
|
18528
|
+
this.markForCheck();
|
|
18529
|
+
}
|
|
18499
18530
|
}));
|
|
18500
18531
|
});
|
|
18501
18532
|
}
|
|
18502
18533
|
ngOnDestroy() {
|
|
18503
18534
|
this._subscription.unsubscribe();
|
|
18535
|
+
this._subscription = null;
|
|
18536
|
+
this.onUpdateOfflineModeClick.complete();
|
|
18537
|
+
this.installLinks = null;
|
|
18538
|
+
this.upgradeLinks = null;
|
|
18504
18539
|
}
|
|
18505
|
-
|
|
18506
|
-
|
|
18507
|
-
|
|
18508
|
-
|
|
18509
|
-
|
|
18510
|
-
|
|
18511
|
-
|
|
18512
|
-
|
|
18540
|
+
download(event, link) {
|
|
18541
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18542
|
+
if (!link || !link.url) {
|
|
18543
|
+
console.error('[install-upgrade-card] Missing required argument \'link.url\'');
|
|
18544
|
+
return; // Skip
|
|
18545
|
+
}
|
|
18546
|
+
const job = this.platform.download({
|
|
18547
|
+
uri: link.url,
|
|
18548
|
+
title: link.title,
|
|
18549
|
+
filename: link.filename,
|
|
18550
|
+
mimeType: link.mimeType
|
|
18551
|
+
});
|
|
18552
|
+
return this.listenDownloadPromise(link, job);
|
|
18513
18553
|
});
|
|
18514
18554
|
}
|
|
18515
18555
|
tryOnline() {
|
|
18516
|
-
this
|
|
18517
|
-
|
|
18518
|
-
this.network.tryOnline({
|
|
18519
|
-
showLoadingToast: false,
|
|
18520
|
-
showOnlineToast: true,
|
|
18521
|
-
showOfflineToast: false
|
|
18522
|
-
})
|
|
18523
|
-
.then(() => {
|
|
18524
|
-
this.waitingNetwork = false;
|
|
18556
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18557
|
+
this.waitingNetwork = true;
|
|
18525
18558
|
this.markForCheck();
|
|
18559
|
+
try {
|
|
18560
|
+
yield this.network.tryOnline({
|
|
18561
|
+
showLoadingToast: false,
|
|
18562
|
+
showOnlineToast: true,
|
|
18563
|
+
showOfflineToast: false
|
|
18564
|
+
});
|
|
18565
|
+
}
|
|
18566
|
+
finally {
|
|
18567
|
+
this.waitingNetwork = false;
|
|
18568
|
+
this.markForCheck();
|
|
18569
|
+
}
|
|
18526
18570
|
});
|
|
18527
18571
|
}
|
|
18528
18572
|
getPlatformName(platform) {
|
|
@@ -18539,6 +18583,23 @@ class AppInstallUpgradeCard {
|
|
|
18539
18583
|
return value;
|
|
18540
18584
|
}
|
|
18541
18585
|
/* -- private method -- */
|
|
18586
|
+
checkNeedInstallOrUpdate(config) {
|
|
18587
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18588
|
+
console.info('[install] Check if need to install or upgrade...');
|
|
18589
|
+
try {
|
|
18590
|
+
const links = this.getLinks(config);
|
|
18591
|
+
// Check for upgrade
|
|
18592
|
+
this.upgradeLinks = this.getCompatibleUpgradeLinks(links, config);
|
|
18593
|
+
// Check for install links (if no upgrade need)
|
|
18594
|
+
this.installLinks = !this.upgradeLinks && this.getCompatibleInstallLinks(links);
|
|
18595
|
+
yield sleep(500); // Add a delay, for animation
|
|
18596
|
+
}
|
|
18597
|
+
finally {
|
|
18598
|
+
this.loading = false;
|
|
18599
|
+
this.markForCheck();
|
|
18600
|
+
}
|
|
18601
|
+
});
|
|
18602
|
+
}
|
|
18542
18603
|
getCompatibleInstallLinks(installLinks) {
|
|
18543
18604
|
// Cordova already running: not need to install
|
|
18544
18605
|
if (this.platform.is('cordova'))
|
|
@@ -18564,10 +18625,16 @@ class AppInstallUpgradeCard {
|
|
|
18564
18625
|
// Use min version as default version
|
|
18565
18626
|
upgradeLinks.forEach(link => {
|
|
18566
18627
|
link.version = link.version || appMinVersionFromPod;
|
|
18628
|
+
const promise = this.platform.getDownloadingPromise(link.url);
|
|
18629
|
+
// Listening download promise, if exists
|
|
18630
|
+
if (promise) {
|
|
18631
|
+
console.info(`[install-upgrade-card] Platform is already downloading this file \'${link.url}\': listening promise...`);
|
|
18632
|
+
this.listenDownloadPromise(link, promise);
|
|
18633
|
+
}
|
|
18567
18634
|
});
|
|
18568
18635
|
return isNotEmptyArray(upgradeLinks) ? upgradeLinks : undefined;
|
|
18569
18636
|
}
|
|
18570
|
-
|
|
18637
|
+
getLinks(config) {
|
|
18571
18638
|
const result = [];
|
|
18572
18639
|
// Android
|
|
18573
18640
|
{
|
|
@@ -18575,16 +18642,20 @@ class AppInstallUpgradeCard {
|
|
|
18575
18642
|
let url = config.getProperty(CORE_CONFIG_OPTIONS.ANDROID_INSTALL_URL);
|
|
18576
18643
|
if (isNilOrBlank(url))
|
|
18577
18644
|
url = this.environment.defaultAndroidInstallUrl || null;
|
|
18645
|
+
// Resolve relative URL
|
|
18646
|
+
const peer = this.network.peer;
|
|
18647
|
+
if (peer && (url.startsWith('./') || url.startsWith('/'))) {
|
|
18648
|
+
url = Peer.path(peer, url);
|
|
18649
|
+
}
|
|
18578
18650
|
const minVersion = config.getProperty(CORE_CONFIG_OPTIONS.APP_MIN_VERSION);
|
|
18579
18651
|
// Compute App name
|
|
18580
18652
|
const name = isNotNilOrBlank(url) && config.label || this.environment.defaultAppName || 'SUMARiS';
|
|
18581
18653
|
if (url) {
|
|
18582
|
-
let
|
|
18583
|
-
let version;
|
|
18654
|
+
let title;
|
|
18584
18655
|
let mimeType;
|
|
18585
18656
|
// Get file name
|
|
18586
|
-
|
|
18587
|
-
version = minVersion || 'latest';
|
|
18657
|
+
let filename = this.getFilename(url);
|
|
18658
|
+
let version = minVersion || 'latest';
|
|
18588
18659
|
// OK, this is a downloadable APK file (e.g. NOT a link to a playstore)
|
|
18589
18660
|
if (filename === null || filename === void 0 ? void 0 : filename.endsWith('.apk')) {
|
|
18590
18661
|
// Define mime type
|
|
@@ -18593,18 +18664,18 @@ class AppInstallUpgradeCard {
|
|
|
18593
18664
|
const versionMatches = /-v([1-9][0-9]*\.[0-9]+\.(:?(:?alpha|beta|rc)?[0-9]*))/i.exec(filename);
|
|
18594
18665
|
version = versionMatches && versionMatches[1] || version;
|
|
18595
18666
|
// Compute a new file name, with the version
|
|
18596
|
-
if (isNotNilOrBlank(name)) {
|
|
18597
|
-
|
|
18667
|
+
if (isNotNilOrBlank(name) && version !== 'latest') {
|
|
18668
|
+
filename = `${name}-v${version}.apk`.toLowerCase();
|
|
18669
|
+
title = `${name} v${version}`;
|
|
18598
18670
|
}
|
|
18599
18671
|
else {
|
|
18600
|
-
downloadFilename = filename;
|
|
18601
18672
|
// Replace 'latest' with the app version, if present
|
|
18602
|
-
if (
|
|
18603
|
-
|
|
18673
|
+
if (filename.indexOf('latest')) {
|
|
18674
|
+
filename = filename.replace('latest', version);
|
|
18604
18675
|
}
|
|
18605
18676
|
}
|
|
18606
18677
|
}
|
|
18607
|
-
result.push({ name, url, platform: 'android', version,
|
|
18678
|
+
result.push({ name, url, platform: 'android', version, filename, title, mimeType });
|
|
18608
18679
|
}
|
|
18609
18680
|
}
|
|
18610
18681
|
// iOS - TODO
|
|
@@ -18628,11 +18699,72 @@ class AppInstallUpgradeCard {
|
|
|
18628
18699
|
markForCheck() {
|
|
18629
18700
|
this.cd.markForCheck();
|
|
18630
18701
|
}
|
|
18702
|
+
showToast(opts) {
|
|
18703
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18704
|
+
yield Toasts.show(this.toastController, this.translate, opts);
|
|
18705
|
+
});
|
|
18706
|
+
}
|
|
18707
|
+
listenDownloadPromise(link, promise) {
|
|
18708
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18709
|
+
if (!link || !promise)
|
|
18710
|
+
return; // Skip
|
|
18711
|
+
if (!link.downloading) {
|
|
18712
|
+
link.downloading = true;
|
|
18713
|
+
this.markForCheck();
|
|
18714
|
+
}
|
|
18715
|
+
try {
|
|
18716
|
+
const location = yield promise;
|
|
18717
|
+
console.info('[install-upgrade-card] File downloaded at: ' + location);
|
|
18718
|
+
}
|
|
18719
|
+
// Failed: display a toast
|
|
18720
|
+
catch (err) {
|
|
18721
|
+
console.error('[install-upgrade] Download failed: ' + (err && err.message || err));
|
|
18722
|
+
this.showDownloadFailedToast(err);
|
|
18723
|
+
}
|
|
18724
|
+
finally {
|
|
18725
|
+
link.downloading = false;
|
|
18726
|
+
this.markForCheck();
|
|
18727
|
+
}
|
|
18728
|
+
return this.showDownloadCompleteDialog();
|
|
18729
|
+
});
|
|
18730
|
+
}
|
|
18731
|
+
showDownloadFailedToast(err) {
|
|
18732
|
+
return this.showToast({
|
|
18733
|
+
message: 'ERROR.DOWNLOAD_FAILED',
|
|
18734
|
+
messageParams: { error: err },
|
|
18735
|
+
type: 'error',
|
|
18736
|
+
showCloseButton: true
|
|
18737
|
+
});
|
|
18738
|
+
}
|
|
18739
|
+
showDownloadCompleteDialog() {
|
|
18740
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
18741
|
+
if (!this._subscription)
|
|
18742
|
+
return; // Skip if component has been destroyed
|
|
18743
|
+
const translations = yield this.translate.get([
|
|
18744
|
+
'INFO.ALERT_HEADER',
|
|
18745
|
+
'INFO.DOWNLOAD_UPDATE_SUCCEED',
|
|
18746
|
+
'COMMON.BTN_CLOSE'
|
|
18747
|
+
]).toPromise();
|
|
18748
|
+
const alert = yield this.alertController.create({
|
|
18749
|
+
header: translations['INFO.ALERT_HEADER'],
|
|
18750
|
+
message: translations['INFO.DOWNLOAD_UPDATE_SUCCEED'],
|
|
18751
|
+
buttons: [
|
|
18752
|
+
{
|
|
18753
|
+
text: translations['COMMON.BTN_CLOSE'],
|
|
18754
|
+
role: 'cancel',
|
|
18755
|
+
cssClass: 'secondary'
|
|
18756
|
+
}
|
|
18757
|
+
]
|
|
18758
|
+
});
|
|
18759
|
+
yield alert.present();
|
|
18760
|
+
yield alert.onDidDismiss();
|
|
18761
|
+
});
|
|
18762
|
+
}
|
|
18631
18763
|
}
|
|
18632
18764
|
AppInstallUpgradeCard.decorators = [
|
|
18633
18765
|
{ type: Component, args: [{
|
|
18634
18766
|
selector: 'app-install-upgrade-card',
|
|
18635
|
-
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
|
|
18767
|
+
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",
|
|
18636
18768
|
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
18637
18769
|
animations: [slideUpDownAnimation],
|
|
18638
18770
|
styles: ["ion-text small{font-size:85%}"]
|
|
@@ -18641,8 +18773,11 @@ AppInstallUpgradeCard.decorators = [
|
|
|
18641
18773
|
AppInstallUpgradeCard.ctorParameters = () => [
|
|
18642
18774
|
{ type: ModalController },
|
|
18643
18775
|
{ type: ConfigService },
|
|
18644
|
-
{ type:
|
|
18776
|
+
{ type: ToastController },
|
|
18777
|
+
{ type: AlertController },
|
|
18778
|
+
{ type: TranslateService },
|
|
18645
18779
|
{ type: ChangeDetectorRef },
|
|
18780
|
+
{ type: PlatformService },
|
|
18646
18781
|
{ type: NetworkService },
|
|
18647
18782
|
{ type: undefined, decorators: [{ type: Inject, args: [ENVIRONMENT,] }] }
|
|
18648
18783
|
];
|