mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-04-02 05:23:14 +00:00
start9 marketplace config
shift not unshift move eos updates to embassy tab selected id sub roughly working keep name in sync in case of change delete commented code 64 img
This commit is contained in:
committed by
Aiden McClelland
parent
2d4ecd3096
commit
0c0cd9d0a0
File diff suppressed because one or more lines are too long
@@ -64,14 +64,6 @@ export module RR {
|
||||
export type KillSessionsReq = WithExpire<{ ids: string[] }> // sessions.kill
|
||||
export type KillSessionsRes = WithRevision<null>
|
||||
|
||||
// marketplace URLs
|
||||
|
||||
export type SetEosMarketplaceReq = WithExpire<{ url: string }> // marketplace.eos.set
|
||||
export type SetEosMarketplaceRes = WithRevision<null>
|
||||
|
||||
export type SetPackageMarketplaceReq = WithExpire<{ url: string }> // marketplace.package.set
|
||||
export type SetPackageMarketplaceRes = WithRevision<null>
|
||||
|
||||
// password
|
||||
|
||||
export type UpdatePasswordReq = { password: string } // password.set
|
||||
@@ -267,15 +259,11 @@ export module RR {
|
||||
query?: string
|
||||
page?: string
|
||||
'per-page'?: string
|
||||
url?: string
|
||||
}
|
||||
export type GetMarketplacePackagesRes = MarketplacePkg[]
|
||||
|
||||
export type GetReleaseNotesReq = { id: string }
|
||||
export type GetReleaseNotesRes = { [version: string]: string }
|
||||
|
||||
export type GetLatestVersionReq = { ids: string[] }
|
||||
export type GetLatestVersionRes = { [id: string]: string }
|
||||
}
|
||||
|
||||
export type WithExpire<T> = { 'expire-id'?: string } & T
|
||||
|
||||
@@ -113,15 +113,6 @@ export abstract class ApiService implements Source<DataModel>, Http<DataModel> {
|
||||
params: RR.GetReleaseNotesReq,
|
||||
): Promise<RR.GetReleaseNotesRes>
|
||||
|
||||
abstract getLatestVersion(
|
||||
params: RR.GetLatestVersionReq,
|
||||
): Promise<RR.GetLatestVersionRes>
|
||||
|
||||
// protected abstract setPackageMarketplaceRaw (params: RR.SetPackageMarketplaceReq): Promise<RR.SetPackageMarketplaceRes>
|
||||
// setPackageMarketplace = (params: RR.SetPackageMarketplaceReq) => this.syncResponse(
|
||||
// () => this.setPackageMarketplaceRaw(params),
|
||||
// )()
|
||||
|
||||
// password
|
||||
// abstract updatePassword (params: RR.UpdatePasswordReq): Promise<RR.UpdatePasswordRes>
|
||||
|
||||
|
||||
@@ -4,15 +4,22 @@ import { ApiService } from './embassy-api.service'
|
||||
import { RR } from './api.types'
|
||||
import { parsePropertiesPermissive } from 'src/app/util/properties.util'
|
||||
import { PatchDbService } from '../patch-db/patch-db.service'
|
||||
import { ConfigService } from '../config.service'
|
||||
|
||||
@Injectable()
|
||||
export class LiveApiService extends ApiService {
|
||||
private marketplaceUrl: string
|
||||
|
||||
constructor(
|
||||
private readonly http: HttpService,
|
||||
private readonly patch: PatchDbService,
|
||||
private readonly config: ConfigService,
|
||||
) {
|
||||
super()
|
||||
;(window as any).rpcClient = this
|
||||
this.patch.watch$('ui', 'marketplace', 'selected-id').subscribe(id => {
|
||||
this.marketplaceUrl = id
|
||||
})
|
||||
}
|
||||
|
||||
async getStatic(url: string): Promise<string> {
|
||||
@@ -106,10 +113,7 @@ export class LiveApiService extends ApiService {
|
||||
params: {},
|
||||
url?: string,
|
||||
): Promise<T> {
|
||||
if (!url) {
|
||||
const id = this.patch.data.ui.marketplace['selected-id']
|
||||
url = this.patch.data.ui.marketplace.options[id].url
|
||||
}
|
||||
url = url || this.marketplaceUrl
|
||||
const fullURL = `${url}${path}?${new URLSearchParams(params).toString()}`
|
||||
return this.http.rpcRequest({
|
||||
method: 'marketplace.get',
|
||||
@@ -120,25 +124,25 @@ export class LiveApiService extends ApiService {
|
||||
async getEos(
|
||||
params: RR.GetMarketplaceEOSReq,
|
||||
): Promise<RR.GetMarketplaceEOSRes> {
|
||||
return this.http.httpRequest({
|
||||
method: Method.GET,
|
||||
url: '/marketplace/eos/latest',
|
||||
return this.marketplaceProxy(
|
||||
'/eos/latest',
|
||||
params,
|
||||
})
|
||||
this.config.eosMarketplaceUrl,
|
||||
)
|
||||
}
|
||||
|
||||
async getMarketplaceData(
|
||||
params: RR.GetMarketplaceDataReq,
|
||||
url?: string,
|
||||
): Promise<RR.GetMarketplaceDataRes> {
|
||||
return this.marketplaceProxy('/marketplace/package/data', params, url)
|
||||
return this.marketplaceProxy('/package/data', params, url)
|
||||
}
|
||||
|
||||
async getMarketplacePkgs(
|
||||
params: RR.GetMarketplacePackagesReq,
|
||||
): Promise<RR.GetMarketplacePackagesRes> {
|
||||
if (params.query) params.category = undefined
|
||||
return this.marketplaceProxy('/marketplace/package/index', {
|
||||
return this.marketplaceProxy('/package/index', {
|
||||
...params,
|
||||
ids: JSON.stringify(params.ids),
|
||||
})
|
||||
@@ -147,27 +151,9 @@ export class LiveApiService extends ApiService {
|
||||
async getReleaseNotes(
|
||||
params: RR.GetReleaseNotesReq,
|
||||
): Promise<RR.GetReleaseNotesRes> {
|
||||
return this.http.httpRequest({
|
||||
method: Method.GET,
|
||||
url: '/marketplace/package/release-notes',
|
||||
params,
|
||||
})
|
||||
return this.marketplaceProxy('/package/release-notes', params)
|
||||
}
|
||||
|
||||
async getLatestVersion(
|
||||
params: RR.GetLatestVersionReq,
|
||||
): Promise<RR.GetLatestVersionRes> {
|
||||
return this.http.httpRequest({
|
||||
method: Method.GET,
|
||||
url: '/marketplace/latest-version',
|
||||
params,
|
||||
})
|
||||
}
|
||||
|
||||
// async setPackageMarketplaceRaw (params: RR.SetPackageMarketplaceReq): Promise<RR.SetPackageMarketplaceRes> {
|
||||
// return this.http.rpcRequest({ method: 'marketplace.package.set', params })
|
||||
// }
|
||||
|
||||
// password
|
||||
// async updatePassword (params: RR.UpdatePasswordReq): Promise<RR.UpdatePasswordRes> {
|
||||
// return this.http.rpcRequest({ method: 'password.set', params })
|
||||
|
||||
@@ -228,16 +228,6 @@ export class MockApiService extends ApiService {
|
||||
return Mock.ReleaseNotes
|
||||
}
|
||||
|
||||
async getLatestVersion (
|
||||
params: RR.GetLatestVersionReq,
|
||||
): Promise<RR.GetLatestVersionRes> {
|
||||
await pauseFor(2000)
|
||||
return params.ids.reduce((obj, id) => {
|
||||
obj[id] = '1.3.0'
|
||||
return obj
|
||||
}, {})
|
||||
}
|
||||
|
||||
// password
|
||||
// async updatePassword (params: RR.UpdatePasswordReq): Promise<RR.UpdatePasswordRes> {
|
||||
// await pauseFor(2000)
|
||||
|
||||
@@ -16,15 +16,7 @@ export const mockPatchData: DataModel = {
|
||||
'pkg-order': [],
|
||||
'ack-welcome': '1.0.0',
|
||||
'ack-share-stats': false,
|
||||
marketplace: {
|
||||
'selected-id': 'asdfasdf',
|
||||
options: {
|
||||
asdfasdf: {
|
||||
name: 'Start9',
|
||||
url: 'start9marketplace.com',
|
||||
},
|
||||
},
|
||||
},
|
||||
marketplace: undefined,
|
||||
},
|
||||
'server-info': {
|
||||
id: 'embassy-abcdefgh',
|
||||
@@ -439,6 +431,8 @@ export const mockPatchData: DataModel = {
|
||||
},
|
||||
'current-dependencies': {},
|
||||
'dependency-info': {},
|
||||
'marketplace-url': 'marketplace-url.com',
|
||||
'developer-key': 'developer-key',
|
||||
},
|
||||
},
|
||||
lnd: {
|
||||
@@ -644,6 +638,8 @@ export const mockPatchData: DataModel = {
|
||||
icon: 'assets/img/service-icons/btc-rpc-proxy.png',
|
||||
},
|
||||
},
|
||||
'marketplace-url': 'marketplace-url.com',
|
||||
'developer-key': 'developer-key',
|
||||
},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -9,7 +9,7 @@ import { WorkspaceConfig } from '@shared'
|
||||
|
||||
const {
|
||||
useMocks,
|
||||
ui: { gitHash, patchDb, api, mocks },
|
||||
ui: { gitHash, patchDb, api, mocks, eosMarketplaceURL },
|
||||
} = require('../../../../../config.json') as WorkspaceConfig
|
||||
|
||||
@Injectable({
|
||||
@@ -25,6 +25,7 @@ export class ConfigService {
|
||||
gitHash = gitHash
|
||||
patchDb = patchDb
|
||||
api = api
|
||||
eosMarketplaceUrl = eosMarketplaceURL
|
||||
|
||||
skipStartupAlerts = useMocks && mocks.skipStartupAlerts
|
||||
isConsulate = window['platform'] === 'ios'
|
||||
|
||||
33
frontend/projects/ui/src/app/services/eos.service.ts
Normal file
33
frontend/projects/ui/src/app/services/eos.service.ts
Normal file
@@ -0,0 +1,33 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { BehaviorSubject } from 'rxjs'
|
||||
import { MarketplaceEOS } 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 { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class EOSService {
|
||||
eos: MarketplaceEOS
|
||||
updateAvailable$ = new BehaviorSubject<boolean>(false)
|
||||
|
||||
constructor(
|
||||
private readonly api: ApiService,
|
||||
private readonly emver: Emver,
|
||||
private readonly patch: PatchDbService,
|
||||
) {}
|
||||
|
||||
async getEOS(): Promise<void> {
|
||||
this.eos = await this.api.getEos({
|
||||
'eos-version-compat':
|
||||
this.patch.getData()['server-info']['eos-version-compat'],
|
||||
})
|
||||
const updateAvailable =
|
||||
this.emver.compare(
|
||||
this.eos.version,
|
||||
this.patch.data['server-info'].version,
|
||||
) === 1
|
||||
this.updateAvailable$.next(updateAvailable)
|
||||
}
|
||||
}
|
||||
@@ -17,8 +17,8 @@ export interface UIData {
|
||||
}
|
||||
|
||||
export interface UIMarketplaceData {
|
||||
'selected-id': string
|
||||
options: {
|
||||
'selected-id': string | null
|
||||
'known-hosts': {
|
||||
[id: string]: {
|
||||
url: string
|
||||
name: string
|
||||
@@ -94,6 +94,8 @@ export interface InstalledPackageDataEntry {
|
||||
'interface-addresses': {
|
||||
[id: string]: { 'tor-address': string; 'lan-address': string }
|
||||
}
|
||||
'marketplace-url': string | null
|
||||
'developer-key': string
|
||||
}
|
||||
|
||||
export interface CurrentDependencyInfo {
|
||||
|
||||
@@ -1,26 +1,14 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import {
|
||||
AlertController,
|
||||
IonicSafeString,
|
||||
ModalController,
|
||||
NavController,
|
||||
} from '@ionic/angular'
|
||||
import { wizardModal } from '../components/install-wizard/install-wizard.component'
|
||||
import { ModalController } from '@ionic/angular'
|
||||
import { WizardBaker } from '../components/install-wizard/prebaked-wizards'
|
||||
import { OSWelcomePage } from '../modals/os-welcome/os-welcome.page'
|
||||
import { displayEmver } from '../pipes/emver.pipe'
|
||||
import { RR } from './api/api.types'
|
||||
import { ConfigService } from './config.service'
|
||||
import { Emver } from './emver.service'
|
||||
import { MarketplaceService } from '../pages/marketplace-routes/marketplace.service'
|
||||
import { DataModel } from './patch-db/data-model'
|
||||
import { PatchDbService } from './patch-db/patch-db.service'
|
||||
import { filter, take } from 'rxjs/operators'
|
||||
import { isEmptyObject } from '../util/misc.util'
|
||||
import { ApiService } from './api/embassy-api.service'
|
||||
import { Subscription } from 'rxjs'
|
||||
import { ServerConfigService } from './server-config.service'
|
||||
import { v4 } from 'uuid'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
@@ -29,13 +17,9 @@ 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 marketplaceService: MarketplaceService,
|
||||
private readonly api: ApiService,
|
||||
private readonly emver: Emver,
|
||||
private readonly wizardBaker: WizardBaker,
|
||||
private readonly patch: PatchDbService,
|
||||
private readonly serverConfig: ServerConfigService,
|
||||
@@ -43,22 +27,14 @@ export class StartupAlertsService {
|
||||
const osWelcome: Check<boolean> = {
|
||||
name: 'osWelcome',
|
||||
shouldRun: () => this.shouldRunOsWelcome(),
|
||||
check: async () => true,
|
||||
display: () => this.displayOsWelcome(),
|
||||
}
|
||||
const shareStats: Check<boolean> = {
|
||||
name: 'shareStats',
|
||||
shouldRun: () => this.shouldRunShareStats(),
|
||||
check: async () => true,
|
||||
display: () => this.displayShareStats(),
|
||||
}
|
||||
const osUpdate: Check<RR.GetMarketplaceEOSRes | undefined> = {
|
||||
name: 'osUpdate',
|
||||
shouldRun: () => this.shouldRunOsUpdateCheck(),
|
||||
check: () => this.osUpdateCheck(),
|
||||
display: pkg => this.displayOsUpdateCheck(pkg),
|
||||
}
|
||||
this.checks = [osWelcome, shareStats, osUpdate]
|
||||
this.checks = [osWelcome, shareStats]
|
||||
}
|
||||
|
||||
// This takes our three checks and filters down to those that should run.
|
||||
@@ -72,37 +48,14 @@ export class StartupAlertsService {
|
||||
filter(data => !isEmptyObject(data)),
|
||||
take(1),
|
||||
)
|
||||
.subscribe(async data => {
|
||||
if (!data.ui.marketplace) {
|
||||
const uuid = v4()
|
||||
const value = {
|
||||
'selected-id': uuid,
|
||||
options: {
|
||||
[uuid]: {
|
||||
url: 'marketplaceurl.com',
|
||||
name: 'Start9',
|
||||
},
|
||||
},
|
||||
}
|
||||
await this.api.setDbValue({ pointer: 'marketplace', value })
|
||||
}
|
||||
.subscribe(async () => {
|
||||
await this.checks
|
||||
.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) => {
|
||||
let checkRes: any
|
||||
try {
|
||||
checkRes = await c.check()
|
||||
} catch (e) {
|
||||
console.error(`Exception in ${c.name} check:`, e)
|
||||
return true
|
||||
}
|
||||
|
||||
const displayRes = await previousDisplay
|
||||
|
||||
if (!checkRes) return true
|
||||
if (displayRes) return c.display(checkRes)
|
||||
if (displayRes) return c.display()
|
||||
}, Promise.resolve(true))
|
||||
})
|
||||
}
|
||||
@@ -120,21 +73,6 @@ export class StartupAlertsService {
|
||||
return this.patch.getData().ui['auto-check-updates']
|
||||
}
|
||||
|
||||
// ** check **
|
||||
|
||||
private async osUpdateCheck(): Promise<RR.GetMarketplaceEOSRes | undefined> {
|
||||
const res = await this.api.getEos({
|
||||
'eos-version-compat':
|
||||
this.patch.getData()['server-info']['eos-version-compat'],
|
||||
})
|
||||
|
||||
if (this.emver.compare(this.config.version, res.version) === -1) {
|
||||
return res
|
||||
} else {
|
||||
return undefined
|
||||
}
|
||||
}
|
||||
|
||||
// ** display **
|
||||
|
||||
private async displayOsWelcome(): Promise<boolean> {
|
||||
@@ -174,69 +112,14 @@ export class StartupAlertsService {
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
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: eos.version,
|
||||
headline: eos.headline,
|
||||
releaseNotes: eos['release-notes'],
|
||||
}),
|
||||
)
|
||||
if (cancelled) return true
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// more
|
||||
|
||||
private async presentAlertNewOS(
|
||||
versionLatest: string,
|
||||
): Promise<{ cancel?: true; update?: true }> {
|
||||
return new Promise(async resolve => {
|
||||
const alert = await this.alertCtrl.create({
|
||||
header: 'New EmbassyOS Version!',
|
||||
message: new IonicSafeString(
|
||||
`<div style="display: flex; flex-direction: column; justify-content: space-around; min-height: 100px">
|
||||
<div>Update EmbassyOS to version ${displayEmver(
|
||||
versionLatest,
|
||||
)}?</div>
|
||||
<div style="font-size:x-small">You can disable these checks in your Embassy Config</div>
|
||||
</div>
|
||||
`,
|
||||
),
|
||||
buttons: [
|
||||
{
|
||||
text: 'Not now',
|
||||
role: 'cancel',
|
||||
handler: () => resolve({ cancel: true }),
|
||||
},
|
||||
{
|
||||
text: 'Update',
|
||||
handler: () => resolve({ update: true }),
|
||||
cssClass: 'enter-click',
|
||||
},
|
||||
],
|
||||
})
|
||||
await alert.present()
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
type Check<T> = {
|
||||
// validates whether a check should run based on server properties
|
||||
shouldRun: () => boolean
|
||||
// executes a check, often requiring api call. It should return a false-y value if there should be no display.
|
||||
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>
|
||||
display: () => Promise<boolean>
|
||||
// for logging purposes
|
||||
name: string
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user