cleaning up

This commit is contained in:
Matt Hill
2021-08-12 17:20:33 -06:00
committed by Aiden McClelland
parent eb03d1ed04
commit 7aaeefc180
42 changed files with 219 additions and 275 deletions

View File

@@ -15,7 +15,7 @@
"builder": "@angular-devkit/build-angular:browser",
"options": {
"preserveSymlinks": true,
"allowedCommonJsDependencies": ["json-pointer", "ng-qrcode"],
"allowedCommonJsDependencies": ["json-pointer", "qrcode", "ajv", "patch-db-client"],
"outputPath": "www",
"index": "src/index.html",
"main": "src/main.ts",

View File

@@ -1,7 +1,7 @@
import { Component } from '@angular/core'
import { Storage } from '@ionic/storage-angular'
import { AuthService, AuthState } from './services/auth.service'
import { ApiService } from './services/api/embassy/embassy-api.service'
import { ApiService } from './services/api/embassy-api.service'
import { Router, RoutesRecognized } from '@angular/router'
import { debounceTime, distinctUntilChanged, filter, take, takeWhile } from 'rxjs/operators'
import { AlertController, IonicSafeString, LoadingController, ToastController } from '@ionic/angular'
@@ -15,7 +15,6 @@ import { ConnectionFailure, ConnectionService } from './services/connection.serv
import { StartupAlertsService } from './services/startup-alerts.service'
import { ConfigService } from './services/config.service'
import { isEmptyObject } from './util/misc.util'
import { MarketplaceApiService } from './services/api/marketplace/marketplace-api.service'
import { ErrorToastService } from './services/error-toast.service'
@Component({
@@ -62,7 +61,6 @@ export class AppComponent {
private readonly alertCtrl: AlertController,
private readonly emver: Emver,
private readonly connectionService: ConnectionService,
private readonly marketplaceApi: MarketplaceApiService,
private readonly startupAlertsService: StartupAlertsService,
private readonly toastCtrl: ToastController,
private readonly loadingCtrl: LoadingController,
@@ -103,8 +101,6 @@ export class AppComponent {
// start the connection monitor
this.connectionService.start(auth)
// watch connection to display connectivity issues
this.marketplaceApi.init(auth)
// watch connection to display connectivity issues
this.watchConnection(auth)
// // watch router to highlight selected menu item
this.watchRouter(auth)

View File

@@ -7,8 +7,8 @@ import { IonicStorageModule } from '@ionic/storage-angular'
import { HttpClientModule } from '@angular/common/http'
import { AppComponent } from './app.component'
import { AppRoutingModule } from './app-routing.module'
import { ApiService } from './services/api/embassy/embassy-api.service'
import { ApiServiceFactory, MarketplaceApiServiceFactory } from './services/api/api.service.factory'
import { ApiService } from './services/api/embassy-api.service'
import { ApiServiceFactory } from './services/api/api.service.factory'
import { PatchDbServiceFactory } from './services/patch-db/patch-db.factory'
import { HttpService } from './services/http.service'
import { ConfigService } from './services/config.service'
@@ -18,7 +18,6 @@ import { MarkdownPageModule } from './modals/markdown/markdown.module'
import { PatchDbService } from './services/patch-db/patch-db.service'
import { LocalStorageBootstrap } from './services/patch-db/local-storage-bootstrap'
import { SharingModule } from './modules/sharing.module'
import { MarketplaceApiService } from './services/api/marketplace/marketplace-api.service'
import { FormBuilder } from '@angular/forms'
@NgModule({
@@ -46,7 +45,6 @@ import { FormBuilder } from '@angular/forms'
Storage,
{ provide: RouteReuseStrategy, useClass: IonicRouteStrategy },
{ provide: ApiService , useFactory: ApiServiceFactory, deps: [ConfigService, HttpService] }, { provide: ApiService , useFactory: ApiServiceFactory, deps: [ConfigService, HttpService] },
{ provide: MarketplaceApiService , useFactory: MarketplaceApiServiceFactory, deps: [ConfigService, HttpService, PatchDbService, ApiService] },
{ provide: PatchDbService, useFactory: PatchDbServiceFactory, deps: [ConfigService, LocalStorageBootstrap, ApiService] },
],
bootstrap: [AppComponent],

View File

@@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'
import { PackageDataEntry } from 'src/app/services/patch-db/data-model'
import { Breakages } from 'src/app/services/api/api.types'
import { exists } from 'src/app/util/misc.util'
import { ApiService } from '../../services/api/embassy/embassy-api.service'
import { ApiService } from '../../services/api/embassy-api.service'
import { InstallWizardComponent, SlideDefinition, TopbarParams } from './install-wizard.component'
@Injectable({ providedIn: 'root' })

View File

@@ -1,6 +1,6 @@
import { Component, Input, ViewChild } from '@angular/core'
import { AlertController, ModalController, IonContent, LoadingController } from '@ionic/angular'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { isEmptyObject, Recommendation } from 'src/app/util/misc.util'
import { wizardModal } from 'src/app/components/install-wizard/install-wizard.component'
import { WizardBaker } from 'src/app/components/install-wizard/prebaked-wizards'

View File

@@ -1,6 +1,6 @@
import { Component, Input } from '@angular/core'
import { LoadingController, ModalController } from '@ionic/angular'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { BackupConfirmationComponent } from 'src/app/modals/backup-confirmation/backup-confirmation.component'
import { DiskInfo } from 'src/app/services/api/api.types'
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'

View File

@@ -1,6 +1,6 @@
import { Component, Input } from '@angular/core'
import { ModalController } from '@ionic/angular'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { ErrorToastService } from 'src/app/services/error-toast.service'
@Component({

View File

@@ -1,6 +1,6 @@
import { Component, Input, ViewChild } from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { AlertController, IonContent, LoadingController, ModalController, NavController } from '@ionic/angular'
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
import { Action, Manifest, PackageDataEntry, PackageMainStatus } from 'src/app/services/patch-db/data-model'

View File

@@ -2,7 +2,7 @@ import { Component, ViewChild } from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { IonContent } from '@ionic/angular'
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { ErrorToastService } from 'src/app/services/error-toast.service'
@Component({

View File

@@ -1,6 +1,6 @@
import { Component, ViewChild } from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { IonContent } from '@ionic/angular'
import { ErrorToastService } from 'src/app/services/error-toast.service'

View File

@@ -3,7 +3,7 @@ import { ActivatedRoute } from '@angular/router'
import { IonContent } from '@ionic/angular'
import { Subscription } from 'rxjs'
import { Metric } from 'src/app/services/api/api.types'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { ErrorToastService } from 'src/app/services/error-toast.service'
import { MainStatus } from 'src/app/services/patch-db/data-model'
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'

View File

@@ -1,6 +1,6 @@
import { Component, ViewChild } from '@angular/core'
import { ActivatedRoute } from '@angular/router'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { Subscription } from 'rxjs'
import { copyToClipboard } from 'src/app/util/web.util'
import { AlertController, IonContent, NavController, PopoverController, ToastController } from '@ionic/angular'

View File

@@ -1,6 +1,6 @@
import { Component, ViewChild } from '@angular/core'
import { AlertController, NavController, ModalController, IonContent, LoadingController } from '@ionic/angular'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { ActivatedRoute, NavigationExtras } from '@angular/router'
import { isEmptyObject, Recommendation } from 'src/app/util/misc.util'
import { combineLatest, Subscription } from 'rxjs'

View File

@@ -1,6 +1,8 @@
import { Component } from '@angular/core'
import { LoadingController } from '@ionic/angular'
import { Subscription } from 'rxjs'
import { AuthService } from 'src/app/services/auth.service'
import { PatchConnection, PatchDbService } from 'src/app/services/patch-db/patch-db.service'
@Component({
selector: 'login',
@@ -12,17 +14,26 @@ export class LoginPage {
unmasked = false
error = ''
loader: HTMLIonLoadingElement
patchConnectionSub: Subscription
constructor (
private readonly authService: AuthService,
private readonly loadingCtrl: LoadingController,
private readonly patch: PatchDbService,
) { }
ngOnInit () {
}
ngOnDestroy () {
if (this.loader) {
this.loader.dismiss()
this.loader = undefined
}
if (this.patchConnectionSub) {
this.patchConnectionSub.unsubscribe()
}
}
toggleMask () {
@@ -43,6 +54,12 @@ export class LoginPage {
await this.authService.login(this.password)
this.loader.message = 'Loading Embassy Data'
this.password = ''
this.patchConnectionSub = this.patch.watchPatchConnection$().subscribe(status => {
if (status === PatchConnection.Disconnected) {
this.error = 'Connection failed'
this.loader.dismiss()
}
})
} catch (e) {
this.error = e.message
this.loader.dismiss()

View File

@@ -7,7 +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 { MarketplaceApiService } from 'src/app/services/api/marketplace/marketplace-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
@Component({
@@ -39,7 +39,7 @@ export class MarketplaceListPage {
constructor (
private readonly marketplaceService: MarketplaceService,
private readonly marketplaceApi: MarketplaceApiService,
private readonly api: ApiService,
private readonly modalCtrl: ModalController,
private readonly errToast: ErrorToastService,
private readonly wizardBaker: WizardBaker,
@@ -55,8 +55,8 @@ export class MarketplaceListPage {
try {
const [data, eos] = await Promise.all([
this.marketplaceApi.getMarketplaceData({ }),
this.marketplaceApi.getEos({ }),
this.api.getMarketplaceData({ }),
this.api.getEos({ }),
this.getPkgs(),
])
this.eos = eos

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'
import { MarketplacePkg } from 'src/app/services/api/api.types'
import { MarketplaceApiService } from 'src/app/services/api/marketplace/marketplace-api.service'
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'
@@ -15,13 +15,13 @@ export class MarketplaceService {
} } = { }
constructor (
private readonly marketplaceApi: MarketplaceApiService,
private readonly api: ApiService,
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.marketplaceApi.getMarketplacePkgs({
const latestPkgs = (await this.api.getMarketplacePkgs({
ids: idAndCurrentVersions,
}))
@@ -35,7 +35,7 @@ export class MarketplaceService {
}
async getPkgs (category: string, query: string, page: number, perPage: number) : Promise<MarketplacePkg[]> {
const pkgs = await this.marketplaceApi.getMarketplacePkgs({
const pkgs = await this.api.getMarketplacePkgs({
category: category !== 'all' ? category : undefined,
query,
page: String(page),
@@ -49,7 +49,7 @@ export class MarketplaceService {
}
async getPkg (id: string, version?: string): Promise<void> {
const pkgs = await this.marketplaceApi.getMarketplacePkgs({
const pkgs = await this.api.getMarketplacePkgs({
ids: [{ id, version: version || '*' }],
})
const pkg = pkgs[0]
@@ -61,7 +61,7 @@ export class MarketplaceService {
}
async getReleaseNotes (id: string): Promise<void> {
this.releaseNotes[id] = await this.marketplaceApi.getReleaseNotes({ id })
this.releaseNotes[id] = await this.api.getReleaseNotes({ id })
}
}

View File

@@ -1,5 +1,5 @@
import { Component } from '@angular/core'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { ServerNotification, ServerNotifications } from 'src/app/services/api/api.types'
import { AlertController, LoadingController } from '@ionic/angular'
import { ActivatedRoute } from '@angular/router'

View File

@@ -2,7 +2,7 @@ import { Component } from '@angular/core'
import { isPlatform, LoadingController, ToastController } from '@ionic/angular'
import { copyToClipboard } from 'src/app/util/web.util'
import { ConfigService } from 'src/app/services/config.service'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
import { Subscription } from 'rxjs'
import { ErrorToastService } from 'src/app/services/error-toast.service'

View File

@@ -23,8 +23,11 @@
</ion-item>
<ion-item-divider>Other Sessions</ion-item-divider>
<div *ngFor="let session of sessionInfo.sessions | keyvalue : asIsOrder">
<ion-item *ngIf="session.key !== sessionInfo.current">
<div *ngFor="let session of sessionInfo.sessions | keyvalue : asIsOrder;">
<ion-item
[id]="session.key"
*ngIf="session.key !== sessionInfo.current"
>
<ion-icon slot="start" [name]="getPlatformIcon(session.value.metadata.platforms)"></ion-icon>
<ion-label class="ion-text-wrap">
<h1>{{ getPlatformName(session.value.metadata.platforms) }}</h1>

View File

@@ -0,0 +1,4 @@
.hide {
max-height: 0px !important;
transition: max-height .5s ease-out;
}

View File

@@ -1,7 +1,7 @@
import { Component } from '@angular/core'
import { AlertController, LoadingController } from '@ionic/angular'
import { ErrorToastService } from 'src/app/services/error-toast.service'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { PlatformType, RR } from 'src/app/services/api/api.types'
@Component({
@@ -30,7 +30,7 @@ export class SessionsPage {
}
}
async presentAlertKill (hash: string) {
async presentAlertKill (id: string) {
const alert = await this.alertCtrl.create({
backdropDismiss: false,
header: 'Caution',
@@ -43,7 +43,7 @@ export class SessionsPage {
{
text: 'Kill',
handler: () => {
this.kill(hash)
this.kill(id)
},
},
],
@@ -51,7 +51,7 @@ export class SessionsPage {
await alert.present()
}
async kill (hash: string): Promise<void> {
async kill (id: string): Promise<void> {
const loader = await this.loadingCtrl.create({
spinner: 'lines',
message: 'Killing session...',
@@ -60,8 +60,8 @@ export class SessionsPage {
await loader.present()
try {
await this.embassyApi.killSessions({ hashes: [hash] })
delete this.sessionInfo.sessions[hash]
await this.embassyApi.killSessions({ ids: [id] })
delete this.sessionInfo.sessions[id]
} catch (e) {
this.errToast.present(e)
} finally {

View File

@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core'
import { BehaviorSubject } from 'rxjs'
import { SSHKeys } from 'src/app/services/api/api.types'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
@Injectable({
providedIn: 'root',

View File

@@ -1,6 +1,6 @@
import { Component } from '@angular/core'
import { LoadingController, ModalController } from '@ionic/angular'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { BackupConfirmationComponent } from 'src/app/modals/backup-confirmation/backup-confirmation.component'
import { DiskInfo } from 'src/app/services/api/api.types'
import { ErrorToastService } from 'src/app/services/error-toast.service'

View File

@@ -1,5 +1,5 @@
import { Component, ViewChild } from '@angular/core'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { IonContent } from '@ionic/angular'
import { ErrorToastService } from 'src/app/services/error-toast.service'

View File

@@ -1,7 +1,7 @@
import { Component, ViewChild } from '@angular/core'
import { IonContent } from '@ionic/angular'
import { Metrics } from 'src/app/services/api/api.types'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { ErrorToastService } from 'src/app/services/error-toast.service'
import { pauseFor } from 'src/app/util/misc.util'

View File

@@ -1,6 +1,6 @@
import { Component } from '@angular/core'
import { AlertController, LoadingController, NavController } from '@ionic/angular'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { ActivatedRoute } from '@angular/router'
import { ErrorToastService } from 'src/app/services/error-toast.service'

View File

@@ -1,6 +1,6 @@
import { Component } from '@angular/core'
import { LoadingController, NavController } from '@ionic/angular'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { WifiService } from '../wifi.service'
import { ErrorToastService } from 'src/app/services/error-toast.service'

View File

@@ -1,6 +1,6 @@
import { Component } from '@angular/core'
import { ActionSheetController, LoadingController } from '@ionic/angular'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
import { ActionSheetButton } from '@ionic/core'
import { WifiService } from './wifi.service'
import { WiFiInfo } from 'src/app/services/patch-db/data-model'

View File

@@ -1,24 +1,12 @@
import { HttpService } from '../http.service'
import { MockApiService } from './embassy/embassy-mock-api.service'
import { LiveApiService } from './embassy/embassy-live-api.service'
import { MockApiService } from './embassy-mock-api.service'
import { LiveApiService } from './embassy-live-api.service'
import { ConfigService } from '../config.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'
import { ApiService } from './embassy/embassy-api.service'
export function ApiServiceFactory (config: ConfigService, http: HttpService) {
if (config.mocks.enabled) {
return new MockApiService(http, config)
return new MockApiService(http)
} else {
return new LiveApiService(http, config)
return new LiveApiService(http)
}
}
export function MarketplaceApiServiceFactory (config: ConfigService, patch: PatchDbService, apiService: ApiService) {
if (config.mocks.enabled) {
return new MarketplaceMockApiService(config, patch)
} else {
return new MarketplaceLiveApiService(apiService, config, patch)
}
}

View File

@@ -55,7 +55,7 @@ export module RR {
sessions: { [hash: string]: Session }
}
export type KillSessionsReq = WithExpire<{ hashes: string[] }> // sessions.kill
export type KillSessionsReq = WithExpire<{ ids: string[] }> // sessions.kill
export type KillSessionsRes = WithRevision<null>
// marketplace URLs

View File

@@ -1,8 +1,8 @@
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'
import { Method, RequestError } from '../../http.service'
import { RequestError } from '../http.service'
export abstract class ApiService implements Source<DataModel>, Http<DataModel> {
protected readonly sync = new Subject<Update<DataModel>>()
@@ -65,7 +65,15 @@ export abstract class ApiService implements Source<DataModel>, Http<DataModel> {
// marketplace URLs
abstract marketplaceProxy (url: string, params: { [key: string]: any }): Promise<any>
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>
abstract getLatestVersion (params: RR.GetLatestVersionReq): Promise<RR.GetLatestVersionRes>
// protected abstract setPackageMarketplaceRaw (params: RR.SetPackageMarketplaceReq): Promise<RR.SetPackageMarketplaceRes>
// setPackageMarketplace = (params: RR.SetPackageMarketplaceReq) => this.syncResponse(

View File

@@ -1,16 +1,14 @@
import { Injectable } from '@angular/core'
import { HttpService, Method } from '../../http.service'
import { HttpService, Method } from '../http.service'
import { ApiService } from './embassy-api.service'
import { RR } from '../api.types'
import { RR } from './api.types'
import { parsePropertiesPermissive } from 'src/app/util/properties.util'
import { ConfigService } from '../../config.service'
@Injectable()
export class LiveApiService extends ApiService {
constructor (
private readonly http: HttpService,
private readonly config: ConfigService,
) { super() }
async getStatic (url: string): Promise<string> {
@@ -87,10 +85,45 @@ export class LiveApiService extends ApiService {
// marketplace URLs
async marketplaceProxy (url: string, params: { [key: string]: any }) {
async getEos (params: RR.GetMarketplaceEOSReq): Promise<RR.GetMarketplaceEOSRes> {
return this.http.httpRequest({
method: Method.GET,
url,
url: '/marketplace/eos/latest',
params,
})
}
async getMarketplaceData (params: RR.GetMarketplaceDataReq): Promise <RR.GetMarketplaceDataRes> {
return this.http.httpRequest({
method: Method.GET,
url: '/marketplace/package/data',
params,
})
}
async getMarketplacePkgs (params: RR.GetMarketplacePackagesReq): Promise <RR.GetMarketplacePackagesRes> {
return this.http.httpRequest({
method: Method.GET,
url: '/marketplace/package/index',
params: {
...params,
ids: JSON.stringify(params.ids),
},
})
}
async getReleaseNotes (params: RR.GetReleaseNotesReq): Promise <RR.GetReleaseNotesRes> {
return this.http.httpRequest({
method: Method.GET,
url: '/marketplace/package/release-notes',
params,
})
}
async getLatestVersion (params: RR.GetLatestVersionReq): Promise <RR.GetLatestVersionRes> {
return this.http.httpRequest({
method: Method.GET,
url: '/marketplace/latest-version',
params,
})
}

View File

@@ -1,14 +1,13 @@
import { Injectable } from '@angular/core'
import { pauseFor } from '../../../util/misc.util'
import { pauseFor } from '../../util/misc.util'
import { ApiService } from './embassy-api.service'
import { Operation, PatchOp } from 'patch-db-client'
import { InstallProgress, 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 '../api.fixures'
import { HttpService } from '../../http.service'
import markdown from '!!raw-loader!src/assets/markdown/md-sample.md'
import { ConfigService } from '../../config.service'
import { Mock } from './api.fixures'
import { HttpService } from '../http.service'
import markdown from 'raw-loader!src/assets/markdown/md-sample.md'
@Injectable()
export class MockApiService extends ApiService {
@@ -16,7 +15,6 @@ export class MockApiService extends ApiService {
constructor (
private readonly http: HttpService,
private readonly config: ConfigService,
) { super() }
async getStatic (url: string): Promise<string> {
@@ -110,7 +108,7 @@ export class MockApiService extends ApiService {
{
op: PatchOp.REPLACE,
path: '/server-info/version',
value: this.config.version + '.1',
value: '3.1.0',
},
]
await this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch } })
@@ -119,7 +117,7 @@ export class MockApiService extends ApiService {
{
op: PatchOp.REPLACE,
path: '/server-info/version',
value: this.config.version,
value: require('../../../../package.json').version,
},
]
this.http.rpcRequest<WithRevision<null>>({ method: 'db.patch', params: { patch: patch2 } })
@@ -147,8 +145,34 @@ export class MockApiService extends ApiService {
// marketplace URLs
async marketplaceProxy (params) {
return null
async getEos (params: RR.GetMarketplaceEOSReq): Promise<RR.GetMarketplaceEOSRes> {
await pauseFor(2000)
return Mock.MarketplaceEos
}
async getMarketplaceData (params: RR.GetMarketplaceDataReq): Promise<RR.GetMarketplaceDataRes> {
await pauseFor(2000)
return {
categories: ['featured', 'bitcoin', 'lightning', 'data', 'messaging', 'social', 'alt coin'],
}
}
async getMarketplacePkgs (params: RR.GetMarketplacePackagesReq): Promise<RR.GetMarketplacePackagesRes> {
await pauseFor(2000)
return Mock.MarketplacePkgsList
}
async getReleaseNotes (params: RR.GetReleaseNotesReq): Promise<RR.GetReleaseNotesRes> {
await pauseFor(2000)
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
}, { })
}
// async setPackageMarketplaceRaw (params: RR.SetPackageMarketplaceReq): Promise<RR.SetPackageMarketplaceRes> {

View File

@@ -1,35 +0,0 @@
import { RR } from '../api.types'
import { ConfigService } from '../../config.service'
import { PatchDbService } from '../../patch-db/patch-db.service'
import { ServerInfo } from '../../patch-db/data-model'
import { AuthState } from '../../auth.service'
import { takeWhile } from 'rxjs/operators'
export abstract class MarketplaceApiService {
private server: ServerInfo
constructor (
readonly config: ConfigService,
readonly patch: PatchDbService,
) { }
init (auth: AuthState) {
this.patch.watch$('server-info')
.pipe(
takeWhile(() => auth === AuthState.VERIFIED),
)
.subscribe(server => {
this.server = server
})
}
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>
abstract getLatestVersion (params: RR.GetLatestVersionReq): Promise<RR.GetLatestVersionRes>
}

View File

@@ -1,39 +0,0 @@
import { Injectable } from '@angular/core'
import { Method } 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'
import { ApiService } from '../embassy/embassy-api.service'
@Injectable()
export class MarketplaceLiveApiService extends MarketplaceApiService {
constructor (
private readonly embassyApiService: ApiService,
config: ConfigService,
patch: PatchDbService,
) {
super( config, patch)
}
async getEos (params: RR.GetMarketplaceEOSReq): Promise<RR.GetMarketplaceEOSRes> {
return this.embassyApiService.marketplaceProxy('/marketplace/eos', params)
}
async getMarketplaceData (params: RR.GetMarketplaceDataReq): Promise < RR.GetMarketplaceDataRes > {
return this.embassyApiService.marketplaceProxy('/marketplace/package/data', params)
}
async getMarketplacePkgs (params: RR.GetMarketplacePackagesReq): Promise < RR.GetMarketplacePackagesRes > {
return this.embassyApiService.marketplaceProxy('/marketplace/package/packages', { ...params, ids: JSON.stringify(params.ids) })
}
async getReleaseNotes (params: RR.GetReleaseNotesReq): Promise < RR.GetReleaseNotesRes > {
return this.embassyApiService.marketplaceProxy('/marketplace/package/release-notes', params)
}
async getLatestVersion (params: RR.GetLatestVersionReq): Promise < RR.GetLatestVersionRes > {
return this.embassyApiService.marketplaceProxy('/marketplace/package/latest-version', params)
}
}

View File

@@ -1,49 +0,0 @@
import { Injectable } from '@angular/core'
import { pauseFor } from '../../../util/misc.util'
import { RR } from '../api.types'
import { Mock } from '../api.fixures'
import { MarketplaceApiService } from './marketplace-api.service'
import { PatchDbService } from '../../patch-db/patch-db.service'
import { ConfigService } from '../../config.service'
@Injectable()
export class MarketplaceMockApiService extends MarketplaceApiService {
constructor (
config: ConfigService,
patch: PatchDbService,
) {
super(config, patch)
}
// marketplace
async getEos (params: RR.GetMarketplaceEOSReq): Promise<RR.GetMarketplaceEOSRes> {
await pauseFor(2000)
return Mock.MarketplaceEos
}
async getMarketplaceData (params: RR.GetMarketplaceDataReq): Promise<RR.GetMarketplaceDataRes> {
await pauseFor(2000)
return {
categories: ['featured', 'bitcoin', 'lightning', 'data', 'messaging', 'social', 'alt coin'],
}
}
async getMarketplacePkgs (params: RR.GetMarketplacePackagesReq): Promise<RR.GetMarketplacePackagesRes> {
await pauseFor(2000)
return Mock.MarketplacePkgsList
}
async getReleaseNotes (params: RR.GetReleaseNotesReq): Promise<RR.GetReleaseNotesRes> {
await pauseFor(2000)
return Mock.ReleaseNotes
}
async getLatestVersion (params: RR.GetLatestVersionReq): Promise<RR.GetLatestVersionRes> {
await pauseFor(2000)
return params.ids.reduce((obj, id) => {
obj[id] = this.patch.getData()['package-data']?.[id]?.manifest.version.replace('0', '1')
return obj
}, { })
}
}

View File

@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core'
import { BehaviorSubject, Observable } from 'rxjs'
import { distinctUntilChanged } from 'rxjs/operators'
import { ApiService } from './api/embassy/embassy-api.service'
import { ApiService } from './api/embassy-api.service'
import { Storage } from '@ionic/storage-angular'
import { getPlatforms, isPlatform } from '@ionic/angular'

View File

@@ -1,6 +1,6 @@
import { Injectable } from '@angular/core'
import { BehaviorSubject, combineLatest, fromEvent, merge, Subscription } from 'rxjs'
import { ConnectionStatus, PatchDbService } from './patch-db/patch-db.service'
import { PatchConnection, PatchDbService } from './patch-db/patch-db.service'
import { HttpService, Method } from './http.service'
import { distinctUntilChanged, takeWhile } from 'rxjs/operators'
import { ConfigService } from './config.service'
@@ -12,7 +12,6 @@ import { AuthState } from './auth.service'
export class ConnectionService {
private readonly networkState$ = new BehaviorSubject<boolean>(true)
private readonly connectionFailure$ = new BehaviorSubject<ConnectionFailure>(ConnectionFailure.None)
private subs: Subscription[] = []
constructor (
private readonly httpService: HttpService,
@@ -25,60 +24,58 @@ export class ConnectionService {
}
start (auth: AuthState) {
this.subs = [
merge(fromEvent(window, 'online'), fromEvent(window, 'offline'))
merge(fromEvent(window, 'online'), fromEvent(window, 'offline'))
.pipe(
takeWhile(() => auth === AuthState.VERIFIED),
)
.subscribe(event => {
this.networkState$.next(event.type === 'online')
}),
combineLatest([
// 1
this.networkState$
.pipe(
distinctUntilChanged(),
),
// 2
this.patch.watchPatchConnection$()
.pipe(
distinctUntilChanged(),
),
// 3
this.patch.watch$('server-info', 'connection-addresses')
.pipe(
takeWhile(() => auth === AuthState.VERIFIED),
)
.subscribe(event => {
this.networkState$.next(event.type === 'online')
}),
combineLatest([
// 1
this.networkState$
.pipe(
distinctUntilChanged(),
),
// 2
this.patch.watchConnection$()
.pipe(
distinctUntilChanged(),
),
// 3
this.patch.watch$('server-info', 'connection-addresses')
.pipe(
takeWhile(() => auth === AuthState.VERIFIED),
distinctUntilChanged(),
),
])
.subscribe(async ([network, connectionStatus, addrs]) => {
if (connectionStatus !== ConnectionStatus.Disconnected) {
this.connectionFailure$.next(ConnectionFailure.None)
} else if (!network) {
this.connectionFailure$.next(ConnectionFailure.Network)
} else if (!this.configService.isTor()) {
this.connectionFailure$.next(ConnectionFailure.Lan)
distinctUntilChanged(),
),
])
.subscribe(async ([network, patchConnection, addrs]) => {
if (patchConnection !== PatchConnection.Disconnected) {
this.connectionFailure$.next(ConnectionFailure.None)
} else if (!network) {
this.connectionFailure$.next(ConnectionFailure.Network)
} else if (!this.configService.isTor()) {
this.connectionFailure$.next(ConnectionFailure.Lan)
} else {
// diagnosing
this.connectionFailure$.next(ConnectionFailure.Diagnosing)
const torSuccess = await this.testAddrs(addrs.tor)
if (torSuccess) {
// TOR SUCCESS, EMBASSY IS PROBLEM
this.connectionFailure$.next(ConnectionFailure.Embassy)
} else {
// diagnosing
this.connectionFailure$.next(ConnectionFailure.Diagnosing)
const torSuccess = await this.testAddrs(addrs.tor)
if (torSuccess) {
// TOR SUCCESS, EMBASSY IS PROBLEM
this.connectionFailure$.next(ConnectionFailure.Embassy)
const clearnetSuccess = await this.testAddrs(addrs.clearnet)
if (clearnetSuccess) {
// CLEARNET SUCCESS, TOR IS PROBLEM
this.connectionFailure$.next(ConnectionFailure.Tor)
} else {
const clearnetSuccess = await this.testAddrs(addrs.clearnet)
if (clearnetSuccess) {
// CLEARNET SUCCESS, TOR IS PROBLEM
this.connectionFailure$.next(ConnectionFailure.Tor)
} else {
// INTERNET IS PROBLEM
this.connectionFailure$.next(ConnectionFailure.Internet)
}
// INTERNET IS PROBLEM
this.connectionFailure$.next(ConnectionFailure.Internet)
}
}
}),
]
}
})
}
private async testAddrs (addrs: string[]): Promise<boolean> {

View File

@@ -3,7 +3,7 @@ import { ConfigService } from 'src/app/services/config.service'
import { DataModel } from './data-model'
import { LocalStorageBootstrap } from './local-storage-bootstrap'
import { PatchDbService } from './patch-db.service'
import { ApiService } from 'src/app/services/api/embassy/embassy-api.service'
import { ApiService } from 'src/app/services/api/embassy-api.service'
export function PatchDbServiceFactory (
config: ConfigService,

View File

@@ -2,14 +2,14 @@ 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/embassy/embassy-api.service'
import { ApiService } from '../api/embassy-api.service'
import { DataModel } from './data-model'
export const PATCH_HTTP = new InjectionToken<Source<DataModel>>('app.config')
export const PATCH_SOURCE = new InjectionToken<Source<DataModel>>('app.config')
export const BOOTSTRAPPER = new InjectionToken<Bootstrapper<DataModel>>('app.config')
export enum ConnectionStatus {
export enum PatchConnection {
Initializing = 'initializing',
Connected = 'connected',
Disconnected = 'disconnected',
@@ -19,7 +19,7 @@ export enum ConnectionStatus {
providedIn: 'root',
})
export class PatchDbService {
connectionStatus$ = new BehaviorSubject(ConnectionStatus.Initializing)
patchConnection$ = new BehaviorSubject(PatchConnection.Initializing)
private patchDb: PatchDB<DataModel>
private patchSub: Subscription
data: DataModel
@@ -46,12 +46,12 @@ export class PatchDbService {
.pipe(debounceTime(500))
.subscribe({
next: cache => {
this.connectionStatus$.next(ConnectionStatus.Connected)
this.patchConnection$.next(PatchConnection.Connected)
this.bootstrapper.update(cache)
},
error: e => {
console.error('patch-db-sync sub ERROR', e)
this.connectionStatus$.next(ConnectionStatus.Disconnected)
this.patchConnection$.next(PatchConnection.Disconnected)
// this.start()
},
complete: () => {
@@ -64,6 +64,7 @@ export class PatchDbService {
}
stop (): void {
this.patchConnection$.next(PatchConnection.Initializing)
if (this.patchSub) {
this.patchSub.unsubscribe()
this.patchSub = undefined
@@ -71,14 +72,14 @@ export class PatchDbService {
}
connected$ (): Observable<boolean> {
return this.connectionStatus$
return this.patchConnection$
.pipe(
map(status => status === ConnectionStatus.Connected),
map(status => status === PatchConnection.Connected),
)
}
watchConnection$ (): Observable<ConnectionStatus> {
return this.connectionStatus$.asObservable()
watchPatchConnection$ (): Observable<PatchConnection> {
return this.patchConnection$.asObservable()
}
watch$: Store<DataModel>['watch$'] = (...args: (string | number)[]): Observable<DataModel> => {

View File

@@ -1,7 +1,7 @@
import { Injectable } from '@angular/core'
import { AlertInput, AlertButton } from '@ionic/core'
// import { AppConfigValuePage } from '../modals/app-config-value/app-config-value.page'
import { ApiService } from './api/embassy/embassy-api.service'
import { ApiService } from './api/embassy-api.service'
import { ConfigSpec } from '../pkg-config/config-types'
import { SSHService } from '../pages/server-routes/security-routes/ssh-keys/ssh.service'
import { AlertController, LoadingController } from '@ionic/angular'

View File

@@ -8,12 +8,11 @@ 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 { MarketplaceApiService } from './api/marketplace/marketplace-api.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/embassy-api.service'
import { ApiService } from './api/embassy-api.service'
@Injectable({
providedIn: 'root',
@@ -28,8 +27,7 @@ export class StartupAlertsService {
private readonly config: ConfigService,
private readonly modalCtrl: ModalController,
private readonly marketplaceService: MarketplaceService,
private readonly marketplaceApi: MarketplaceApiService,
private readonly embassyApi: ApiService,
private readonly api: ApiService,
private readonly emver: Emver,
private readonly wizardBaker: WizardBaker,
private readonly patch: PatchDbService,
@@ -104,7 +102,7 @@ export class StartupAlertsService {
}
private async osUpdateCheck (): Promise<RR.GetMarketplaceEOSRes | undefined> {
const res = await this.marketplaceApi.getEos({ })
const res = await this.api.getEos({ })
if (this.emver.compare(this.config.version, res.version) === -1) {
return res
@@ -128,7 +126,7 @@ export class StartupAlertsService {
},
})
modal.onWillDismiss().then(() => {
this.embassyApi.setDbValue({ pointer: '/welcome-ack', value: this.config.version })
this.api.setDbValue({ pointer: '/welcome-ack', value: this.config.version })
.catch()
return resolve(true)
})