mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
fix marketplace dependency show and chaching
This commit is contained in:
committed by
Aiden McClelland
parent
a3e307dd38
commit
d92bccdc45
@@ -68,7 +68,7 @@
|
||||
<ion-icon name="arrow-up"></ion-icon>
|
||||
<ion-icon name="briefcase-outline"></ion-icon>
|
||||
<ion-icon name="bookmark-outline"></ion-icon>
|
||||
<ion-icon name="checkmark-outline"></ion-icon>
|
||||
<ion-icon name="checkmark"></ion-icon>
|
||||
<ion-icon name="chevron-down"></ion-icon>
|
||||
<ion-icon name="chevron-up"></ion-icon>
|
||||
<ion-icon name="chevron-forward"></ion-icon> <!-- needed for detail="true" on ion-item button -->
|
||||
@@ -106,8 +106,8 @@
|
||||
<ion-icon name="qr-code-outline"></ion-icon>
|
||||
<ion-icon name="receipt-outline"></ion-icon>
|
||||
<ion-icon name="refresh"></ion-icon>
|
||||
<ion-icon name="reload-outline"></ion-icon>
|
||||
<ion-icon name="remove-outline"></ion-icon>
|
||||
<ion-icon name="reload"></ion-icon>
|
||||
<ion-icon name="remove"></ion-icon>
|
||||
<ion-icon name="save-outline"></ion-icon>
|
||||
<ion-icon name="shield-checkmark-outline"></ion-icon>
|
||||
<ion-icon name="storefront-outline"></ion-icon>
|
||||
|
||||
@@ -63,13 +63,13 @@
|
||||
<ion-item *ngFor="let health of healthChecks | keyvalue : asIsOrder">
|
||||
<ng-container *ngIf="$any(health.value).result as result">
|
||||
<ion-spinner class="icon-spinner" color="warning" slot="start" *ngIf="['starting', 'loading'] | includes : result"></ion-spinner>
|
||||
<ion-icon slot="start" *ngIf="result === 'success'" name="checkmark-outline" color="success"></ion-icon>
|
||||
<ion-icon slot="start" *ngIf="result === 'failure'" name="close" color="danger"></ion-icon>
|
||||
<ion-icon slot="start" *ngIf="result === 'disabled'" name="remove-outline" color="dark"></ion-icon>
|
||||
<ion-icon slot="start" *ngIf="result === 'success'" name="checkmark" color="success"></ion-icon>
|
||||
<ion-icon slot="start" *ngIf="result === 'failure'" name="warning" color="warning"></ion-icon>
|
||||
<ion-icon slot="start" *ngIf="result === 'disabled'" name="remove" color="dark"></ion-icon>
|
||||
<ion-label>
|
||||
<p>{{ health.key }}</p>
|
||||
<h2>{{ result }}</h2>
|
||||
<p *ngIf="result === 'failure'"><ion-text color="danger">{{ $any(health.value).error }}</ion-text></p>
|
||||
<h2 style="font-weight: bold;">{{ health.key }}</h2>
|
||||
<h2>Result: {{ result | titlecase }}</h2>
|
||||
<p *ngIf="result === 'failure'"><ion-text color="warning">{{ $any(health.value).error }}</ion-text></p>
|
||||
</ion-label>
|
||||
</ng-container>
|
||||
</ion-item>
|
||||
@@ -84,9 +84,14 @@
|
||||
<img [src]="dep.value.icon" />
|
||||
</ion-thumbnail>
|
||||
<ion-label>
|
||||
<h2 style="font-family: 'Montserrat'">{{ dep.value.title }}</h2>
|
||||
<h2 class="inline" style="font-family: 'Montserrat'">
|
||||
<ion-icon *ngIf="!!dep.value.errorText" slot="start" name="warning" color="warning"></ion-icon>
|
||||
{{ dep.value.title }}
|
||||
</h2>
|
||||
<p>{{ dep.value.version | displayEmver }}</p>
|
||||
<p><ion-text [color]="!!dep.value.errorText ? 'warning' : 'success'">{{ dep.value.errorText || 'satisfied' }}</ion-text></p>
|
||||
<p>
|
||||
<ion-text [color]="!!dep.value.errorText ? 'warning' : 'success'">{{ dep.value.errorText || 'satisfied' }}</ion-text>
|
||||
</p>
|
||||
</ion-label>
|
||||
<ion-spinner *ngIf="dep.value.spinnerColor" slot="end" [color]="dep.value.spinnerColor" style="height: 3vh; width: 3vh"></ion-spinner>
|
||||
<ion-button *ngIf="dep.value.actionText" slot="end" fill="clear">
|
||||
|
||||
@@ -11,4 +11,14 @@
|
||||
.icon-spinner {
|
||||
height: 20px;
|
||||
width: 20px;
|
||||
}
|
||||
|
||||
.inline {
|
||||
* {
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
}
|
||||
ion-icon {
|
||||
padding-right: 4px;
|
||||
}
|
||||
}
|
||||
@@ -391,7 +391,7 @@ export class AppShowPage {
|
||||
},
|
||||
{
|
||||
action: () => this.donate(),
|
||||
title: `Donate to ${this.pkg.manifest.title}`,
|
||||
title: 'Donate',
|
||||
icon: 'logo-bitcoin',
|
||||
color: 'danger',
|
||||
},
|
||||
|
||||
@@ -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 () {
|
||||
|
||||
@@ -11,19 +11,22 @@
|
||||
|
||||
<ion-grid style="padding-bottom: 32px;">
|
||||
<ion-row>
|
||||
<ion-col sizeMd="6" offset-md="3">
|
||||
<ion-col sizeSm="8" offset-sm="2">
|
||||
<ion-toolbar color="transparent">
|
||||
<ion-searchbar enterkeyhint="search" color="dark" (keyup.enter)="search()" debounce="300" [(ngModel)]="query"></ion-searchbar>
|
||||
<ion-button style="height: 42px;" slot="end" color="primary" fill="solid" (click)="search()">
|
||||
<ion-icon slot="icon-only" name="search-outline"></ion-icon>
|
||||
</ion-button>
|
||||
<ion-searchbar
|
||||
enterkeyhint="search"
|
||||
color="dark"
|
||||
debounce="250"
|
||||
[(ngModel)]="query"
|
||||
(ionChange)="search()"
|
||||
></ion-searchbar>
|
||||
</ion-toolbar>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
|
||||
<!-- page loading -->
|
||||
<ng-container *ngIf="pageLoading; else pageLoaded">
|
||||
<!-- loading -->
|
||||
<ng-container *ngIf="loading; else pageLoaded">
|
||||
<div class="scrollable ion-text-center">
|
||||
<ion-button *ngFor="let cat of ['', '', '', '', '', '', '']" fill="clear">
|
||||
<ion-skeleton-text animated style="width: 80px; border-radius: 0;"></ion-skeleton-text>
|
||||
@@ -33,11 +36,11 @@
|
||||
<div class="divider" style="margin: 24px 0;"></div>
|
||||
</ng-container>
|
||||
|
||||
<!-- page loaded -->
|
||||
<!-- loaded -->
|
||||
<ng-template #pageLoaded>
|
||||
<div class="scrollable ion-text-center">
|
||||
<ion-button
|
||||
*ngFor="let cat of data.categories"
|
||||
*ngFor="let cat of categories"
|
||||
fill="clear"
|
||||
[class]="cat === category ? 'selected' : 'dim'"
|
||||
(click)="switchCategory(cat)"
|
||||
@@ -49,8 +52,8 @@
|
||||
<div class="divider" style="margin: 24px;"></div>
|
||||
</ng-template>
|
||||
|
||||
<!-- packages loading -->
|
||||
<ng-container *ngIf="pkgsLoading; else pkgsLoaded">
|
||||
<!-- loading -->
|
||||
<ng-container *ngIf="loading; else pkgsLoaded">
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col *ngFor="let pkg of ['', '', '', '']" sizeXs="12" sizeSm="12" sizeMd="6">
|
||||
@@ -73,15 +76,15 @@
|
||||
<ng-template #pkgsLoaded>
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col *ngIf="eos && category === 'featured'" sizeXs="12" sizeSm="12" sizeMd="6">
|
||||
<ion-col *ngIf="marketplaceService.eos && category === 'featured'" sizeXs="12" sizeSm="12" sizeMd="6">
|
||||
<ion-item button class="eos-item" (click)="updateEos()">
|
||||
<ion-thumbnail slot="start">
|
||||
<img src="assets/img/icon.png" />
|
||||
</ion-thumbnail>
|
||||
<ion-label>
|
||||
<h3>Now Available...</h3>
|
||||
<h2>Embassy OS {{ eos.version }}</h2>
|
||||
<p>{{ eos.headline }}</p>
|
||||
<h2>Embassy OS {{ marketplaceService.eos.version }}</h2>
|
||||
<p>{{ marketplaceService.eos.headline }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
|
||||
@@ -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<void> {
|
||||
// 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<void> {
|
||||
this.category = category
|
||||
this.query = undefined
|
||||
this.filterPkgs()
|
||||
}
|
||||
|
||||
async updateEos (): Promise<void> {
|
||||
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<void> {
|
||||
private async filterPkgs (): Promise<void> {
|
||||
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<void> {
|
||||
this.category = category
|
||||
this.query = undefined
|
||||
await this.getPkgs()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,192 +12,190 @@
|
||||
<text-spinner *ngIf="loading; else loaded" text="Loading Package"></text-spinner>
|
||||
|
||||
<ng-template #loaded>
|
||||
<ng-container *ngIf="marketplaceService.pkgs[pkgId] as pkg">
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col sizeXs="12" sizeSm="12" sizeMd="9" sizeLg="9" sizeXl="9">
|
||||
<div class="header">
|
||||
<img [src]="pkg.icon" />
|
||||
<div class="header-text">
|
||||
<h1 class="header-title">{{ pkg.manifest.title }}</h1>
|
||||
<p class="header-version">{{ pkg.manifest.version | displayEmver }}</p>
|
||||
<div class="header-status">
|
||||
<!-- no localPkg -->
|
||||
<p *ngIf="!localPkg; else local">
|
||||
Not Installed
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col sizeXs="12" sizeSm="12" sizeMd="9" sizeLg="9" sizeXl="9">
|
||||
<div class="header">
|
||||
<img [src]="pkg.icon" />
|
||||
<div class="header-text">
|
||||
<h1 class="header-title">{{ pkg.manifest.title }}</h1>
|
||||
<p class="header-version">{{ pkg.manifest.version | displayEmver }}</p>
|
||||
<div class="header-status">
|
||||
<!-- no localPkg -->
|
||||
<p *ngIf="!localPkg; else local">Not Installed</p>
|
||||
<!-- localPkg -->
|
||||
<ng-template #local>
|
||||
<!-- installed -->
|
||||
<p *ngIf="localPkg.state === PackageState.Installed">
|
||||
<ion-text *ngIf="(pkg.manifest.version | compareEmver : localPkg.manifest.version) === 0" color="success">Installed</ion-text>
|
||||
<ion-text *ngIf="(pkg.manifest.version | compareEmver : localPkg.manifest.version) === 1" color="warning">Update Available</ion-text>
|
||||
</p>
|
||||
<!-- localPkg -->
|
||||
<ng-template #local>
|
||||
<!-- installed -->
|
||||
<p *ngIf="localPkg.state === PackageState.Installed">
|
||||
<ion-text *ngIf="(pkg.manifest.version | compareEmver : localPkg.manifest.version) === 0" color="success">Installed</ion-text>
|
||||
<ion-text *ngIf="(pkg.manifest.version | compareEmver : localPkg.manifest.version) === 1" color="warning">Update Available</ion-text>
|
||||
</p>
|
||||
<!-- installing, updating -->
|
||||
<p *ngIf="[PackageState.Installing, PackageState.Updating] | includes : localPkg.state">
|
||||
<ion-text color="primary">{{ localPkg.state | titlecase }}...{{ (localPkg['install-progress'] | installState).totalProgress }}%</ion-text>
|
||||
</p>
|
||||
<!-- removing -->
|
||||
<p *ngIf="localPkg.state === PackageState.Removing">
|
||||
<ion-text color="warning">{{ localPkg.state | titlecase }}</ion-text>
|
||||
<ion-spinner name="dots" color="warning"></ion-spinner>
|
||||
</p>
|
||||
</ng-template>
|
||||
</div>
|
||||
<!-- installing, updating -->
|
||||
<p *ngIf="[PackageState.Installing, PackageState.Updating] | includes : localPkg.state">
|
||||
<ion-text color="primary">{{ localPkg.state | titlecase }}...{{ (localPkg['install-progress'] | installState).totalProgress }}%</ion-text>
|
||||
</p>
|
||||
<!-- removing -->
|
||||
<p *ngIf="localPkg.state === PackageState.Removing">
|
||||
<ion-text color="warning">{{ localPkg.state | titlecase }}</ion-text>
|
||||
<ion-spinner name="dots" color="warning"></ion-spinner>
|
||||
</p>
|
||||
</ng-template>
|
||||
</div>
|
||||
</div>
|
||||
</ion-col>
|
||||
<ion-col sizeXl="3" sizeLg="3" sizeMd="3" sizeSm="12" sizeXs="12" class="ion-align-self-center">
|
||||
<!-- no localPkg -->
|
||||
<ion-button *ngIf="!localPkg" expand="block" (click)="tryInstall()">
|
||||
Install
|
||||
</ion-button>
|
||||
<!-- localPkg -->
|
||||
<ng-container *ngIf="localPkg">
|
||||
<!-- not installing, updating, or removing -->
|
||||
<ng-container *ngIf="localPkg.state === PackageState.Installed">
|
||||
<ion-button *ngIf="(localPkg.manifest.version | compareEmver : pkg.manifest.version) === -1" expand="block" (click)="presentModal('update')">
|
||||
Update
|
||||
</ion-button>
|
||||
<ion-button *ngIf="(localPkg.manifest.version | compareEmver : pkg.manifest.version) === 1" expand="block" color="warning" (click)="presentModal('downgrade')">
|
||||
Downgrade
|
||||
</ion-button>
|
||||
</ng-container>
|
||||
</div>
|
||||
</ion-col>
|
||||
<ion-col sizeXl="3" sizeLg="3" sizeMd="3" sizeSm="12" sizeXs="12" class="ion-align-self-center">
|
||||
<!-- no localPkg -->
|
||||
<ion-button *ngIf="!localPkg" expand="block" (click)="tryInstall()">
|
||||
Install
|
||||
</ion-button>
|
||||
<!-- localPkg -->
|
||||
<ng-container *ngIf="localPkg">
|
||||
<!-- not installing, updating, or removing -->
|
||||
<ng-container *ngIf="localPkg.state === PackageState.Installed">
|
||||
<ion-button *ngIf="(localPkg.manifest.version | compareEmver : pkg.manifest.version) === -1" expand="block" (click)="presentModal('update')">
|
||||
Update
|
||||
</ion-button>
|
||||
<ion-button *ngIf="(localPkg.manifest.version | compareEmver : pkg.manifest.version) === 1" expand="block" color="warning" (click)="presentModal('downgrade')">
|
||||
Downgrade
|
||||
</ion-button>
|
||||
</ng-container>
|
||||
</ng-container>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row *ngIf="localPkg">
|
||||
<ion-col sizeXl="3" sizeLg="3" sizeMd="3" sizeSm="12" sizeXs="12" class="ion-align-self-center">
|
||||
<ion-button expand="block" fill="outline" color="primary" [routerLink]="['/services', pkg.manifest.id]">
|
||||
View Service
|
||||
</ion-button>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
|
||||
<!-- recommendation -->
|
||||
<ion-item *ngIf="rec && showRec" class="rec-item">
|
||||
<ion-label>
|
||||
<h2 style="display: flex; align-items: center;">
|
||||
<ion-thumbnail style="height: 3vh; width: 3vh; margin: 5px" slot="start">
|
||||
<img [src]="rec.dependentIcon" [alt]="rec.dependentTitle"/>
|
||||
</ion-thumbnail>
|
||||
<ion-text style="margin: 5px; font-family: 'Montserrat'; font-size: smaller;">{{ rec.dependentTitle }}</ion-text>
|
||||
</h2>
|
||||
<div style="margin: 7px 5px;">
|
||||
<p style="color: var(--ion-color-dark); font-size: small">{{ rec.description }}</p>
|
||||
<p *ngIf="pkg.manifest.version | satisfiesEmver: rec.version" class="recommendation-text">{{ pkg.manifest.title }} version {{ pkg.manifest.version | displayEmver }} is compatible.</p>
|
||||
<p *ngIf="!(pkg.manifest.version | satisfiesEmver: rec.version)" class="recommendation-text recommendation-error">{{ pkg.manifest.title }} version {{ pkg.manifest.version | displayEmver }} is NOT compatible.</p>
|
||||
<ion-button style="position: absolute; right: 0; top: 0" fill="clear" (click)="dismissRec()">
|
||||
<ion-icon name="close"></ion-icon>
|
||||
</ion-button>
|
||||
</div>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-item-group>
|
||||
<!-- release notes -->
|
||||
<ion-item-divider>
|
||||
New in {{ pkg.manifest.version | displayEmver }}
|
||||
<ion-button [routerLink]="['notes']" style="position: absolute; right: 10px;" fill="clear" color="dark">
|
||||
All Release Notes
|
||||
<ion-icon slot="end" name="arrow-forward-outline"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-item-divider>
|
||||
<ion-item lines="none" color="transparent">
|
||||
<ion-label>
|
||||
<div id='release-notes' [innerHTML]="pkg.manifest['release-notes'] | markdown"></div>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<!-- description -->
|
||||
<ion-item-divider>Description</ion-item-divider>
|
||||
<ion-item lines="none" color="transparent">
|
||||
<ion-label>
|
||||
<div id="release-notes" class="release-notes">{{ pkg.manifest.description.long }}</div>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<!-- dependencies -->
|
||||
<ng-container *ngIf="!(pkg.manifest.dependencies | empty)">
|
||||
<ion-item-divider>Dependencies</ion-item-divider>
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col *ngFor="let dep of pkg.manifest.dependencies | keyvalue" sizeSm="12" sizeMd="6">
|
||||
<ion-item [routerLink]="['/marketplace', dep.key]">
|
||||
<ion-thumbnail slot="start">
|
||||
<img [src]="pkg['dependency-metadata'][dep.key].icon" />
|
||||
</ion-thumbnail>
|
||||
<ion-label>
|
||||
<h2>
|
||||
{{ pkg['dependency-metadata'][dep.key].title }}
|
||||
<span *ngIf="dep.value.requirement.type === 'required'"> (required)</span>
|
||||
<span *ngIf="dep.value.requirement.type === 'opt-out'"> (required by default)</span>
|
||||
<span *ngIf="dep.value.requirement.type === 'opt-in'"> (optional)</span>
|
||||
</h2>
|
||||
<p style="font-size: small">{{ dep.value.version | displayEmver }}</p>
|
||||
<p>{{ dep.value.description }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ng-container>
|
||||
</ion-item-group>
|
||||
|
||||
<ion-item-divider>Additional Info</ion-item-divider>
|
||||
<ion-card>
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col sizeSm="12" sizeMd="6">
|
||||
<ion-item-group>
|
||||
<ion-item button detail="false" (click)="presentAlertVersions()">
|
||||
<ion-label>
|
||||
<h2>Other Versions</h2>
|
||||
<p>Click to view other versions</p>
|
||||
</ion-label>
|
||||
<ion-icon slot="end" name="chevron-forward-outline"></ion-icon>
|
||||
</ion-item>
|
||||
<ion-item button detail="false" (click)="presentModalMd('license')">
|
||||
<ion-label>
|
||||
<h2>License</h2>
|
||||
<p>{{ pkg.manifest.license }}</p>
|
||||
</ion-label>
|
||||
<ion-icon slot="end" name="chevron-forward-outline"></ion-icon>
|
||||
</ion-item>
|
||||
<ion-item button detail="false" (click)="presentModalMd('instructions')">
|
||||
<ion-label>
|
||||
<h2>Instructions</h2>
|
||||
<p>Click to view instructions</p>
|
||||
</ion-label>
|
||||
<ion-icon slot="end" name="chevron-forward-outline"></ion-icon>
|
||||
</ion-item>
|
||||
</ion-item-group>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
<ion-row *ngIf="localPkg">
|
||||
<ion-col sizeXl="3" sizeLg="3" sizeMd="3" sizeSm="12" sizeXs="12" class="ion-align-self-center">
|
||||
<ion-button expand="block" fill="outline" color="primary" [routerLink]="['/services', pkg.manifest.id]">
|
||||
View Service
|
||||
</ion-button>
|
||||
<ion-col sizeSm="12" sizeMd="6">
|
||||
<ion-item-group>
|
||||
<ion-item [href]="pkg.manifest['upstream-repo']" target="_blank" rel="noreferrer" detail="false">
|
||||
<ion-label>
|
||||
<h2>Source Repository</h2>
|
||||
<p>{{ pkg.manifest['upstream-repo'] }}</p>
|
||||
</ion-label>
|
||||
<ion-icon slot="end" name="open-outline"></ion-icon>
|
||||
</ion-item>
|
||||
<ion-item [href]="pkg.manifest['wrapper-repo']" target="_blank" rel="noreferrer" detail="false">
|
||||
<ion-label>
|
||||
<h2>Wrapper Repository</h2>
|
||||
<p>{{ pkg.manifest['wrapper-repo'] }}</p>
|
||||
</ion-label>
|
||||
<ion-icon slot="end" name="open-outline"></ion-icon>
|
||||
</ion-item>
|
||||
<ion-item [href]="pkg.manifest['support-site']" target="_blank" rel="noreferrer" detail="false">
|
||||
<ion-label>
|
||||
<h2>Support Site</h2>
|
||||
<p>{{ pkg.manifest['support-site'] }}</p>
|
||||
</ion-label>
|
||||
<ion-icon slot="end" name="open-outline"></ion-icon>
|
||||
</ion-item>
|
||||
</ion-item-group>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
|
||||
<!-- recommendation -->
|
||||
<ion-item *ngIf="rec && showRec" class="rec-item">
|
||||
<ion-label>
|
||||
<h2 style="display: flex; align-items: center;">
|
||||
<ion-thumbnail style="height: 3vh; width: 3vh; margin: 5px" slot="start">
|
||||
<img [src]="rec.dependentIcon" [alt]="rec.dependentTitle"/>
|
||||
</ion-thumbnail>
|
||||
<ion-text style="margin: 5px; font-family: 'Montserrat'; font-size: smaller;">{{ rec.dependentTitle }}</ion-text>
|
||||
</h2>
|
||||
<div style="margin: 7px 5px;">
|
||||
<p style="color: var(--ion-color-dark); font-size: small">{{ rec.description }}</p>
|
||||
<p *ngIf="pkg.manifest.version | satisfiesEmver: rec.version" class="recommendation-text">{{ pkg.manifest.title }} version {{ pkg.manifest.version | displayEmver }} is compatible.</p>
|
||||
<p *ngIf="!(pkg.manifest.version | satisfiesEmver: rec.version)" class="recommendation-text recommendation-error">{{ pkg.manifest.title }} version {{ pkg.manifest.version | displayEmver }} is NOT compatible.</p>
|
||||
<ion-button style="position: absolute; right: 0; top: 0" fill="clear" (click)="dismissRec()">
|
||||
<ion-icon name="close"></ion-icon>
|
||||
</ion-button>
|
||||
</div>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-item-group>
|
||||
<!-- release notes -->
|
||||
<ion-item-divider>
|
||||
New in {{ pkg.manifest.version | displayEmver }}
|
||||
<ion-button [routerLink]="['notes']" style="position: absolute; right: 10px;" fill="clear" color="dark">
|
||||
All Release Notes
|
||||
<ion-icon slot="end" name="arrow-forward-outline"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-item-divider>
|
||||
<ion-item lines="none" color="transparent">
|
||||
<ion-label>
|
||||
<div id='release-notes' [innerHTML]="pkg.manifest['release-notes'] | markdown"></div>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<!-- description -->
|
||||
<ion-item-divider>Description</ion-item-divider>
|
||||
<ion-item lines="none" color="transparent">
|
||||
<ion-label>
|
||||
<div id="release-notes" class="release-notes">{{ pkg.manifest.description.long }}</div>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
<!-- dependencies -->
|
||||
<ng-container *ngIf="!(pkg.manifest.dependencies | empty)">
|
||||
<ion-item-divider>Dependencies</ion-item-divider>
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col *ngFor="let dep of pkg.manifest.dependencies | keyvalue" sizeSm="12" sizeMd="6">
|
||||
<ion-item *ngIf="!dep.value.optional" [routerLink]="['/marketplace', dep.key]">
|
||||
<ion-thumbnail slot="start">
|
||||
<img [src]="pkg['dependency-metadata'][dep.key].icon" />
|
||||
</ion-thumbnail>
|
||||
<ion-label>
|
||||
<h2>
|
||||
{{ pkg['dependency-metadata'][dep.key].title }}
|
||||
<span *ngIf="dep.value.recommended"> (recommended)</span>
|
||||
</h2>
|
||||
<p style="font-size: small">{{ dep.value.version | displayEmver }}</p>
|
||||
<p>{{ dep.value.description }}</p>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ng-container>
|
||||
</ion-item-group>
|
||||
|
||||
<ion-item-divider>Additional Info</ion-item-divider>
|
||||
<ion-card>
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col sizeSm="12" sizeMd="6">
|
||||
<ion-item-group>
|
||||
<ion-item button detail="false" (click)="presentAlertVersions()">
|
||||
<ion-label>
|
||||
<h2>Other Versions</h2>
|
||||
<p>Click to view other versions</p>
|
||||
</ion-label>
|
||||
<ion-icon slot="end" name="chevron-forward-outline"></ion-icon>
|
||||
</ion-item>
|
||||
<ion-item button detail="false" (click)="presentModalMd('license')">
|
||||
<ion-label>
|
||||
<h2>License</h2>
|
||||
<p>{{ pkg.manifest.license }}</p>
|
||||
</ion-label>
|
||||
<ion-icon slot="end" name="chevron-forward-outline"></ion-icon>
|
||||
</ion-item>
|
||||
<ion-item button detail="false" (click)="presentModalMd('instructions')">
|
||||
<ion-label>
|
||||
<h2>Instructions</h2>
|
||||
<p>Click to view instructions</p>
|
||||
</ion-label>
|
||||
<ion-icon slot="end" name="chevron-forward-outline"></ion-icon>
|
||||
</ion-item>
|
||||
</ion-item-group>
|
||||
</ion-col>
|
||||
<ion-col sizeSm="12" sizeMd="6">
|
||||
<ion-item-group>
|
||||
<ion-item [href]="pkg.manifest['upstream-repo']" target="_blank" rel="noreferrer" detail="false">
|
||||
<ion-label>
|
||||
<h2>Source Repository</h2>
|
||||
<p>{{ pkg.manifest['upstream-repo'] }}</p>
|
||||
</ion-label>
|
||||
<ion-icon slot="end" name="open-outline"></ion-icon>
|
||||
</ion-item>
|
||||
<ion-item [href]="pkg.manifest['wrapper-repo']" target="_blank" rel="noreferrer" detail="false">
|
||||
<ion-label>
|
||||
<h2>Wrapper Repository</h2>
|
||||
<p>{{ pkg.manifest['wrapper-repo'] }}</p>
|
||||
</ion-label>
|
||||
<ion-icon slot="end" name="open-outline"></ion-icon>
|
||||
</ion-item>
|
||||
<ion-item [href]="pkg.manifest['support-site']" target="_blank" rel="noreferrer" detail="false">
|
||||
<ion-label>
|
||||
<h2>Support Site</h2>
|
||||
<p>{{ pkg.manifest['support-site'] }}</p>
|
||||
</ion-label>
|
||||
<ion-icon slot="end" name="open-outline"></ion-icon>
|
||||
</ion-item>
|
||||
</ion-item-group>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
</ion-card>
|
||||
</ng-container>
|
||||
</ion-card>
|
||||
</ng-template>
|
||||
</ion-content>
|
||||
|
||||
@@ -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<void> {
|
||||
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<void> {
|
||||
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<void> {
|
||||
const loader = await this.loadingCtrl.create({
|
||||
spinner: 'lines',
|
||||
|
||||
@@ -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<void> {
|
||||
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<void> {
|
||||
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<MarketplacePkg[]> {
|
||||
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<void> {
|
||||
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<MarketplacePkg[]> {
|
||||
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<void> {
|
||||
async getPkg (id: string, version?: string): Promise<MarketplacePkg> {
|
||||
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<void> {
|
||||
this.releaseNotes[id] = await this.api.getReleaseNotes({ id })
|
||||
}
|
||||
|
||||
private async getPkgs (page: number, perPage: number) : Promise<MarketplacePkg[]> {
|
||||
const pkgs = await this.api.getMarketplacePkgs({
|
||||
page: String(page),
|
||||
'per-page': String(perPage),
|
||||
})
|
||||
|
||||
return pkgs
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@
|
||||
<ion-item-group>
|
||||
<ion-item button (click)="presentModalName()">
|
||||
<ion-label>{{ fields['name'].name }}</ion-label>
|
||||
<ion-note slot="end">{{ patch.data.ui.name }}</ion-note>
|
||||
<ion-note slot="end">{{ patch.data.ui.name || defaultName }}</ion-note>
|
||||
</ion-item>
|
||||
</ion-item-group>
|
||||
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-title>{{ patch.data.ui.name || patch.data['server-info'].id }}</ion-title>
|
||||
<ion-title>{{ patch.data.ui.name || "Embassy-" + patch.data['server-info'].id }}</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<badge-menu-button></badge-menu-button>
|
||||
</ion-buttons>
|
||||
|
||||
@@ -162,7 +162,7 @@ export class ServerShowPage {
|
||||
'Power': [
|
||||
{
|
||||
title: 'Restart',
|
||||
icon: 'reload-outline',
|
||||
icon: 'reload',
|
||||
action: () => this.presentAlertRestart(),
|
||||
detail: false,
|
||||
},
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -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: {
|
||||
|
||||
@@ -38,21 +38,18 @@ export class StartupAlertsService {
|
||||
shouldRun: () => this.shouldRunOsWelcome(),
|
||||
check: async () => true,
|
||||
display: () => this.displayOsWelcome(),
|
||||
hasRun: this.config.skipStartupAlerts,
|
||||
}
|
||||
const osUpdate: Check<RR.GetMarketplaceEOSRes | undefined> = {
|
||||
name: 'osUpdate',
|
||||
shouldRun: () => this.shouldRunOsUpdateCheck(),
|
||||
check: () => this.osUpdateCheck(),
|
||||
display: pkg => this.displayOsUpdateCheck(pkg),
|
||||
hasRun: this.config.skipStartupAlerts,
|
||||
}
|
||||
const pkgsUpdate: Check<boolean> = {
|
||||
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<boolean> {
|
||||
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<boolean> {
|
||||
@@ -220,8 +217,6 @@ type Check<T> = {
|
||||
// display an alert based on the result of the check.
|
||||
// return false if subsequent modals should not be displayed
|
||||
display: (a: T) => Promise<boolean>
|
||||
// tracks if this check has run in this app instance.
|
||||
hasRun: boolean
|
||||
// for logging purposes
|
||||
name: string
|
||||
}
|
||||
Reference in New Issue
Block a user