diff --git a/ui/src/app/app.component.html b/ui/src/app/app.component.html index 824f0b989..032caa388 100644 --- a/ui/src/app/app.component.html +++ b/ui/src/app/app.component.html @@ -68,7 +68,7 @@ - + @@ -106,8 +106,8 @@ - - + + diff --git a/ui/src/app/pages/apps-routes/app-show/app-show.page.html b/ui/src/app/pages/apps-routes/app-show/app-show.page.html index 977dce885..bc66982df 100644 --- a/ui/src/app/pages/apps-routes/app-show/app-show.page.html +++ b/ui/src/app/pages/apps-routes/app-show/app-show.page.html @@ -63,13 +63,13 @@ - - - + + + -

{{ health.key }}

-

{{ result }}

-

{{ $any(health.value).error }}

+

{{ health.key }}

+

Result: {{ result | titlecase }}

+

{{ $any(health.value).error }}

@@ -84,9 +84,14 @@ -

{{ dep.value.title }}

+

+ + {{ dep.value.title }} +

{{ dep.value.version | displayEmver }}

-

{{ dep.value.errorText || 'satisfied' }}

+

+ {{ dep.value.errorText || 'satisfied' }} +

diff --git a/ui/src/app/pages/apps-routes/app-show/app-show.page.scss b/ui/src/app/pages/apps-routes/app-show/app-show.page.scss index 7ec7d334e..b1e7b77f2 100644 --- a/ui/src/app/pages/apps-routes/app-show/app-show.page.scss +++ b/ui/src/app/pages/apps-routes/app-show/app-show.page.scss @@ -11,4 +11,14 @@ .icon-spinner { height: 20px; width: 20px; +} + +.inline { + * { + display: inline-block; + vertical-align: middle; + } + ion-icon { + padding-right: 4px; + } } \ No newline at end of file diff --git a/ui/src/app/pages/apps-routes/app-show/app-show.page.ts b/ui/src/app/pages/apps-routes/app-show/app-show.page.ts index bdbef3273..c74fe2ed5 100644 --- a/ui/src/app/pages/apps-routes/app-show/app-show.page.ts +++ b/ui/src/app/pages/apps-routes/app-show/app-show.page.ts @@ -391,7 +391,7 @@ export class AppShowPage { }, { action: () => this.donate(), - title: `Donate to ${this.pkg.manifest.title}`, + title: 'Donate', icon: 'logo-bitcoin', color: 'danger', }, diff --git a/ui/src/app/pages/marketplace-routes/app-release-notes/app-release-notes.page.ts b/ui/src/app/pages/marketplace-routes/app-release-notes/app-release-notes.page.ts index 76e2e5ce5..e1a9248b4 100644 --- a/ui/src/app/pages/marketplace-routes/app-release-notes/app-release-notes.page.ts +++ b/ui/src/app/pages/marketplace-routes/app-release-notes/app-release-notes.page.ts @@ -24,15 +24,19 @@ export class AppReleaseNotes { async ngOnInit () { this.pkgId = this.route.snapshot.paramMap.get('pkgId') try { + const promises = [] if (!this.marketplaceService.releaseNotes[this.pkgId]) { - await this.marketplaceService.getReleaseNotes(this.pkgId) + promises.push(this.marketplaceService.getReleaseNotes(this.pkgId)) } + if (!this.marketplaceService.pkgs.length) { + promises.push(this.marketplaceService.load()) + } + await Promise.all(promises) } catch (e) { this.errToast.present(e) } finally { this.loading = false } - } ngAfterViewInit () { diff --git a/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.html b/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.html index fdcfbb36b..1e91da67e 100644 --- a/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.html +++ b/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.html @@ -11,19 +11,22 @@ - + - - - - + - - + +
@@ -33,11 +36,11 @@
- +
- - + + @@ -73,15 +76,15 @@ - +

Now Available...

-

Embassy OS {{ eos.version }}

-

{{ eos.headline }}

+

Embassy OS {{ marketplaceService.eos.version }}

+

{{ marketplaceService.eos.headline }}

diff --git a/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.ts b/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.ts index 78e2b5373..8f97731ca 100644 --- a/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.ts +++ b/ui/src/app/pages/marketplace-routes/marketplace-list/marketplace-list.page.ts @@ -1,5 +1,5 @@ import { Component, ViewChild } from '@angular/core' -import { MarketplaceData, MarketplaceEOS, MarketplacePkg } from 'src/app/services/api/api.types' +import { MarketplacePkg } from 'src/app/services/api/api.types' import { wizardModal } from 'src/app/components/install-wizard/install-wizard.component' import { IonContent, ModalController } from '@ionic/angular' import { WizardBaker } from 'src/app/components/install-wizard/prebaked-wizards' @@ -7,9 +7,7 @@ import { PackageDataEntry, PackageState } from 'src/app/services/patch-db/data-m import { Subscription } from 'rxjs' import { ErrorToastService } from 'src/app/services/error-toast.service' import { MarketplaceService } from '../marketplace.service' -import { ApiService } from 'src/app/services/api/embassy-api.service' import { PatchDbService } from 'src/app/services/patch-db/patch-db.service' -import { pauseFor } from 'src/app/util/misc.util' @Component({ selector: 'marketplace-list', @@ -17,30 +15,25 @@ import { pauseFor } from 'src/app/util/misc.util' styleUrls: ['./marketplace-list.page.scss'], }) export class MarketplaceListPage { + PackageState = PackageState + @ViewChild(IonContent) content: IonContent + + pkgs: MarketplacePkg[] = [] + categories: string[] localPkgs: { [id: string]: PackageDataEntry } = { } - - pageLoading = true - pkgsLoading = true - category = 'featured' query: string - - data: MarketplaceData - eos: MarketplaceEOS - pkgs: MarketplacePkg[] = [] - - PackageState = PackageState + loading = true subs: Subscription[] = [] constructor ( - private readonly marketplaceService: MarketplaceService, - private readonly api: ApiService, private readonly modalCtrl: ModalController, private readonly errToast: ErrorToastService, private readonly wizardBaker: WizardBaker, - public readonly patch: PatchDbService, + private readonly patch: PatchDbService, + public readonly marketplaceService: MarketplaceService, ) { } async ngOnInit () { @@ -54,26 +47,21 @@ export class MarketplaceListPage { ] try { - const [data, eos] = await Promise.all([ - this.api.getMarketplaceData({ }), - this.api.getEos({ }), - this.marketplaceService.getAllPkgs(), - ]) - this.eos = eos - this.data = data - - this.pkgsLoading = false - this.getPkgs() + if (!this.marketplaceService.pkgs.length) { + await this.marketplaceService.load() + } // category should start as first item in array // remove here then add at beginning - const filterdCategories = this.data.categories.filter(cat => this.category !== cat) - this.data.categories = [this.category, 'updates'].concat(filterdCategories).concat(['all']) + const filterdCategories = this.marketplaceService.data.categories.filter(cat => this.category !== cat) + this.categories = [this.category, 'updates'].concat(filterdCategories).concat(['all']) + + this.filterPkgs() } catch (e) { this.errToast.present(e) } finally { - this.pageLoading = false + this.loading = false } } @@ -86,35 +74,44 @@ export class MarketplaceListPage { } async search (): Promise { - // you can actually press enter and run code before the data binds to this.category - await pauseFor(200) this.category = undefined - await this.getPkgs() + await this.filterPkgs() + } + + async switchCategory (category: string): Promise { + this.category = category + this.query = undefined + this.filterPkgs() } async updateEos (): Promise { + const { version, headline, 'release-notes': releaseNotes } = this.marketplaceService.eos + await wizardModal( this.modalCtrl, this.wizardBaker.updateOS({ - version: this.eos.version, - headline: this.eos.headline, - releaseNotes: this.eos['release-notes'], + version, + headline, + releaseNotes, }), ) } - private async getPkgs (): Promise { + private async filterPkgs (): Promise { if (this.category === 'updates') { - this.pkgs = this.marketplaceService.allPkgs.filter(pkg => { - return this.localPkgs[pkg.manifest.id] && pkg.manifest.version !== this.localPkgs[pkg.manifest.id].manifest.version + this.pkgs = this.marketplaceService.pkgs.filter(pkg => { + const { id, version } = pkg.manifest + return this.localPkgs[id] && version !== this.localPkgs[id].manifest.version }) } else { - this.pkgs = this.marketplaceService.allPkgs.filter(pkg => { + this.pkgs = this.marketplaceService.pkgs.filter(pkg => { + const { id, title, description } = pkg.manifest if (this.query) { - return pkg.manifest.id.toUpperCase().includes(this.query.toUpperCase()) || - pkg.manifest.title.toUpperCase().includes(this.query.toUpperCase()) || - pkg.manifest.description.short.toUpperCase().includes(this.query.toUpperCase()) || - pkg.manifest.description.long.toUpperCase().includes(this.query.toUpperCase()) + const query = this.query.toUpperCase() + return id.toUpperCase().includes(query) || + title.toUpperCase().includes(query) || + description.short.toUpperCase().includes(query) || + description.long.toUpperCase().includes(query) } else { if (this.category === 'all' || !this.category) { return true @@ -125,10 +122,4 @@ export class MarketplaceListPage { }) } } - - async switchCategory (category: string): Promise { - this.category = category - this.query = undefined - await this.getPkgs() - } } diff --git a/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.html b/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.html index 6d7fe0c50..32f9a70ff 100644 --- a/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.html +++ b/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.html @@ -12,192 +12,190 @@ - - - - -
- -
-

{{ pkg.manifest.title }}

-

{{ pkg.manifest.version | displayEmver }}

-
- -

- Not Installed + + + +

+ +
+

{{ pkg.manifest.title }}

+

{{ pkg.manifest.version | displayEmver }}

+
+ +

Not Installed

+ + + +

+ Installed + Update Available

- - - -

- Installed - Update Available -

- -

- {{ localPkg.state | titlecase }}...{{ (localPkg['install-progress'] | installState).totalProgress }}% -

- -

- {{ localPkg.state | titlecase }} - -

-
-
+ +

+ {{ localPkg.state | titlecase }}...{{ (localPkg['install-progress'] | installState).totalProgress }}% +

+ +

+ {{ localPkg.state | titlecase }} + +

+
- - - - - Install - - - - - - - Update - - - Downgrade - - +
+ + + + + Install + + + + + + + Update + + + Downgrade + + + + + + + + View Service + + + + + + + + +

+ + + + {{ rec.dependentTitle }} +

+
+

{{ rec.description }}

+

{{ pkg.manifest.title }} version {{ pkg.manifest.version | displayEmver }} is compatible.

+

{{ pkg.manifest.title }} version {{ pkg.manifest.version | displayEmver }} is NOT compatible.

+ + + +
+
+
+ + + + + New in {{ pkg.manifest.version | displayEmver }} + + All Release Notes + + + + + +
+
+
+ + Description + + +
{{ pkg.manifest.description.long }}
+
+
+ + + Dependencies + + + + + + + + +

+ {{ pkg['dependency-metadata'][dep.key].title }} + (required) + (required by default) + (optional) +

+

{{ dep.value.version | displayEmver }}

+

{{ dep.value.description }}

+
+
+
+
+
+
+
+ + Additional Info + + + + + + + +

Other Versions

+

Click to view other versions

+
+ +
+ + +

License

+

{{ pkg.manifest.license }}

+
+ +
+ + +

Instructions

+

Click to view instructions

+
+ +
+
-
- - - - View Service - + + + + +

Source Repository

+

{{ pkg.manifest['upstream-repo'] }}

+
+ +
+ + +

Wrapper Repository

+

{{ pkg.manifest['wrapper-repo'] }}

+
+ +
+ + +

Support Site

+

{{ pkg.manifest['support-site'] }}

+
+ +
+
- - - - -

- - - - {{ rec.dependentTitle }} -

-
-

{{ rec.description }}

-

{{ pkg.manifest.title }} version {{ pkg.manifest.version | displayEmver }} is compatible.

-

{{ pkg.manifest.title }} version {{ pkg.manifest.version | displayEmver }} is NOT compatible.

- - - -
-
-
- - - - - New in {{ pkg.manifest.version | displayEmver }} - - All Release Notes - - - - - -
-
-
- - Description - - -
{{ pkg.manifest.description.long }}
-
-
- - - Dependencies - - - - - - - - -

- {{ pkg['dependency-metadata'][dep.key].title }} - (recommended) -

-

{{ dep.value.version | displayEmver }}

-

{{ dep.value.description }}

-
-
-
-
-
-
-
- - Additional Info - - - - - - - -

Other Versions

-

Click to view other versions

-
- -
- - -

License

-

{{ pkg.manifest.license }}

-
- -
- - -

Instructions

-

Click to view instructions

-
- -
-
-
- - - - -

Source Repository

-

{{ pkg.manifest['upstream-repo'] }}

-
- -
- - -

Wrapper Repository

-

{{ pkg.manifest['wrapper-repo'] }}

-
- -
- - -

Support Site

-

{{ pkg.manifest['support-site'] }}

-
- -
-
-
-
-
-
- +
diff --git a/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.ts b/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.ts index b5ad813c3..7cd3a7852 100644 --- a/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.ts +++ b/ui/src/app/pages/marketplace-routes/marketplace-show/marketplace-show.page.ts @@ -13,6 +13,7 @@ import { MarketplaceService } from '../marketplace.service' import { Subscription } from 'rxjs' import { MarkdownPage } from 'src/app/modals/markdown/markdown.page' import { ApiService } from 'src/app/services/api/embassy-api.service' +import { MarketplacePkg } from 'src/app/services/api/api.types' @Component({ selector: 'marketplace-show', @@ -23,11 +24,11 @@ export class MarketplaceShowPage { @ViewChild(IonContent) content: IonContent loading = true pkgId: string + pkg: MarketplacePkg localPkg: PackageDataEntry PackageState = PackageState rec: Recommendation | null = null showRec = true - subs: Subscription[] = [] constructor ( @@ -41,7 +42,7 @@ export class MarketplaceShowPage { private readonly emver: Emver, private readonly patch: PatchDbService, private readonly embassyApi: ApiService, - public readonly marketplaceService: MarketplaceService, + private readonly marketplaceService: MarketplaceService, ) { } async ngOnInit () { @@ -57,10 +58,18 @@ export class MarketplaceShowPage { }), ] - if (this.marketplaceService.pkgs[this.pkgId]) { + try { + if (!this.marketplaceService.pkgs.length) { + await this.marketplaceService.load() + } + this.pkg = this.marketplaceService.pkgs.find(pkg => pkg.manifest.id === this.pkgId) + if (!this.pkg) { + throw new Error(`Service with ID "${this.pkgId}" not found.`) + } + } catch (e) { + this.errToast.present(e) + } finally { this.loading = false - } else { - this.getPkg() } } @@ -72,27 +81,16 @@ export class MarketplaceShowPage { this.subs.forEach(sub => sub.unsubscribe()) } - async getPkg (version?: string): Promise { - try { - await this.marketplaceService.getPkg(this.pkgId, version) - } catch (e) { - this.errToast.present(e) - } finally { - await pauseFor(100) - this.loading = false - } - } - async presentAlertVersions () { const alert = await this.alertCtrl.create({ header: 'Versions', - inputs: this.marketplaceService.pkgs[this.pkgId].versions.sort((a, b) => -1 * this.emver.compare(a, b)).map(v => { + inputs: this.pkg.versions.sort((a, b) => -1 * this.emver.compare(a, b)).map(v => { return { name: v, // for CSS type: 'radio', label: displayEmver(v), // appearance on screen value: v, // literal SEM version value - checked: this.marketplaceService.pkgs[this.pkgId].manifest.version === v, + checked: this.pkg.manifest.version === v, } }), buttons: [ @@ -116,7 +114,7 @@ export class MarketplaceShowPage { const modal = await this.modalCtrl.create({ componentProps: { title, - contentUrl: this.marketplaceService.pkgs[this.pkgId][title], + contentUrl: this.pkg[title], }, component: MarkdownPage, }) @@ -125,7 +123,7 @@ export class MarketplaceShowPage { } async tryInstall () { - const { id, title, version, alerts } = this.marketplaceService.pkgs[this.pkgId].manifest + const { id, title, version, alerts } = this.pkg.manifest if (!alerts.install) { await this.install(id, version) @@ -152,7 +150,7 @@ export class MarketplaceShowPage { } async presentModal (action: 'update' | 'downgrade') { - const { id, title, version, dependencies, alerts } = this.marketplaceService.pkgs[this.pkgId].manifest + const { id, title, version, dependencies, alerts } = this.pkg.manifest const value = { id, title, @@ -177,6 +175,18 @@ export class MarketplaceShowPage { this.showRec = false } + private async getPkg (version?: string): Promise { + this.loading = true + try { + this.pkg = await this.marketplaceService.getPkg(this.pkgId, version) + } catch (e) { + this.errToast.present(e) + } finally { + await pauseFor(100) + this.loading = false + } + } + private async install (id: string, version?: string): Promise { const loader = await this.loadingCtrl.create({ spinner: 'lines', diff --git a/ui/src/app/pages/marketplace-routes/marketplace.service.ts b/ui/src/app/pages/marketplace-routes/marketplace.service.ts index ef96165b9..4a5b1c0d4 100644 --- a/ui/src/app/pages/marketplace-routes/marketplace.service.ts +++ b/ui/src/app/pages/marketplace-routes/marketplace.service.ts @@ -1,5 +1,5 @@ import { Injectable } from '@angular/core' -import { MarketplacePkg } from 'src/app/services/api/api.types' +import { MarketplaceData, MarketplaceEOS, MarketplacePkg } from 'src/app/services/api/api.types' import { ApiService } from 'src/app/services/api/embassy-api.service' import { Emver } from 'src/app/services/emver.service' import { PackageDataEntry } from 'src/app/services/patch-db/data-model' @@ -8,9 +8,9 @@ import { PackageDataEntry } from 'src/app/services/patch-db/data-model' providedIn: 'root', }) export class MarketplaceService { - allPkgs: MarketplacePkg[] = [] - pkgs: { [id: string]: MarketplacePkg } = { } - updates: MarketplacePkg[] = [] + data: MarketplaceData + eos: MarketplaceEOS + pkgs: MarketplacePkg[] = [] releaseNotes: { [id: string]: { [version: string]: string } } = { } @@ -20,61 +20,55 @@ export class MarketplaceService { private readonly emver: Emver, ) { } - async getUpdates (localPkgs: { [id: string]: PackageDataEntry }) : Promise { - const idAndCurrentVersions = Object.keys(localPkgs).map(key => ({ id: key, version: localPkgs[key].manifest.version })) - const latestPkgs = (await this.api.getMarketplacePkgs({ - ids: idAndCurrentVersions, - })) + async load (): Promise { + const [data, eos, pkgs] = await Promise.all([ + this.api.getMarketplaceData({ }), + this.api.getEos({ }), + this.getPkgs(1, 100), + ]) + this.data = data + this.eos = eos + this.pkgs = pkgs + } - const updates = latestPkgs.filter(latestPkg => { + async getUpdates (localPkgs: { [id: string]: PackageDataEntry }) : Promise { + const idAndCurrentVersions = Object.keys(localPkgs).map(key => ({ id: key, version: localPkgs[key].manifest.version })) + const latestPkgs = await this.api.getMarketplacePkgs({ + ids: idAndCurrentVersions, + }) + + return latestPkgs.filter(latestPkg => { const latestVersion = latestPkg.manifest.version const curVersion = localPkgs[latestPkg.manifest.id]?.manifest.version return !!curVersion && this.emver.compare(latestVersion, curVersion) === 1 }) - - this.updates = updates } - async getAllPkgs (): Promise { - if (this.allPkgs.length) return - - this.allPkgs = await this.getPkgs( - undefined, - null, - 1, - 100000, - ) - } - - async getPkgs (category: string, query: string, page: number, perPage: number) : Promise { - const pkgs = await this.api.getMarketplacePkgs({ - category: category !== 'all' ? category : undefined, - query, - page: String(page), - 'per-page': String(perPage), - }) - this.pkgs = pkgs.reduce((cur, val) => { - cur[val.manifest.id] = val - return cur - }, { }) - return pkgs - } - - async getPkg (id: string, version?: string): Promise { + async getPkg (id: string, version?: string): Promise { const pkgs = await this.api.getMarketplacePkgs({ ids: [{ id, version: version || '*' }], }) const pkg = pkgs.find(pkg => pkg.manifest.id == id) - if (pkg) { - this.pkgs[id] = pkg + + if (!pkg) { + throw new Error(`No results for ${id}${version ? ' ' + version : ''}`) } else { - throw new Error(`No results for ${id}${version ? ' ' + version : ''}.`) + return pkg } } async getReleaseNotes (id: string): Promise { this.releaseNotes[id] = await this.api.getReleaseNotes({ id }) } + + private async getPkgs (page: number, perPage: number) : Promise { + const pkgs = await this.api.getMarketplacePkgs({ + page: String(page), + 'per-page': String(perPage), + }) + + return pkgs + } } diff --git a/ui/src/app/pages/server-routes/preferences/preferences.page.html b/ui/src/app/pages/server-routes/preferences/preferences.page.html index 87d9b7087..dfb0dade0 100644 --- a/ui/src/app/pages/server-routes/preferences/preferences.page.html +++ b/ui/src/app/pages/server-routes/preferences/preferences.page.html @@ -12,7 +12,7 @@ {{ fields['name'].name }} - {{ patch.data.ui.name }} + {{ patch.data.ui.name || defaultName }} diff --git a/ui/src/app/pages/server-routes/preferences/preferences.page.ts b/ui/src/app/pages/server-routes/preferences/preferences.page.ts index ea0edf072..afb996394 100644 --- a/ui/src/app/pages/server-routes/preferences/preferences.page.ts +++ b/ui/src/app/pages/server-routes/preferences/preferences.page.ts @@ -14,6 +14,7 @@ import { ErrorToastService } from 'src/app/services/error-toast.service' export class PreferencesPage { @ViewChild(IonContent) content: IonContent fields = fields + defaultName: string constructor ( private readonly modalCtrl: ModalController, @@ -23,6 +24,10 @@ export class PreferencesPage { public readonly patch: PatchDbService, ) { } + ngOnInit () { + this.defaultName = `Embassy-${this.patch.data['server-info'].id}` + } + ngAfterViewInit () { this.content.scrollToPoint(undefined, 1) } @@ -34,11 +39,11 @@ export class PreferencesPage { message: 'This is for your reference only.', label: 'Device Name', useMask: false, - placeholder: this.patch.data['server-info'].id, + placeholder: this.defaultName, nullable: true, value: this.patch.data.ui.name, buttonText: 'Save', - submitFn: async (value: string) => await this.setDbValue('name', value || this.patch.data['server-info'].id), + submitFn: async (value: string) => await this.setDbValue('name', value || this.defaultName), }, cssClass: 'alertlike-modal', presentingElement: await this.modalCtrl.getTop(), diff --git a/ui/src/app/pages/server-routes/server-show/server-show.page.html b/ui/src/app/pages/server-routes/server-show/server-show.page.html index ceb557604..e2d010f5d 100644 --- a/ui/src/app/pages/server-routes/server-show/server-show.page.html +++ b/ui/src/app/pages/server-routes/server-show/server-show.page.html @@ -1,6 +1,6 @@ - {{ patch.data.ui.name || patch.data['server-info'].id }} + {{ patch.data.ui.name || "Embassy-" + patch.data['server-info'].id }} diff --git a/ui/src/app/pages/server-routes/server-show/server-show.page.ts b/ui/src/app/pages/server-routes/server-show/server-show.page.ts index 8c145e297..36b1e8820 100644 --- a/ui/src/app/pages/server-routes/server-show/server-show.page.ts +++ b/ui/src/app/pages/server-routes/server-show/server-show.page.ts @@ -162,7 +162,7 @@ export class ServerShowPage { 'Power': [ { title: 'Restart', - icon: 'reload-outline', + icon: 'reload', action: () => this.presentAlertRestart(), detail: false, }, diff --git a/ui/src/app/services/api/api.fixures.ts b/ui/src/app/services/api/api.fixures.ts index aae75cdcb..3138588a9 100644 --- a/ui/src/app/services/api/api.fixures.ts +++ b/ui/src/app/services/api/api.fixures.ts @@ -262,9 +262,11 @@ export module Mock { dependencies: { 'bitcoind': { version: '=0.21.0', + requirement: { + type: 'opt-out', + how: 'You can use an external node if you prefer.', + }, description: 'LND needs bitcoin to live.', - optional: null, - recommended: true, critical: true, config: { check: { @@ -294,8 +296,10 @@ export module Mock { 'bitcoin-proxy': { version: '>=0.2.2', description: 'As long as Bitcoin is pruned, LND needs Bitcoin Proxy to fetch block over the P2P network.', - optional: null, - recommended: true, + requirement: { + type: 'opt-in', + how: 'You can choose to use Bitcoin Proxy for permission management', + }, critical: true, config: { check: { @@ -410,8 +414,9 @@ export module Mock { 'bitcoind': { version: '>=0.20.0', description: 'Bitcoin Proxy requires a Bitcoin node.', - optional: null, - recommended: true, + requirement: { + type: 'required', + }, critical: false, config: { check: { diff --git a/ui/src/app/services/patch-db/data-model.ts b/ui/src/app/services/patch-db/data-model.ts index 8784106fd..999aca90a 100644 --- a/ui/src/app/services/patch-db/data-model.ts +++ b/ui/src/app/services/patch-db/data-model.ts @@ -344,8 +344,15 @@ export interface DependencyInfo { export interface DependencyEntry { version: string - optional: string | null - recommended: boolean + requirement: { + type: 'opt-in' + how: string + } | { + type: 'opt-out' + how: string + } | { + type: 'required' + } description: string | null critical: boolean, config: { diff --git a/ui/src/app/services/startup-alerts.service.ts b/ui/src/app/services/startup-alerts.service.ts index 19bc1bfd6..e3765fd84 100644 --- a/ui/src/app/services/startup-alerts.service.ts +++ b/ui/src/app/services/startup-alerts.service.ts @@ -38,21 +38,18 @@ export class StartupAlertsService { shouldRun: () => this.shouldRunOsWelcome(), check: async () => true, display: () => this.displayOsWelcome(), - hasRun: this.config.skipStartupAlerts, } const osUpdate: Check = { name: 'osUpdate', shouldRun: () => this.shouldRunOsUpdateCheck(), check: () => this.osUpdateCheck(), display: pkg => this.displayOsUpdateCheck(pkg), - hasRun: this.config.skipStartupAlerts, } const pkgsUpdate: Check = { name: 'pkgsUpdate', shouldRun: () => this.shouldRunAppsCheck(), check: () => this.appsCheck(), display: () => this.displayAppsCheck(), - hasRun: this.config.skipStartupAlerts, } this.checks = [osWelcome, osUpdate, pkgsUpdate] } @@ -70,7 +67,7 @@ export class StartupAlertsService { .subscribe(async data => { this.data = data await this.checks - .filter(c => !c.hasRun && c.shouldRun()) + .filter(c => !this.config.skipStartupAlerts && c.shouldRun()) // returning true in the below block means to continue to next modal // returning false means to skip all subsequent modals .reduce(async (previousDisplay, c) => { @@ -81,7 +78,7 @@ export class StartupAlertsService { console.error(`Exception in ${c.name} check:`, e) return true } - c.hasRun = true + const displayRes = await previousDisplay if (!checkRes) return true @@ -113,8 +110,8 @@ export class StartupAlertsService { } private async appsCheck (): Promise { - await this.marketplaceService.getUpdates(this.data['package-data']) - return !!this.marketplaceService.updates.length + const updates = await this.marketplaceService.getUpdates(this.data['package-data']) + return !!updates.length } private async displayOsWelcome (): Promise { @@ -220,8 +217,6 @@ type Check = { // display an alert based on the result of the check. // return false if subsequent modals should not be displayed display: (a: T) => Promise - // tracks if this check has run in this app instance. - hasRun: boolean // for logging purposes name: string } \ No newline at end of file