mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
rework LAN display and service launchability
This commit is contained in:
committed by
Keagan McClelland
parent
daf701a76c
commit
deb0b1e561
@@ -37,18 +37,23 @@ export interface AppInstalledPreview extends BaseApp {
|
||||
lanAddress?: string
|
||||
torAddress: string
|
||||
versionInstalled: string
|
||||
ui: boolean
|
||||
lanUi: boolean
|
||||
torUi: boolean
|
||||
// FE state only
|
||||
hasUI: boolean
|
||||
launchable: boolean
|
||||
}
|
||||
|
||||
export interface AppInstalledFull extends AppInstalledPreview {
|
||||
instructions: string | null
|
||||
lastBackup: string | null
|
||||
configuredRequirements: AppDependency[] | null // null if not yet configured
|
||||
hasFetchedFull: boolean
|
||||
startAlert?: string
|
||||
uninstallAlert?: string
|
||||
restoreAlert?: string
|
||||
actions: Actions
|
||||
// FE state only
|
||||
hasFetchedFull: boolean
|
||||
}
|
||||
|
||||
export type Actions = ServiceAction[]
|
||||
|
||||
@@ -22,11 +22,17 @@
|
||||
<ion-grid>
|
||||
<ion-row>
|
||||
<ion-col *ngFor="let app of apps" sizeXs="4" sizeSm="3" sizeMd="2" sizeLg="2">
|
||||
<ng-container *ngIf="{ status: app.subject.status | async, ui: app.subject.ui | async, iconURL: app.subject.iconURL | async | iconParse, title: app.subject.title | async } as vars" >
|
||||
<ng-container *ngIf="{
|
||||
status: app.subject.status | async,
|
||||
hasUI: app.subject.hasUI | async,
|
||||
launchable: app.subject.launchable | async,
|
||||
iconURL: app.subject.iconURL | async | iconParse,
|
||||
title: app.subject.title | async
|
||||
} as vars">
|
||||
|
||||
<ion-card class="installed-card" [class.installed-card-on]="vars.status === 'RUNNING'" style="position:relative" [routerLink]="['/services', 'installed', app.id]">
|
||||
<div class="launch-container" *ngIf="vars.ui && !isConsulate">
|
||||
<div class="launch-button-triangle" (click)="launchUiTab(app.id, $event)" [class.disabled]="vars.status !== AppStatus.RUNNING">
|
||||
<ion-card class="installed-card" style="position:relative" [routerLink]="['/services', 'installed', app.id]">
|
||||
<div class="launch-container" *ngIf="vars.hasUI">
|
||||
<div class="launch-button-triangle" (click)="launchUiTab(app.id, $event)" [class.disabled]="!vars.launchable">
|
||||
<ion-icon name="rocket-outline"></ion-icon>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -35,19 +35,15 @@ export class AppInstalledListPage extends Cleanup {
|
||||
segmentValue: 'services' | 'embassy' = 'services'
|
||||
|
||||
showCertDownload : boolean
|
||||
isConsulate: boolean
|
||||
isTor: boolean
|
||||
|
||||
constructor (
|
||||
private readonly serverModel: ServerModel,
|
||||
private readonly appModel: AppModel,
|
||||
private readonly preload: ModelPreload,
|
||||
private readonly syncDaemon: SyncDaemon,
|
||||
config: ConfigService,
|
||||
private readonly config: ConfigService,
|
||||
) {
|
||||
super()
|
||||
this.isConsulate = config.isConsulateAndroid || config.isConsulateIos
|
||||
this.isTor = config.isTor()
|
||||
}
|
||||
|
||||
ngOnDestroy () {
|
||||
@@ -105,12 +101,11 @@ export class AppInstalledListPage extends Cleanup {
|
||||
const app = this.apps.find(app => app.id === id).subject
|
||||
|
||||
let uiAddress: string
|
||||
if (this.isTor) {
|
||||
if (this.config.isTor()) {
|
||||
uiAddress = `http://${app.torAddress.getValue()}`
|
||||
} else {
|
||||
uiAddress = `https://${app.lanAddress.getValue()}`
|
||||
}
|
||||
console.log(uiAddress)
|
||||
return window.open(uiAddress, '_blank')
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,8 @@
|
||||
hasFetchedFull: app.hasFetchedFull | async,
|
||||
iconURL: app.iconURL | async,
|
||||
title: app.title | async,
|
||||
ui: app.ui | async,
|
||||
hasUI: app.hasUI | async,
|
||||
launchable: app.launchable | async,
|
||||
lanAddress: app.lanAddress | async
|
||||
} as vars" class="ion-padding-bottom">
|
||||
<ion-spinner *ngIf="$loading$ | async" class="center" name="lines" color="warning"></ion-spinner>
|
||||
@@ -77,7 +78,7 @@
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-button size="small" *ngIf="vars.status === AppStatus.RUNNING && vars.ui && !isConsulate" class="launch-button" expand="block" fill="outline" (click)="launchUiTab()">
|
||||
<ion-button size="small" *ngIf="vars.hasUI" [disabled]="!vars.launchable" class="launch-button" expand="block" (click)="launchUiTab()">
|
||||
Launch Web Interface
|
||||
<ion-icon slot="end" name="rocket-outline"></ion-icon>
|
||||
</ion-button>
|
||||
@@ -96,7 +97,7 @@
|
||||
<ion-icon slot="icon-only" name="copy-outline" color="primary"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-item>
|
||||
<ion-item *ngIf="vars.lanAddress" lines="none">
|
||||
<ion-item *ngIf="!hideLAN" lines="none">
|
||||
<ion-label class="ion-text-wrap">
|
||||
<h2>LAN Address</h2>
|
||||
<p>{{ vars.lanAddress }}</p>
|
||||
|
||||
@@ -32,8 +32,8 @@ export class AppInstalledShowPage extends Cleanup {
|
||||
appId: string
|
||||
AppStatus = AppStatus
|
||||
showInstructions = false
|
||||
isConsulate: boolean
|
||||
isTor: boolean
|
||||
|
||||
hideLAN: boolean
|
||||
|
||||
dependencyDefintion = () => `<span style="font-style: italic">Dependencies</span> are other services which must be installed, configured appropriately, and started in order to start ${this.app.title.getValue()}`
|
||||
|
||||
@@ -51,11 +51,9 @@ export class AppInstalledShowPage extends Cleanup {
|
||||
private readonly wizardBaker: WizardBaker,
|
||||
private readonly appModel: AppModel,
|
||||
private readonly popoverController: PopoverController,
|
||||
config: ConfigService,
|
||||
private readonly config: ConfigService,
|
||||
) {
|
||||
super()
|
||||
this.isConsulate = config.isConsulateIos || config.isConsulateAndroid
|
||||
this.isTor = config.isTor()
|
||||
}
|
||||
|
||||
async ngOnInit () {
|
||||
@@ -64,8 +62,12 @@ export class AppInstalledShowPage extends Cleanup {
|
||||
this.cleanup(
|
||||
markAsLoadingDuring$(this.$loading$, this.preload.appFull(this.appId))
|
||||
.pipe(
|
||||
tap(app => this.app = app),
|
||||
concatMap(() => this.syncWhenDependencyInstalls()), //must be final in stack
|
||||
tap(app => {
|
||||
this.app = app
|
||||
const appP = peekProperties(this.app)
|
||||
this.hideLAN = !appP.lanAddress || (appP.id === 'mastodon' && appP.versionInstalled === '3.3.0') // @TODO delete this hack in 0.3.0
|
||||
}),
|
||||
concatMap(() => this.syncWhenDependencyInstalls()), // must be final in stack
|
||||
catchError(e => of(this.setError(e))),
|
||||
).subscribe(),
|
||||
)
|
||||
@@ -98,7 +100,7 @@ export class AppInstalledShowPage extends Cleanup {
|
||||
|
||||
async launchUiTab () {
|
||||
let uiAddress: string
|
||||
if (this.isTor) {
|
||||
if (this.config.isTor()) {
|
||||
uiAddress = `http://${this.app.torAddress.getValue()}`
|
||||
} else {
|
||||
uiAddress = `https://${this.app.lanAddress.getValue()}`
|
||||
|
||||
@@ -130,7 +130,6 @@ export class AppMetricsPage {
|
||||
|
||||
toggleMask (key: string) {
|
||||
this.unmasked[key] = !this.unmasked[key]
|
||||
console.log(this.unmasked)
|
||||
}
|
||||
|
||||
asIsOrder (a: any, b: any) {
|
||||
|
||||
@@ -16,10 +16,8 @@ export class LANPage {
|
||||
lanDocs = 'docs.start9labs.com/user-manual/general/secure-lan'
|
||||
|
||||
lanAddress: string
|
||||
isTor: boolean
|
||||
fullDocumentationLink: string
|
||||
isConsulate: boolean
|
||||
lanDisabled: LanSetupIssue = undefined
|
||||
lanDisabled: LanSetupIssue
|
||||
readonly lanDisabledExplanation: { [k in LanSetupIssue]: string } = {
|
||||
NotDesktop: `We have detected you are on a mobile device. To setup LAN on a mobile device, use the Start9 Setup App.`,
|
||||
NotTor: `We have detected you are not using a Tor connection. For security reasons, you must setup LAN over a Tor connection. Please navigate to your Embassy Tor Address and try again.`,
|
||||
@@ -40,8 +38,6 @@ export class LANPage {
|
||||
this.lanDisabled = 'NotTor'
|
||||
}
|
||||
|
||||
this.isConsulate = this.config.isConsulateIos || this.config.isConsulateAndroid
|
||||
|
||||
if (this.config.isTor()) {
|
||||
this.fullDocumentationLink = `http://${this.torDocs}`
|
||||
} else {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { ConfigSpec } from 'src/app/app-config/config-types'
|
||||
import { AppAvailableFull, AppInstalledFull } from 'src/app/models/app-types'
|
||||
import { AppAvailableFull, AppInstalledFull, AppInstalledPreview } from 'src/app/models/app-types'
|
||||
import { Rules } from '../../models/app-model'
|
||||
import { SSHFingerprint, ServerStatus, ServerSpecs } from '../../models/server-model'
|
||||
|
||||
@@ -23,7 +23,9 @@ export interface ApiServer {
|
||||
|
||||
/** APPS **/
|
||||
export type ApiAppAvailableFull = Omit<AppAvailableFull, 'versionViewing'>
|
||||
export type ApiAppInstalledFull = Omit<AppInstalledFull, 'hasFetchedFull'>
|
||||
|
||||
export type ApiAppInstalledPreview = Omit<AppInstalledPreview, 'hasUI' | 'launchable'>
|
||||
export type ApiAppInstalledFull = Omit<AppInstalledFull, 'hasFetchedFull' | 'hasUI' | 'launchable'>
|
||||
|
||||
export interface ApiAppConfig {
|
||||
spec: ConfigSpec
|
||||
|
||||
@@ -7,8 +7,8 @@ import { ConfigService } from '../config.service'
|
||||
|
||||
export function ApiServiceFactory (config: ConfigService, http: HttpService, appModel: AppModel, serverModel: ServerModel) {
|
||||
if (config.api.useMocks) {
|
||||
return new MockApiService(appModel, serverModel)
|
||||
return new MockApiService(appModel, serverModel, config)
|
||||
} else {
|
||||
return new LiveApiService(http, appModel, serverModel)
|
||||
return new LiveApiService(http, appModel, serverModel, config)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ import { Rules } from '../../models/app-model'
|
||||
import { AppAvailablePreview, AppAvailableFull, AppInstalledPreview, AppInstalledFull, DependentBreakage, AppAvailableVersionSpecificInfo, ServiceAction } from '../../models/app-types'
|
||||
import { S9Notification, SSHFingerprint, ServerMetrics, DiskInfo } from '../../models/server-model'
|
||||
import { Subject, Observable } from 'rxjs'
|
||||
import { Unit, ApiServer, ApiAppInstalledFull, ApiAppConfig, ApiAppAvailableFull } from './api-types'
|
||||
import { Unit, ApiServer, ApiAppInstalledFull, ApiAppConfig, ApiAppAvailableFull, ApiAppInstalledPreview } from './api-types'
|
||||
import { AppMetrics, AppMetricsVersioned } from 'src/app/util/metrics.util'
|
||||
import { ConfigSpec } from 'src/app/app-config/config-types'
|
||||
|
||||
@@ -102,7 +102,7 @@ export module ReqRes {
|
||||
export type GetAppLogsRes = string[]
|
||||
export type GetServerLogsRes = string[]
|
||||
export type GetAppMetricsRes = AppMetricsVersioned<number>
|
||||
export type GetAppsInstalledRes = AppInstalledPreview[]
|
||||
export type GetAppsInstalledRes = ApiAppInstalledPreview[]
|
||||
export type PostInstallAppReq = { version: string }
|
||||
export type PostInstallAppRes = ApiAppInstalledFull & { breakages: DependentBreakage[] }
|
||||
export type PostUpdateAgentReq = { version: string }
|
||||
|
||||
@@ -4,8 +4,8 @@ import { AppModel, AppStatus } from '../../models/app-model'
|
||||
import { AppAvailablePreview, AppAvailableFull, AppInstalledFull, AppInstalledPreview, DependentBreakage, AppAvailableVersionSpecificInfo, ServiceAction } from '../../models/app-types'
|
||||
import { S9Notification, SSHFingerprint, ServerModel, DiskInfo } from '../../models/server-model'
|
||||
import { ApiService, ReqRes } from './api.service'
|
||||
import { ApiServer, Unit } from './api-types'
|
||||
import { HttpClient, HttpErrorResponse } from '@angular/common/http'
|
||||
import { ApiAppInstalledPreview, ApiServer, Unit } from './api-types'
|
||||
import { HttpErrorResponse } from '@angular/common/http'
|
||||
import { isUnauthorized } from 'src/app/util/web.util'
|
||||
import { Replace } from 'src/app/util/types.util'
|
||||
import { AppMetrics, parseMetricsPermissive } from 'src/app/util/metrics.util'
|
||||
@@ -13,7 +13,7 @@ import { modulateTime } from 'src/app/util/misc.util'
|
||||
import { Observable, of, throwError } from 'rxjs'
|
||||
import { catchError, mapTo } from 'rxjs/operators'
|
||||
import * as uuid from 'uuid'
|
||||
import { METHODS } from 'http'
|
||||
import { ConfigService } from '../config.service'
|
||||
|
||||
@Injectable()
|
||||
export class LiveApiService extends ApiService {
|
||||
@@ -22,6 +22,7 @@ export class LiveApiService extends ApiService {
|
||||
// TODO remove app + server model from here. updates to state should be done in a separate class wrapping ApiService + App/ServerModel
|
||||
private readonly appModel: AppModel,
|
||||
private readonly serverModel: ServerModel,
|
||||
private readonly config: ConfigService,
|
||||
) { super() }
|
||||
|
||||
testConnection(url: string): Promise<true> {
|
||||
@@ -116,11 +117,27 @@ export class LiveApiService extends ApiService {
|
||||
|
||||
async getInstalledApp(appId: string): Promise<AppInstalledFull> {
|
||||
return this.authRequest<ReqRes.GetAppInstalledRes>({ method: Method.GET, url: `/apps/${appId}/installed` })
|
||||
.then(app => ({ ...app, hasFetchedFull: true }))
|
||||
.then(app => {
|
||||
return {
|
||||
...app,
|
||||
hasFetchedFull: true,
|
||||
hasUI: this.config.hasUI(app),
|
||||
launchable: this.config.isLaunchable(app),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async getInstalledApps(): Promise<AppInstalledPreview[]> {
|
||||
return this.authRequest<ReqRes.GetAppsInstalledRes>({ method: Method.GET, url: `/apps/installed` })
|
||||
.then(apps => {
|
||||
return apps.map(app => {
|
||||
return {
|
||||
...app,
|
||||
hasUI: this.config.hasUI(app),
|
||||
launchable: this.config.isLaunchable(app),
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async getAppConfig(appId: string): Promise<ReqRes.GetAppConfigRes> {
|
||||
@@ -145,7 +162,14 @@ export class LiveApiService extends ApiService {
|
||||
version,
|
||||
}
|
||||
return this.authRequest<ReqRes.PostInstallAppRes>({ method: Method.POST, url: `/apps/${appId}/install${dryRunParam(dryRun, true)}`, data })
|
||||
.then(res => ({ ...res, hasFetchedFull: false }))
|
||||
.then(app => {
|
||||
return {
|
||||
...app,
|
||||
hasFetchedFull: false,
|
||||
hasUI: this.config.hasUI(app),
|
||||
launchable: this.config.isLaunchable(app),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async uninstallApp(appId: string, dryRun: boolean = false): Promise<{ breakages: DependentBreakage[] }> {
|
||||
|
||||
@@ -4,9 +4,10 @@ import { AppAvailablePreview, AppAvailableFull, AppInstalledPreview, AppInstalle
|
||||
import { S9Notification, SSHFingerprint, ServerStatus, ServerModel, DiskInfo } from '../../models/server-model'
|
||||
import { pauseFor } from '../../util/misc.util'
|
||||
import { ApiService, ReqRes } from './api.service'
|
||||
import { ApiServer, Unit as EmptyResponse, Unit } from './api-types'
|
||||
import { ApiAppInstalledFull, ApiAppInstalledPreview, ApiServer, Unit as EmptyResponse, Unit } from './api-types'
|
||||
import { AppMetrics, AppMetricsVersioned, parseMetricsPermissive } from 'src/app/util/metrics.util'
|
||||
import { mockApiAppAvailableFull, mockApiAppAvailableVersionInfo, mockApiAppInstalledFull, mockAppDependentBreakages, toInstalledPreview } from './mock-app-fixures'
|
||||
import { ConfigService } from '../config.service'
|
||||
|
||||
//@TODO consider moving to test folders.
|
||||
@Injectable()
|
||||
@@ -16,6 +17,7 @@ export class MockApiService extends ApiService {
|
||||
constructor (
|
||||
private readonly appModel: AppModel,
|
||||
private readonly serverModel: ServerModel,
|
||||
private readonly config: ConfigService,
|
||||
) {
|
||||
super()
|
||||
}
|
||||
@@ -107,6 +109,14 @@ export class MockApiService extends ApiService {
|
||||
|
||||
async getInstalledApp (appId: string): Promise<AppInstalledFull> {
|
||||
return mockGetInstalledApp(appId)
|
||||
.then(app => {
|
||||
return {
|
||||
...app,
|
||||
hasFetchedFull: false,
|
||||
hasUI: this.hasUI(app),
|
||||
launchable: this.isLaunchable(app),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async getAppMetrics (appId: string): Promise<AppMetrics> {
|
||||
@@ -115,6 +125,15 @@ export class MockApiService extends ApiService {
|
||||
|
||||
async getInstalledApps (): Promise<AppInstalledPreview[]> {
|
||||
return mockGetInstalledApps()
|
||||
.then(apps => {
|
||||
return apps.map(app => {
|
||||
return {
|
||||
...app,
|
||||
hasUI: this.hasUI(app),
|
||||
launchable: this.isLaunchable(app),
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
|
||||
async getAppConfig (appId: string): Promise<ReqRes.GetAppConfigRes> {
|
||||
@@ -131,6 +150,14 @@ export class MockApiService extends ApiService {
|
||||
|
||||
async installApp (appId: string, version: string, dryRun: boolean): Promise<AppInstalledFull & { breakages: DependentBreakage[] }> {
|
||||
return mockInstallApp(appId)
|
||||
.then(app => {
|
||||
return {
|
||||
...app,
|
||||
hasFetchedFull: true,
|
||||
hasUI: this.hasUI(app),
|
||||
launchable: this.isLaunchable(app),
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
async uninstallApp (appId: string, dryRun: boolean): Promise<{ breakages: DependentBreakage[] }> {
|
||||
@@ -230,7 +257,6 @@ export class MockApiService extends ApiService {
|
||||
}
|
||||
|
||||
async serviceAction (appId: string, action: ServiceAction): Promise<ReqRes.ServiceActionResponse> {
|
||||
console.log('service action', appId, action)
|
||||
await pauseFor(1000)
|
||||
return {
|
||||
jsonrpc: '2.0',
|
||||
@@ -243,9 +269,22 @@ export class MockApiService extends ApiService {
|
||||
}
|
||||
}
|
||||
|
||||
refreshLAN (): Promise<Unit> {
|
||||
async refreshLAN (): Promise<Unit> {
|
||||
return mockRefreshLAN()
|
||||
}
|
||||
|
||||
private hasUI (app: ApiAppInstalledPreview): boolean {
|
||||
return app.lanUi || app.torUi
|
||||
}
|
||||
|
||||
private isLaunchable (app: ApiAppInstalledPreview): boolean {
|
||||
return !this.config.isConsulate &&
|
||||
app.status === AppStatus.RUNNING &&
|
||||
(
|
||||
(app.torAddress && app.torUi && this.config.isTor()) ||
|
||||
(app.lanAddress && app.lanUi && !this.config.isTor())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
async function mockGetServer (): Promise<ReqRes.GetServerRes> {
|
||||
@@ -294,12 +333,12 @@ async function mockGetAvailableApps (): Promise<ReqRes.GetAppsAvailableRes> {
|
||||
return Object.values(mockApiAppAvailableFull)
|
||||
}
|
||||
|
||||
async function mockGetInstalledApp (appId: string): Promise<AppInstalledFull> {
|
||||
async function mockGetInstalledApp (appId: string): Promise<ReqRes.GetAppInstalledRes> {
|
||||
await pauseFor(1000)
|
||||
return { ...mockApiAppInstalledFull[appId], hasFetchedFull: true }
|
||||
return { ...mockApiAppInstalledFull[appId] }
|
||||
}
|
||||
|
||||
async function mockGetInstalledApps (): Promise<AppInstalledPreview[]> {
|
||||
async function mockGetInstalledApps (): Promise<ApiAppInstalledPreview[]> {
|
||||
await pauseFor(1000)
|
||||
return Object.values(mockApiAppInstalledFull).map(toInstalledPreview).filter(({ versionInstalled}) => !!versionInstalled)
|
||||
}
|
||||
@@ -329,9 +368,9 @@ async function mockGetAppConfig (): Promise<ReqRes.GetAppConfigRes> {
|
||||
return mockApiAppConfig
|
||||
}
|
||||
|
||||
async function mockInstallApp (appId: string): Promise<AppInstalledFull & { breakages: DependentBreakage[] }> {
|
||||
async function mockInstallApp (appId: string): Promise<ApiAppInstalledFull & { breakages: DependentBreakage[] }> {
|
||||
await pauseFor(1000)
|
||||
return { ...mockApiAppInstalledFull[appId], hasFetchedFull: true, ...mockAppDependentBreakages }
|
||||
return { ...mockApiAppInstalledFull[appId], ...mockAppDependentBreakages }
|
||||
}
|
||||
|
||||
async function mockUninstallApp (): Promise< { breakages: DependentBreakage[] } > {
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import { AppStatus } from '../../models/app-model'
|
||||
import { AppAvailablePreview, AppAvailableFull, AppInstalledPreview, AppDependency, BaseApp, AppInstalledFull, DependentBreakage, AppAvailableVersionSpecificInfo } from '../../models/app-types'
|
||||
import { modulateTime } from 'src/app/util/misc.util'
|
||||
import { ApiAppInstalledFull } from './api-types'
|
||||
|
||||
export function toAvailablePreview (f: AppAvailableFull): AppAvailablePreview {
|
||||
return {
|
||||
@@ -23,8 +24,11 @@ export function toInstalledPreview (f: AppInstalledFull): AppInstalledPreview {
|
||||
title: f.title,
|
||||
iconURL: f.iconURL,
|
||||
torAddress: f.torAddress,
|
||||
ui: f.ui,
|
||||
lanAddress: f.lanAddress,
|
||||
lanUi: f.lanUi,
|
||||
torUi: f.torUi,
|
||||
hasUI: f.hasUI,
|
||||
launchable: f.launchable,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,7 +49,7 @@ export function toServiceBreakage (f: BaseApp): DependentBreakage {
|
||||
}
|
||||
}
|
||||
|
||||
export const bitcoinI: AppInstalledFull = {
|
||||
export const bitcoinI: ApiAppInstalledFull = {
|
||||
id: 'bitcoind',
|
||||
versionInstalled: '0.18.1',
|
||||
lanAddress: 'bitcoinLan.local',
|
||||
@@ -57,8 +61,8 @@ export const bitcoinI: AppInstalledFull = {
|
||||
instructions: 'some instructions',
|
||||
lastBackup: new Date().toISOString(),
|
||||
configuredRequirements: [],
|
||||
hasFetchedFull: true,
|
||||
ui: false,
|
||||
lanUi: false,
|
||||
torUi: false,
|
||||
restoreAlert: 'if you restore this app horrible things will happen to the people you love.',
|
||||
actions: [
|
||||
{ id: 'sync-chain', name: 'Sync Chain', description: 'this will sync with the chain like from Avatar', allowedStatuses: [ AppStatus.RUNNING, AppStatus.RUNNING, AppStatus.RUNNING, AppStatus.RUNNING ]},
|
||||
@@ -66,14 +70,14 @@ export const bitcoinI: AppInstalledFull = {
|
||||
],
|
||||
}
|
||||
|
||||
export const lightningI: AppInstalledFull = {
|
||||
id: 'c-lightning',
|
||||
export const lightningI: ApiAppInstalledFull = {
|
||||
id: 'lightning',
|
||||
lanAddress: 'lightningLan.local',
|
||||
status: AppStatus.RUNNING,
|
||||
title: 'C Lightning',
|
||||
versionInstalled: '1.0.0',
|
||||
torAddress: '4acth47i6kxnvkewtm6q7ib2s3ufpo5sqbsnzjpbi7utijcltosqemad.onion',
|
||||
iconURL: 'assets/img/service-icons/bitwarden.png',
|
||||
iconURL: 'assets/img/service-icons/c-lightning.png',
|
||||
instructions: 'some instructions',
|
||||
lastBackup: new Date().toISOString(),
|
||||
configuredRequirements: [
|
||||
@@ -86,12 +90,12 @@ export const lightningI: AppInstalledFull = {
|
||||
violation: null,
|
||||
}),
|
||||
],
|
||||
hasFetchedFull: true,
|
||||
ui: true,
|
||||
lanUi: false,
|
||||
torUi: true,
|
||||
actions: [],
|
||||
}
|
||||
|
||||
export const cupsI: AppInstalledFull = {
|
||||
export const cupsI: ApiAppInstalledFull = {
|
||||
id: 'cups',
|
||||
lanAddress: 'cupsLan.local',
|
||||
versionInstalled: '2.1.0',
|
||||
@@ -102,7 +106,6 @@ export const cupsI: AppInstalledFull = {
|
||||
|
||||
instructions: 'some instructions',
|
||||
lastBackup: new Date().toISOString(),
|
||||
ui: true,
|
||||
uninstallAlert: 'This is A GREAT APP man, I just don\'t know',
|
||||
configuredRequirements: [
|
||||
toServiceRequirement(lightningI,
|
||||
@@ -133,7 +136,8 @@ export const cupsI: AppInstalledFull = {
|
||||
violation: { name: 'incompatible-config', ruleViolations: ['bro', 'seriously', 'fix this'] },
|
||||
}),
|
||||
],
|
||||
hasFetchedFull: true,
|
||||
lanUi: true,
|
||||
torUi: true,
|
||||
actions: [],
|
||||
}
|
||||
|
||||
@@ -296,7 +300,7 @@ export const mockApiAppAvailableFull: { [appId: string]: AppAvailableFull; } = {
|
||||
bitwarden: bitwardenA,
|
||||
}
|
||||
|
||||
export const mockApiAppInstalledFull: { [appId: string]: AppInstalledFull; } = {
|
||||
export const mockApiAppInstalledFull: { [appId: string]: ApiAppInstalledFull; } = {
|
||||
bitcoind: bitcoinI,
|
||||
cups: cupsI,
|
||||
lightning: lightningI,
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { AppStatus } from '../models/app-model'
|
||||
import { ApiAppInstalledPreview } from './api/api-types'
|
||||
|
||||
const { useMocks, mockOver, skipStartupAlerts } = require('../../../use-mocks.json') as UseMocks
|
||||
|
||||
@@ -22,12 +24,25 @@ export class ConfigService {
|
||||
}
|
||||
|
||||
skipStartupAlerts = skipStartupAlerts
|
||||
isConsulateIos = window['platform'] === 'ios'
|
||||
isConsulateAndroid = window['platform'] === 'android'
|
||||
isConsulate = window['platform'] === 'ios'
|
||||
|
||||
isTor () : boolean {
|
||||
return (this.api.useMocks && mockOver === 'tor') || this.origin.endsWith('.onion')
|
||||
}
|
||||
|
||||
hasUI (app: ApiAppInstalledPreview): boolean {
|
||||
return app.lanUi || app.torUi
|
||||
}
|
||||
|
||||
isLaunchable (app: ApiAppInstalledPreview): boolean {
|
||||
return !this.isConsulate &&
|
||||
app.status === AppStatus.RUNNING &&
|
||||
(
|
||||
(app.torAddress && app.torUi && this.isTor()) ||
|
||||
(app.lanAddress && app.lanUi && !this.isTor())
|
||||
)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function removeProtocol (str: string): string {
|
||||
|
||||
Reference in New Issue
Block a user