mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
bring back startup alerts
This commit is contained in:
committed by
Aiden McClelland
parent
48632271d5
commit
301a19d644
@@ -1,5 +1,5 @@
|
||||
import { DependencyErrorType, DockerIoFormat, Manifest, PackageDataEntry, PackageMainStatus, PackageState, ServerStatus } from 'src/app/services/patch-db/data-model'
|
||||
import { MarketplacePkg, Metric, NotificationLevel, RR, ServerNotification, ServerNotifications } from './api-types'
|
||||
import { MarketplacePkg, Metric, NotificationLevel, RR, ServerNotification, ServerNotifications } from './api.types'
|
||||
|
||||
export module Mock {
|
||||
|
||||
@@ -1,23 +1,23 @@
|
||||
import { HttpService } from '../http.service'
|
||||
import { MockApiService } from './mock-api.service'
|
||||
import { LiveApiService } from './live-api.service'
|
||||
import { MockApiService } from './embassy/embassy-mock-api.service'
|
||||
import { LiveApiService } from './embassy/embassy-live-api.service'
|
||||
import { ConfigService } from '../config.service'
|
||||
import { PatchDbModel } from '../patch-db/patch-db.service'
|
||||
import { MarketplaceLiveApiService } from './marketplace-live-api.service'
|
||||
import { MarketplaceMockApiService } from './marketplace-mock-api.service'
|
||||
import { PatchDbService } from '../patch-db/patch-db.service'
|
||||
import { MarketplaceLiveApiService } from './marketplace/marketplace-live-api.service'
|
||||
import { MarketplaceMockApiService } from './marketplace/marketplace-mock-api.service'
|
||||
|
||||
export function ApiServiceFactory (config: ConfigService, http: HttpService) {
|
||||
if (config.mocks.enabled) {
|
||||
return new MockApiService(config, http)
|
||||
return new MockApiService(http, config)
|
||||
} else {
|
||||
return new LiveApiService(config, http)
|
||||
return new LiveApiService(http, config)
|
||||
}
|
||||
}
|
||||
|
||||
export function MarketplaceApiServiceFactory (config: ConfigService, http: HttpService, patch: PatchDbModel) {
|
||||
export function MarketplaceApiServiceFactory (config: ConfigService, http: HttpService, patch: PatchDbService) {
|
||||
if (config.mocks.enabled) {
|
||||
return new MarketplaceMockApiService(http, patch)
|
||||
return new MarketplaceMockApiService(http, config, patch)
|
||||
} else {
|
||||
return new MarketplaceLiveApiService(http, patch)
|
||||
return new MarketplaceLiveApiService(http, config, patch)
|
||||
}
|
||||
}
|
||||
@@ -167,7 +167,17 @@ export module RR {
|
||||
export type GetMarketplaceEOSReq = { }
|
||||
export type GetMarketplaceEOSRes = MarketplaceEOS
|
||||
|
||||
export type GetMarketplacePackagesReq = { id?: string, version?: string, category?: string, query?: string, page?: string, 'per-page'?: string }
|
||||
export type GetMarketplacePackagesReq = {
|
||||
ids?: string[]
|
||||
id?: string
|
||||
// iff id
|
||||
version?: string
|
||||
// iff !id
|
||||
category?: string
|
||||
query?: string
|
||||
page?: string
|
||||
'per-page'?: string
|
||||
}
|
||||
export type GetMarketplacePackagesRes = MarketplacePkg[]
|
||||
|
||||
export type GetReleaseNotesReq = { id: string }
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Subject, Observable } from 'rxjs'
|
||||
import { Http, Update, Operation, Revision, Source, Store } from 'patch-db-client'
|
||||
import { RR } from './api-types'
|
||||
import { RR } from '../api.types'
|
||||
import { DataModel } from 'src/app/services/patch-db/data-model'
|
||||
|
||||
export abstract class ApiService implements Source<DataModel>, Http<DataModel> {
|
||||
@@ -1,16 +1,16 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { HttpService, Method } from '../http.service'
|
||||
import { ApiService } from './api.service'
|
||||
import { RR } from './api-types'
|
||||
import { HttpService, Method } from '../../http.service'
|
||||
import { ApiService } from './embassy-api.service'
|
||||
import { RR } from '../api.types'
|
||||
import { parsePropertiesPermissive } from 'src/app/util/properties.util'
|
||||
import { ConfigService } from '../config.service'
|
||||
import { ConfigService } from '../../config.service'
|
||||
|
||||
@Injectable()
|
||||
export class LiveApiService extends ApiService {
|
||||
|
||||
constructor (
|
||||
private readonly config: ConfigService,
|
||||
private readonly http: HttpService,
|
||||
private readonly config: ConfigService,
|
||||
) { super() }
|
||||
|
||||
async getStatic (url: string): Promise<string> {
|
||||
@@ -1,22 +1,22 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { pauseFor } from '../../util/misc.util'
|
||||
import { ApiService } from './api.service'
|
||||
import { pauseFor } from '../../../util/misc.util'
|
||||
import { ApiService } from './embassy-api.service'
|
||||
import { PatchOp } from 'patch-db-client'
|
||||
import { PackageDataEntry, PackageMainStatus, PackageState, ServerStatus } from 'src/app/services/patch-db/data-model'
|
||||
import { RR, WithRevision } from './api-types'
|
||||
import { RR, WithRevision } from '../api.types'
|
||||
import { parsePropertiesPermissive } from 'src/app/util/properties.util'
|
||||
import { Mock } from './mock-app-fixures'
|
||||
import { HttpService } from '../http.service'
|
||||
import { Mock } from '../api.fixures'
|
||||
import { HttpService } from '../../http.service'
|
||||
import markdown from 'raw-loader!src/assets/markdown/md-sample.md'
|
||||
import { ConfigService } from '../config.service'
|
||||
import { ConfigService } from '../../config.service'
|
||||
|
||||
@Injectable()
|
||||
export class MockApiService extends ApiService {
|
||||
welcomeAck = false
|
||||
|
||||
constructor (
|
||||
private readonly config: ConfigService,
|
||||
private readonly http: HttpService,
|
||||
private readonly config: ConfigService,
|
||||
) { super() }
|
||||
|
||||
async getStatic (url: string): Promise<string> {
|
||||
@@ -1,24 +0,0 @@
|
||||
import { RR } from './api-types'
|
||||
// import { DataModel } from 'src/app/services/patch-db/data-model'
|
||||
import { DataModel } from '../../../../src/app/services/patch-db/data-model'
|
||||
|
||||
export abstract class MarketplaceApiService {
|
||||
abstract getMarketplaceData (params: RR.GetMarketplaceDataReq): Promise<RR.GetMarketplaceDataRes>
|
||||
|
||||
abstract getEos (params: RR.GetMarketplaceEOSReq): Promise<RR.GetMarketplaceEOSRes>
|
||||
|
||||
abstract getMarketplacePkgs (params: RR.GetMarketplacePackagesReq): Promise<RR.GetMarketplacePackagesRes>
|
||||
|
||||
abstract getReleaseNotes (params: RR.GetReleaseNotesReq): Promise<RR.GetReleaseNotesRes>
|
||||
|
||||
}
|
||||
|
||||
export function getMarketURL (eosOrPackage: 'eos' | 'package', data: DataModel): string {
|
||||
const eosMarketplace = data['server-info']['eos-marketplace']
|
||||
if (eosOrPackage === 'eos') {
|
||||
return eosMarketplace
|
||||
} else {
|
||||
const packageMarketplace = data['server-info']['package-marketplace']
|
||||
return packageMarketplace || eosMarketplace
|
||||
}
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { HttpService } from '../http.service'
|
||||
import { getMarketURL } from './marketplace-api.service'
|
||||
import { RR } from './api-types'
|
||||
import { MarketplaceApiService } from './marketplace-api.service'
|
||||
import { PatchDbModel } from '../patch-db/patch-db.service'
|
||||
|
||||
@Injectable()
|
||||
export class MarketplaceLiveApiService extends MarketplaceApiService {
|
||||
|
||||
constructor (
|
||||
private readonly http: HttpService,
|
||||
private readonly patch: PatchDbModel,
|
||||
) { super() }
|
||||
|
||||
async getMarketplaceData (params: RR.GetMarketplaceDataReq): Promise<RR.GetMarketplaceDataRes> {
|
||||
return this.http.simpleGet<RR.GetMarketplaceDataRes>(getMarketURL('package', this.patch.data), params)
|
||||
}
|
||||
|
||||
async getEos (params: RR.GetMarketplaceEOSReq): Promise<RR.GetMarketplaceEOSRes> {
|
||||
return this.http.simpleGet<RR.GetMarketplaceEOSRes>(getMarketURL('eos', this.patch.data), params)
|
||||
}
|
||||
|
||||
async getMarketplacePkgs (params: RR.GetMarketplacePackagesReq): Promise<RR.GetMarketplacePackagesRes> {
|
||||
return this.http.simpleGet<RR.GetMarketplacePackagesRes>(getMarketURL('package', this.patch.data), params)
|
||||
}
|
||||
|
||||
async getReleaseNotes (params: RR.GetReleaseNotesReq): Promise<RR.GetReleaseNotesRes> {
|
||||
return this.http.simpleGet<RR.GetReleaseNotesRes>(getMarketURL('package', this.patch.data), params)
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
import { RR } from '../api.types'
|
||||
import { ConfigService } from '../../config.service'
|
||||
import { PatchDbService } from '../../patch-db/patch-db.service'
|
||||
|
||||
export abstract class MarketplaceApiService {
|
||||
|
||||
constructor (
|
||||
readonly config: ConfigService,
|
||||
readonly patch: PatchDbService,
|
||||
) { }
|
||||
|
||||
abstract getEos (params: RR.GetMarketplaceEOSReq): Promise<RR.GetMarketplaceEOSRes>
|
||||
|
||||
abstract getMarketplaceData (params: RR.GetMarketplaceDataReq): Promise<RR.GetMarketplaceDataRes>
|
||||
|
||||
abstract getMarketplacePkgs (params: RR.GetMarketplacePackagesReq): Promise<RR.GetMarketplacePackagesRes>
|
||||
|
||||
abstract getReleaseNotes (params: RR.GetReleaseNotesReq): Promise<RR.GetReleaseNotesRes>
|
||||
|
||||
getMarketplaceURL (type: 'eos' | 'package'): string {
|
||||
const eosMarketplace = this.patch.data['server-info']['eos-marketplace'] || this.config.start9Marketplace.clearnet
|
||||
if (type === 'eos') {
|
||||
return eosMarketplace
|
||||
} else {
|
||||
const packageMarketplace = this.patch.data['server-info']['package-marketplace']
|
||||
return packageMarketplace || eosMarketplace
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { HttpService } from '../../http.service'
|
||||
import { RR } from '../api.types'
|
||||
import { MarketplaceApiService } from './marketplace-api.service'
|
||||
import { PatchDbService } from '../../patch-db/patch-db.service'
|
||||
import { ConfigService } from '../../config.service'
|
||||
|
||||
@Injectable()
|
||||
export class MarketplaceLiveApiService extends MarketplaceApiService {
|
||||
|
||||
constructor (
|
||||
private readonly http: HttpService,
|
||||
config: ConfigService,
|
||||
patch: PatchDbService,
|
||||
) {
|
||||
super(config, patch)
|
||||
}
|
||||
|
||||
async getEos (params: RR.GetMarketplaceEOSReq): Promise<RR.GetMarketplaceEOSRes> {
|
||||
return this.http.simpleGet<RR.GetMarketplaceEOSRes>(this.getMarketplaceURL('eos'), params)
|
||||
}
|
||||
|
||||
async getMarketplaceData (params: RR.GetMarketplaceDataReq): Promise<RR.GetMarketplaceDataRes> {
|
||||
return this.http.simpleGet<RR.GetMarketplaceDataRes>(this.getMarketplaceURL('package'), params)
|
||||
}
|
||||
|
||||
async getMarketplacePkgs (params: RR.GetMarketplacePackagesReq): Promise<RR.GetMarketplacePackagesRes> {
|
||||
return this.http.simpleGet<RR.GetMarketplacePackagesRes>(this.getMarketplaceURL('package'), params)
|
||||
}
|
||||
|
||||
async getReleaseNotes (params: RR.GetReleaseNotesReq): Promise<RR.GetReleaseNotesRes> {
|
||||
return this.http.simpleGet<RR.GetReleaseNotesRes>(this.getMarketplaceURL('package'), params)
|
||||
}
|
||||
}
|
||||
@@ -1,62 +1,68 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { pauseFor } from '../../util/misc.util'
|
||||
import { RR } from './api-types'
|
||||
import { Mock } from './mock-app-fixures'
|
||||
import { HttpService } from '../http.service'
|
||||
import { pauseFor } from '../../../util/misc.util'
|
||||
import { RR } from '../api.types'
|
||||
import { Mock } from '../api.fixures'
|
||||
import { HttpService } from '../../http.service'
|
||||
import { MarketplaceApiService } from './marketplace-api.service'
|
||||
import { getMarketURL } from './marketplace-api.service'
|
||||
import { PatchDbModel } from '../patch-db/patch-db.service'
|
||||
import { PatchDbService } from '../../patch-db/patch-db.service'
|
||||
import { ConfigService } from '../../config.service'
|
||||
|
||||
@Injectable()
|
||||
export class MarketplaceMockApiService extends MarketplaceApiService {
|
||||
welcomeAck = false
|
||||
|
||||
constructor (
|
||||
private readonly http: HttpService,
|
||||
private readonly patch: PatchDbModel,
|
||||
) { super() }
|
||||
config: ConfigService,
|
||||
patch: PatchDbService,
|
||||
) {
|
||||
super(config, patch)
|
||||
}
|
||||
|
||||
// marketplace
|
||||
|
||||
async getEos (params: RR.GetMarketplaceEOSReq): Promise<RR.GetMarketplaceEOSRes> {
|
||||
let url = this.getMarketplaceURL('eos')
|
||||
if (this.useLocal(url)) {
|
||||
await pauseFor(2000)
|
||||
return Mock.MarketplaceEos
|
||||
}
|
||||
url = `${url}/sys/version/eos`
|
||||
return this.http.simpleGet<RR.GetMarketplaceEOSRes>(url)
|
||||
}
|
||||
|
||||
async getMarketplaceData (params: RR.GetMarketplaceDataReq): Promise<RR.GetMarketplaceDataRes> {
|
||||
const registryURL = getMarketURL('package', this.patch.data)
|
||||
if (!registryURL) {
|
||||
let url = this.getMarketplaceURL('package')
|
||||
if (this.useLocal(url)) {
|
||||
await pauseFor(2000)
|
||||
return {
|
||||
categories: ['featured', 'bitcoin', 'lightning', 'data', 'messaging', 'social', 'alt coin'],
|
||||
}
|
||||
}
|
||||
const url = `${registryURL}/marketplace/data`
|
||||
url = `${url}/marketplace/data`
|
||||
return this.http.simpleGet<RR.GetMarketplaceDataRes>(url)
|
||||
}
|
||||
|
||||
async getEos (params: RR.GetMarketplaceEOSReq): Promise<RR.GetMarketplaceEOSRes> {
|
||||
const registryURL = getMarketURL('eos', this.patch.data)
|
||||
if (!registryURL) {
|
||||
await pauseFor(2000)
|
||||
return Mock.MarketplaceEos
|
||||
}
|
||||
const url = `${registryURL}/sys/version/eos`
|
||||
return this.http.simpleGet<RR.GetMarketplaceEOSRes>(url)
|
||||
}
|
||||
|
||||
async getMarketplacePkgs (params: RR.GetMarketplacePackagesReq): Promise<RR.GetMarketplacePackagesRes> {
|
||||
const registryURL = getMarketURL('package', this.patch.data)
|
||||
if (!registryURL) {
|
||||
let url = this.getMarketplaceURL('package')
|
||||
if (this.useLocal(url)) {
|
||||
await pauseFor(2000)
|
||||
return Mock.AvailableList
|
||||
}
|
||||
const url = `${registryURL}/marketplace/packages`
|
||||
url = `${url}/marketplace/packages`
|
||||
return this.http.simpleGet<RR.GetMarketplacePackagesRes>(url, params)
|
||||
}
|
||||
|
||||
async getReleaseNotes (params: RR.GetReleaseNotesReq): Promise<RR.GetReleaseNotesRes> {
|
||||
const registryURL = getMarketURL('package', this.patch.data)
|
||||
if (!registryURL) {
|
||||
let url = this.getMarketplaceURL('package')
|
||||
if (this.useLocal(url)) {
|
||||
await pauseFor(2000)
|
||||
return Mock.ReleaseNotes
|
||||
}
|
||||
const url = `${registryURL}/marketplace/release-notes`
|
||||
url = `${url}/marketplace/release-notes`
|
||||
return this.http.simpleGet<RR.GetReleaseNotesRes>(url)
|
||||
}
|
||||
|
||||
private useLocal (url: string): boolean {
|
||||
return !url || this.config.mocks.marketplace
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { BehaviorSubject, Observable } from 'rxjs'
|
||||
import { distinctUntilChanged } from 'rxjs/operators'
|
||||
import { ApiService } from './api/api.service'
|
||||
import { ApiService } from './api/embassy/embassy-api.service'
|
||||
import { Storage } from '@ionic/storage'
|
||||
|
||||
export enum AuthState {
|
||||
|
||||
@@ -19,6 +19,7 @@ type UiConfig = {
|
||||
}
|
||||
mocks: {
|
||||
enabled: boolean
|
||||
marketplace: boolean
|
||||
connection: 'ws' | 'poll'
|
||||
rpcPort: number
|
||||
wsPort: number
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { BehaviorSubject, combineLatest, fromEvent, merge, Subscription } from 'rxjs'
|
||||
import { ConnectionStatus, PatchDbModel } from './patch-db/patch-db.service'
|
||||
import { ConnectionStatus, PatchDbService } from './patch-db/patch-db.service'
|
||||
import { HttpService, Method } from './http.service'
|
||||
import { distinctUntilChanged } from 'rxjs/operators'
|
||||
import { ConfigService } from './config.service'
|
||||
@@ -16,7 +16,7 @@ export class ConnectionService {
|
||||
constructor (
|
||||
private readonly httpService: HttpService,
|
||||
private readonly configService: ConfigService,
|
||||
private readonly patch: PatchDbModel,
|
||||
private readonly patch: PatchDbService,
|
||||
) { }
|
||||
|
||||
watchFailure$ () {
|
||||
|
||||
@@ -2,14 +2,14 @@ import { PollSource, Source, WebsocketSource } from 'patch-db-client'
|
||||
import { ConfigService } from 'src/app/services/config.service'
|
||||
import { DataModel } from './data-model'
|
||||
import { LocalStorageBootstrap } from './local-storage-bootstrap'
|
||||
import { PatchDbModel } from './patch-db.service'
|
||||
import { ApiService } from 'src/app/services/api/api.service'
|
||||
import { PatchDbService } from './patch-db.service'
|
||||
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
|
||||
|
||||
export function PatchDbModelFactory (
|
||||
export function PatchDbServiceFactory (
|
||||
config: ConfigService,
|
||||
bootstrapper: LocalStorageBootstrap,
|
||||
apiService: ApiService,
|
||||
): PatchDbModel {
|
||||
): PatchDbService {
|
||||
|
||||
const { mocks, patchDb: { poll }, isConsulate } = config
|
||||
|
||||
@@ -31,5 +31,5 @@ export function PatchDbModelFactory (
|
||||
}
|
||||
}
|
||||
|
||||
return new PatchDbModel(source, apiService, bootstrapper)
|
||||
return new PatchDbService(source, apiService, bootstrapper)
|
||||
}
|
||||
@@ -2,7 +2,7 @@ import { Inject, Injectable, InjectionToken } from '@angular/core'
|
||||
import { Bootstrapper, PatchDB, Source, Store } from 'patch-db-client'
|
||||
import { BehaviorSubject, Observable, of, Subscription } from 'rxjs'
|
||||
import { catchError, debounceTime, finalize, map, tap } from 'rxjs/operators'
|
||||
import { ApiService } from '../api/api.service'
|
||||
import { ApiService } from '../api/embassy/embassy-api.service'
|
||||
import { DataModel } from './data-model'
|
||||
|
||||
export const PATCH_HTTP = new InjectionToken<Source<DataModel>>('app.config')
|
||||
@@ -18,7 +18,7 @@ export enum ConnectionStatus {
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class PatchDbModel {
|
||||
export class PatchDbService {
|
||||
connectionStatus$ = new BehaviorSubject(ConnectionStatus.Initializing)
|
||||
sequence$: Observable<number>
|
||||
data: DataModel
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { AppConfigValuePage } from '../modals/app-config-value/app-config-value.page'
|
||||
import { ApiService } from './api/api.service'
|
||||
import { ApiService } from './api/embassy/embassy-api.service'
|
||||
import { ConfigSpec } from '../pkg-config/config-types'
|
||||
import { ConfigCursor } from '../pkg-config/config-cursor'
|
||||
import { SSHService } from '../pages/server-routes/developer-routes/dev-ssh-keys/ssh.service'
|
||||
|
||||
@@ -4,60 +4,65 @@ import { wizardModal } from '../components/install-wizard/install-wizard.compone
|
||||
import { WizardBaker } from '../components/install-wizard/prebaked-wizards'
|
||||
import { OSWelcomePage } from '../modals/os-welcome/os-welcome.page'
|
||||
import { displayEmver } from '../pipes/emver.pipe'
|
||||
import { ApiService } from './api/api.service'
|
||||
import { RR } from './api/api.types'
|
||||
import { MarketplaceApiService } from './api/marketplace/marketplace-api.service'
|
||||
import { PatchDbService } from './patch-db/patch-db.service'
|
||||
import { ConfigService } from './config.service'
|
||||
import { Emver } from './emver.service'
|
||||
import { OsUpdateService } from './os-update.service'
|
||||
|
||||
@Injectable({providedIn: 'root' })
|
||||
export class StartupAlertsNotifier {
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class StartupAlertsService {
|
||||
private checks: Check<any>[]
|
||||
|
||||
constructor (
|
||||
private readonly alertCtrl: AlertController,
|
||||
private readonly navCtrl: NavController,
|
||||
private readonly config: ConfigService,
|
||||
private readonly modalCtrl: ModalController,
|
||||
private readonly apiService: ApiService,
|
||||
private readonly marketplaceApi: MarketplaceApiService,
|
||||
private readonly emver: Emver,
|
||||
private readonly osUpdateService: OsUpdateService,
|
||||
private readonly wizardBaker: WizardBaker,
|
||||
private readonly patch: PatchDbService,
|
||||
) {
|
||||
const welcome: Check<S9Server> = {
|
||||
const welcome: Check<boolean> = {
|
||||
name: 'welcome',
|
||||
shouldRun: s => this.shouldRunOsWelcome(s),
|
||||
check: async s => s,
|
||||
display: s => this.displayOsWelcome(s),
|
||||
shouldRun: () => this.shouldRunOsWelcome(),
|
||||
check: async () => true,
|
||||
display: () => this.displayOsWelcome(),
|
||||
hasRun: this.config.skipStartupAlerts,
|
||||
}
|
||||
const osUpdate: Check<ReqRes.GetVersionLatestRes | undefined> = {
|
||||
const osUpdate: Check<RR.GetMarketplaceEOSRes | undefined> = {
|
||||
name: 'osUpdate',
|
||||
shouldRun: s => this.shouldRunOsUpdateCheck(s),
|
||||
check: s => this.osUpdateCheck(s),
|
||||
display: vl => this.displayOsUpdateCheck(vl),
|
||||
shouldRun: () => this.shouldRunOsUpdateCheck(),
|
||||
check: () => this.osUpdateCheck(),
|
||||
display: pkg => this.displayOsUpdateCheck(pkg),
|
||||
hasRun: this.config.skipStartupAlerts,
|
||||
}
|
||||
const apps: Check<boolean> = {
|
||||
name: 'apps',
|
||||
shouldRun: s => this.shouldRunAppsCheck(s),
|
||||
shouldRun: () => this.shouldRunAppsCheck(),
|
||||
check: () => this.appsCheck(),
|
||||
display: () => this.displayAppsCheck(),
|
||||
hasRun: this.config.skipStartupAlerts,
|
||||
}
|
||||
this.checks = [welcome, osUpdate, v1StatusUpdate, apps]
|
||||
this.checks = [welcome, osUpdate, apps]
|
||||
}
|
||||
|
||||
// This takes our three checks and filters down to those that should run.
|
||||
// Then, the reduce fires, quickly iterating through yielding a promise (previousDisplay) to the next element
|
||||
// Each promise fires more or less concurrently, so each c.check(server) is run concurrently
|
||||
// Then, since we await previoudDisplay before c.display(res), each promise executing gets hung awaiting the display of the previous run
|
||||
async runChecks (server: Readonly<S9Server>): Promise<void> {
|
||||
// Then, since we await previousDisplay before c.display(res), each promise executing gets hung awaiting the display of the previous run
|
||||
async runChecks (): Promise<void> {
|
||||
await this.checks
|
||||
.filter(c => !c.hasRun && c.shouldRun(server))
|
||||
.filter(c => !c.hasRun && 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) => {
|
||||
let checkRes: any
|
||||
try {
|
||||
checkRes = await c.check(server)
|
||||
checkRes = await c.check()
|
||||
} catch (e) {
|
||||
console.error(`Exception in ${c.name} check:`, e)
|
||||
return true
|
||||
@@ -70,44 +75,49 @@ export class StartupAlertsNotifier {
|
||||
}, Promise.resolve(true))
|
||||
}
|
||||
|
||||
checks: Check<any>[]
|
||||
|
||||
private shouldRunOsWelcome (s: S9Server): boolean {
|
||||
return !s.welcomeAck && s.versionInstalled === this.config.version
|
||||
private shouldRunOsWelcome (): boolean {
|
||||
const data = this.patch.data
|
||||
return !data.ui['welcome-ack'] && data['server-info'].version === this.config.version
|
||||
}
|
||||
|
||||
private shouldRunAppsCheck (server: S9Server): boolean {
|
||||
return server.autoCheckUpdates
|
||||
private shouldRunOsUpdateCheck (): boolean {
|
||||
return this.patch.data.ui['auto-check-updates']
|
||||
}
|
||||
|
||||
private shouldRunOsUpdateCheck (server: S9Server): boolean {
|
||||
return server.autoCheckUpdates
|
||||
private shouldRunAppsCheck (): boolean {
|
||||
return this.patch.data.ui['auto-check-updates']
|
||||
}
|
||||
|
||||
private async v1StatusCheck (): Promise<V1Status> {
|
||||
return this.apiService.checkV1Status()
|
||||
}
|
||||
private async osUpdateCheck (): Promise<RR.GetMarketplaceEOSRes | undefined> {
|
||||
const res = await this.marketplaceApi.getEos({ })
|
||||
|
||||
private async osUpdateCheck (s: Readonly<S9Server>): Promise<ReqRes.GetVersionLatestRes | undefined> {
|
||||
const res = await this.apiService.getVersionLatest()
|
||||
return this.osUpdateService.updateIsAvailable(s.versionInstalled, res) ? res : undefined
|
||||
if (this.emver.compare(this.patch.data['server-info'].version, res.version) === -1) {
|
||||
return res
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
private async appsCheck (): Promise<boolean> {
|
||||
const availableApps = await this.apiService.getAvailableApps()
|
||||
return !!availableApps.find(
|
||||
app => app.versionInstalled && this.emver.compare(app.versionInstalled, app.versionLatest) === -1,
|
||||
)
|
||||
const pkgs = await this.marketplaceApi.getMarketplacePkgs({
|
||||
ids: Object.keys(this.patch.data['package-data']).filter(id => {
|
||||
return !!this.patch.data['package-data'][id].installed
|
||||
}),
|
||||
})
|
||||
return !!pkgs.find(pkg => {
|
||||
const versionInstalled = this.patch.data['package-data'][pkg.manifest.id].manifest.version
|
||||
return this.emver.compare(versionInstalled, pkg.manifest.version) === -1
|
||||
})
|
||||
}
|
||||
|
||||
private async displayOsWelcome (s: Readonly<S9Server>): Promise<boolean> {
|
||||
private async displayOsWelcome (): Promise<boolean> {
|
||||
return new Promise(async resolve => {
|
||||
const modal = await this.modalCtrl.create({
|
||||
backdropDismiss: false,
|
||||
component: OSWelcomePage,
|
||||
presentingElement: await this.modalCtrl.getTop(),
|
||||
componentProps: {
|
||||
version: s.versionInstalled,
|
||||
version: this.patch.data['server-info'].version,
|
||||
},
|
||||
})
|
||||
|
||||
@@ -118,14 +128,15 @@ export class StartupAlertsNotifier {
|
||||
})
|
||||
}
|
||||
|
||||
private async displayOsUpdateCheck (res: ReqRes.GetVersionLatestRes): Promise<boolean> {
|
||||
const { update } = await this.presentAlertNewOS(res.versionLatest)
|
||||
private async displayOsUpdateCheck (eos: RR.GetMarketplaceEOSRes): Promise<boolean> {
|
||||
const { update } = await this.presentAlertNewOS(eos.version)
|
||||
if (update) {
|
||||
const { cancelled } = await wizardModal(
|
||||
this.modalCtrl,
|
||||
this.wizardBaker.updateOS({
|
||||
version: res.versionLatest,
|
||||
releaseNotes: res.releaseNotes,
|
||||
version: eos.version,
|
||||
headline: eos.headline,
|
||||
releaseNotes: eos['release-notes'],
|
||||
}),
|
||||
)
|
||||
if (cancelled) return true
|
||||
@@ -134,33 +145,6 @@ export class StartupAlertsNotifier {
|
||||
return true
|
||||
}
|
||||
|
||||
private async displayV1Check (s: V1Status): Promise<boolean> {
|
||||
return new Promise(async resolve => {
|
||||
if (s.status !== 'available') return resolve(true)
|
||||
const alert = await this.alertCtrl.create({
|
||||
backdropDismiss: true,
|
||||
header: `EmbassyOS ${s.version} Now Available!`,
|
||||
message: `Version ${s.version} introduces SSD support and a whole lot more.`,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Cancel',
|
||||
role: 'cancel',
|
||||
handler: () => resolve(true),
|
||||
},
|
||||
{
|
||||
text: 'View Instructions',
|
||||
handler: () => {
|
||||
window.open(`https://start9.com/eos-${s.version}`, '_blank')
|
||||
resolve(false)
|
||||
},
|
||||
},
|
||||
],
|
||||
})
|
||||
|
||||
await alert.present()
|
||||
})
|
||||
}
|
||||
|
||||
private async displayAppsCheck (): Promise<boolean> {
|
||||
return new Promise(async resolve => {
|
||||
const alert = await this.alertCtrl.create({
|
||||
@@ -223,9 +207,9 @@ export class StartupAlertsNotifier {
|
||||
|
||||
type Check<T> = {
|
||||
// validates whether a check should run based on server properties
|
||||
shouldRun: (s: S9Server) => boolean
|
||||
shouldRun: () => boolean
|
||||
// executes a check, often requiring api call. It should return a false-y value if there should be no display.
|
||||
check: (s: S9Server) => Promise<T>
|
||||
check: () => Promise<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>
|
||||
Reference in New Issue
Block a user