mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-26 02:11:53 +00:00
Update/misc frontend (#2191)
* update version to 0.3.4 * update release guide with sdk instructions * remove comment * update page styling * closes #2152, closes #2155, closes #2157 * move marketing site link to description block * re-arrange setup wizard recovery options * move divider for update list item * fix bug in mocks to display lnd as aavailable for update --------- Co-authored-by: Matt Hill <matthewonthemoon@gmail.com>
This commit is contained in:
@@ -70,3 +70,7 @@
|
|||||||
- `make eos_raspberrypi.img`
|
- `make eos_raspberrypi.img`
|
||||||
- `tar --format=posix -cS -f- eos-<version>-<git hash>-<date>_raspberrypi.img | gzip > eos-<version>-<git hash>-<date>_raspberrypi.tar.gz`
|
- `tar --format=posix -cS -f- eos-<version>-<git hash>-<date>_raspberrypi.img | gzip > eos-<version>-<git hash>-<date>_raspberrypi.tar.gz`
|
||||||
- Artifact `./eos-<version>-<git hash>-<date>_raspberrypi.tar.gz`
|
- Artifact `./eos-<version>-<git hash>-<date>_raspberrypi.tar.gz`
|
||||||
|
|
||||||
|
## `embassy-sdk`
|
||||||
|
|
||||||
|
- Build and deploy to all registries
|
||||||
4
frontend/package-lock.json
generated
4
frontend/package-lock.json
generated
@@ -1,12 +1,12 @@
|
|||||||
{
|
{
|
||||||
"name": "embassy-os",
|
"name": "embassy-os",
|
||||||
"version": "0.3.3",
|
"version": "0.3.4",
|
||||||
"lockfileVersion": 2,
|
"lockfileVersion": 2,
|
||||||
"requires": true,
|
"requires": true,
|
||||||
"packages": {
|
"packages": {
|
||||||
"": {
|
"": {
|
||||||
"name": "embassy-os",
|
"name": "embassy-os",
|
||||||
"version": "0.3.3",
|
"version": "0.3.4",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@angular/animations": "^14.1.0",
|
"@angular/animations": "^14.1.0",
|
||||||
"@angular/common": "^14.1.0",
|
"@angular/common": "^14.1.0",
|
||||||
|
|||||||
@@ -24,3 +24,12 @@
|
|||||||
<h2>{{ pkg.manifest.description.long }}</h2>
|
<h2>{{ pkg.manifest.description.long }}</h2>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
<div
|
||||||
|
*ngIf="pkg.manifest['marketing-site'] as url"
|
||||||
|
style="padding: 4px 0 10px 14px"
|
||||||
|
>
|
||||||
|
<ion-button [href]="url" target="_blank" rel="noreferrer" color="tertiary">
|
||||||
|
View marketing website
|
||||||
|
<ion-icon slot="end" name="open-outline"></ion-icon>
|
||||||
|
</ion-button>
|
||||||
|
</div>
|
||||||
|
|||||||
@@ -1,13 +1,3 @@
|
|||||||
<div
|
|
||||||
*ngIf="pkg.manifest['marketing-site'] as url"
|
|
||||||
style="padding: 4px 0 10px 14px"
|
|
||||||
>
|
|
||||||
<ion-button [href]="url" target="_blank" rel="noreferrer" color="tertiary">
|
|
||||||
View marketing website
|
|
||||||
<ion-icon slot="end" name="open-outline"></ion-icon>
|
|
||||||
</ion-button>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<ng-container *ngIf="pkg.manifest.replaces as replaces">
|
<ng-container *ngIf="pkg.manifest.replaces as replaces">
|
||||||
<div *ngIf="replaces.length" class="ion-padding-bottom">
|
<div *ngIf="replaces.length" class="ion-padding-bottom">
|
||||||
<ion-item-divider>Intended to replace</ion-item-divider>
|
<ion-item-divider>Intended to replace</ion-item-divider>
|
||||||
|
|||||||
@@ -154,9 +154,7 @@ export class EmbassyPage {
|
|||||||
await this.stateService.setupEmbassy(logicalname, password)
|
await this.stateService.setupEmbassy(logicalname, password)
|
||||||
await this.navCtrl.navigateForward(`/loading`)
|
await this.navCtrl.navigateForward(`/loading`)
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
this.errorToastService.present({
|
this.errorToastService.present(e)
|
||||||
message: `${e.message}\n\nRestart Embassy to try again.`,
|
|
||||||
})
|
|
||||||
console.error(e)
|
console.error(e)
|
||||||
} finally {
|
} finally {
|
||||||
loader.dismiss()
|
loader.dismiss()
|
||||||
|
|||||||
@@ -66,22 +66,6 @@
|
|||||||
|
|
||||||
<!-- SLIDE 2 -->
|
<!-- SLIDE 2 -->
|
||||||
<ng-template swiperSlide>
|
<ng-template swiperSlide>
|
||||||
<!-- restore from backup -->
|
|
||||||
<ion-item
|
|
||||||
button
|
|
||||||
lines="none"
|
|
||||||
detail="false"
|
|
||||||
routerLink="/recover"
|
|
||||||
>
|
|
||||||
<ion-icon slot="start" name="save-outline"></ion-icon>
|
|
||||||
<ion-label>
|
|
||||||
<h2>
|
|
||||||
<ion-text color="warning">Restore From Backup</ion-text>
|
|
||||||
</h2>
|
|
||||||
<p>Restore an Embassy from an encrypted backup</p>
|
|
||||||
</ion-label>
|
|
||||||
</ion-item>
|
|
||||||
|
|
||||||
<!-- attach -->
|
<!-- attach -->
|
||||||
<ion-item
|
<ion-item
|
||||||
button
|
button
|
||||||
@@ -92,10 +76,12 @@
|
|||||||
<ion-icon slot="start" name="cube-outline"></ion-icon>
|
<ion-icon slot="start" name="cube-outline"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>
|
<h2>
|
||||||
<ion-text color="primary">Use Existing Drive</ion-text>
|
<ion-text color="success">Use Existing Drive</ion-text>
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
Use an existing, valid Embassy data drive (not a backup)
|
Attach an existing embassyOS data drive (
|
||||||
|
<b>not</b>
|
||||||
|
a backup)
|
||||||
</p>
|
</p>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
@@ -110,15 +96,33 @@
|
|||||||
<ion-icon slot="start" name="share-outline"></ion-icon>
|
<ion-icon slot="start" name="share-outline"></ion-icon>
|
||||||
<ion-label>
|
<ion-label>
|
||||||
<h2>
|
<h2>
|
||||||
<ion-text color="success">Transfer</ion-text>
|
<ion-text color="primary">Transfer</ion-text>
|
||||||
</h2>
|
</h2>
|
||||||
<p>
|
<p>
|
||||||
Transfer data from an existing, valid Embassy data drive
|
Transfer data from an existing embassyOS data drive (not a
|
||||||
(not a backup) to a new drive<br />(e.g. in order to
|
backup) to a new, preferred drive
|
||||||
transfer data to another device)
|
<br />
|
||||||
</p>
|
</p>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
|
||||||
|
<!-- restore from backup -->
|
||||||
|
<ion-item
|
||||||
|
button
|
||||||
|
lines="none"
|
||||||
|
detail="false"
|
||||||
|
routerLink="/recover"
|
||||||
|
>
|
||||||
|
<ion-icon slot="start" name="save-outline"></ion-icon>
|
||||||
|
<ion-label>
|
||||||
|
<h2>
|
||||||
|
<ion-text color="warning">
|
||||||
|
Restore From Backup (Disaster Recovery)
|
||||||
|
</ion-text>
|
||||||
|
</h2>
|
||||||
|
<p>Restore embassyOS data from an encrypted backup</p>
|
||||||
|
</ion-label>
|
||||||
|
</ion-item>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</swiper>
|
</swiper>
|
||||||
</ion-card-content>
|
</ion-card-content>
|
||||||
|
|||||||
@@ -49,9 +49,7 @@ export class StateService {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
} catch (e: any) {
|
} catch (e: any) {
|
||||||
this.errorToastService.present({
|
this.errorToastService.present(e)
|
||||||
message: `${e.message}\n\nRestart Embassy to try again.`,
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
setTimeout(() => this.pollDataTransferProgress(), 0) // prevent call stack from growing
|
setTimeout(() => this.pollDataTransferProgress(), 0) // prevent call stack from growing
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ import { HttpErrorResponse } from '@angular/common/http'
|
|||||||
export class HttpError {
|
export class HttpError {
|
||||||
readonly code = this.error.status
|
readonly code = this.error.status
|
||||||
readonly message = this.error.statusText
|
readonly message = this.error.statusText
|
||||||
readonly details = null
|
|
||||||
readonly revision = null
|
|
||||||
|
|
||||||
constructor(private readonly error: HttpErrorResponse) {}
|
constructor(private readonly error: HttpErrorResponse) {}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
import { Injectable } from '@angular/core'
|
import { Injectable } from '@angular/core'
|
||||||
import { IonicSafeString, ToastController } from '@ionic/angular'
|
import { IonicSafeString, ToastController } from '@ionic/angular'
|
||||||
|
import { HttpError } from '../classes/http-error'
|
||||||
|
|
||||||
@Injectable({
|
@Injectable({
|
||||||
providedIn: 'root',
|
providedIn: 'root',
|
||||||
@@ -9,7 +10,7 @@ export class ErrorToastService {
|
|||||||
|
|
||||||
constructor(private readonly toastCtrl: ToastController) {}
|
constructor(private readonly toastCtrl: ToastController) {}
|
||||||
|
|
||||||
async present(e: { message: string }, link?: string): Promise<void> {
|
async present(e: HttpError | string, link?: string): Promise<void> {
|
||||||
console.error(e)
|
console.error(e)
|
||||||
|
|
||||||
if (this.toast) return
|
if (this.toast) return
|
||||||
@@ -42,12 +43,21 @@ export class ErrorToastService {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function getErrorMessage(
|
export function getErrorMessage(
|
||||||
{ message }: { message: string },
|
e: HttpError | string,
|
||||||
link?: string,
|
link?: string,
|
||||||
): string | IonicSafeString {
|
): string | IonicSafeString {
|
||||||
if (!message) {
|
let message = ''
|
||||||
message = 'Unknown Error.'
|
|
||||||
|
if (typeof e === 'string') {
|
||||||
|
message = e
|
||||||
|
} else if (e.code === 0) {
|
||||||
|
message =
|
||||||
|
'Request Error. Your browser blocked the request. This is usually caused by a corrupt browser cache or an overly aggressive ad blocker. Please clear your browser cache and/or adjust your ad blocker and try again'
|
||||||
|
} else if (!e.message) {
|
||||||
|
message = 'Unknown Error'
|
||||||
link = 'https://docs.start9.com/latest/support/faq'
|
link = 'https://docs.start9.com/latest/support/faq'
|
||||||
|
} else {
|
||||||
|
message = e.message
|
||||||
}
|
}
|
||||||
|
|
||||||
if (link) {
|
if (link) {
|
||||||
|
|||||||
@@ -6,13 +6,14 @@ import { PatchDataService } from './services/patch-data.service'
|
|||||||
import { PatchMonitorService } from './services/patch-monitor.service'
|
import { PatchMonitorService } from './services/patch-monitor.service'
|
||||||
import { ConnectionService } from './services/connection.service'
|
import { ConnectionService } from './services/connection.service'
|
||||||
import { Title } from '@angular/platform-browser'
|
import { Title } from '@angular/platform-browser'
|
||||||
import { ServerNameService } from './services/server-name.service'
|
|
||||||
import {
|
import {
|
||||||
ClientStorageService,
|
ClientStorageService,
|
||||||
WidgetDrawer,
|
WidgetDrawer,
|
||||||
} from './services/client-storage.service'
|
} from './services/client-storage.service'
|
||||||
import { ThemeSwitcherService } from './services/theme-switcher.service'
|
import { ThemeSwitcherService } from './services/theme-switcher.service'
|
||||||
import { THEME } from '@start9labs/shared'
|
import { THEME } from '@start9labs/shared'
|
||||||
|
import { PatchDB } from 'patch-db-client'
|
||||||
|
import { DataModel } from './services/patch-db/data-model'
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-root',
|
selector: 'app-root',
|
||||||
@@ -30,7 +31,7 @@ export class AppComponent implements OnDestroy {
|
|||||||
private readonly patchData: PatchDataService,
|
private readonly patchData: PatchDataService,
|
||||||
private readonly patchMonitor: PatchMonitorService,
|
private readonly patchMonitor: PatchMonitorService,
|
||||||
private readonly splitPane: SplitPaneTracker,
|
private readonly splitPane: SplitPaneTracker,
|
||||||
private readonly serverNameService: ServerNameService,
|
private readonly patch: PatchDB<DataModel>,
|
||||||
readonly authService: AuthService,
|
readonly authService: AuthService,
|
||||||
readonly connection: ConnectionService,
|
readonly connection: ConnectionService,
|
||||||
readonly clientStorageService: ClientStorageService,
|
readonly clientStorageService: ClientStorageService,
|
||||||
@@ -38,9 +39,9 @@ export class AppComponent implements OnDestroy {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.serverNameService.name$.subscribe(({ current }) =>
|
this.patch
|
||||||
this.titleService.setTitle(current),
|
.watch$('ui', 'name')
|
||||||
)
|
.subscribe(name => this.titleService.setTitle(name || 'embassyOS'))
|
||||||
}
|
}
|
||||||
|
|
||||||
splitPaneVisible({ detail }: any) {
|
splitPaneVisible({ detail }: any) {
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import {
|
|||||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||||
import { ActivatedRoute } from '@angular/router'
|
import { ActivatedRoute } from '@angular/router'
|
||||||
import { PatchDB } from 'patch-db-client'
|
import { PatchDB } from 'patch-db-client'
|
||||||
import { ServerNameService } from 'src/app/services/server-name.service'
|
|
||||||
import { combineLatest, firstValueFrom, map, Observable, of } from 'rxjs'
|
import { combineLatest, firstValueFrom, map, Observable, of } from 'rxjs'
|
||||||
import { ErrorToastService } from '@start9labs/shared'
|
import { ErrorToastService } from '@start9labs/shared'
|
||||||
import { EOSService } from 'src/app/services/eos.service'
|
import { EOSService } from 'src/app/services/eos.service'
|
||||||
@@ -52,7 +51,6 @@ export class ServerShowPage {
|
|||||||
private readonly patch: PatchDB<DataModel>,
|
private readonly patch: PatchDB<DataModel>,
|
||||||
private readonly eosService: EOSService,
|
private readonly eosService: EOSService,
|
||||||
private readonly ClientStorageService: ClientStorageService,
|
private readonly ClientStorageService: ClientStorageService,
|
||||||
private readonly serverNameService: ServerNameService,
|
|
||||||
private readonly authService: AuthService,
|
private readonly authService: AuthService,
|
||||||
private readonly toastCtrl: ToastController,
|
private readonly toastCtrl: ToastController,
|
||||||
private readonly config: ConfigService,
|
private readonly config: ConfigService,
|
||||||
@@ -60,19 +58,18 @@ export class ServerShowPage {
|
|||||||
) {}
|
) {}
|
||||||
|
|
||||||
async presentModalName(): Promise<void> {
|
async presentModalName(): Promise<void> {
|
||||||
const name = await firstValueFrom(this.serverNameService.name$)
|
const chosenName = await firstValueFrom(this.patch.watch$('ui', 'name'))
|
||||||
|
|
||||||
const options: GenericInputOptions = {
|
const options: GenericInputOptions = {
|
||||||
title: 'Set Device Name',
|
title: 'Set Device Name',
|
||||||
message: 'This will be displayed in your browser tab',
|
message: 'This will be displayed in your browser tab',
|
||||||
label: 'Device Name',
|
label: 'Device Name',
|
||||||
useMask: false,
|
useMask: false,
|
||||||
placeholder: name.default,
|
placeholder: 'embassyOS',
|
||||||
nullable: true,
|
nullable: true,
|
||||||
initialValue: name.current,
|
initialValue: chosenName,
|
||||||
buttonText: 'Save',
|
buttonText: 'Save',
|
||||||
submitFn: (value: string) =>
|
submitFn: (name: string) => this.setName(name || null),
|
||||||
this.setDbValue('name', value || name.default),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const modal = await this.modalCtrl.create({
|
const modal = await this.modalCtrl.create({
|
||||||
@@ -227,14 +224,14 @@ export class ServerShowPage {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private async setDbValue(key: string, value: string): Promise<void> {
|
private async setName(value: string | null): Promise<void> {
|
||||||
const loader = await this.loadingCtrl.create({
|
const loader = await this.loadingCtrl.create({
|
||||||
message: 'Saving...',
|
message: 'Saving...',
|
||||||
})
|
})
|
||||||
await loader.present()
|
await loader.present()
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await this.embassyApi.setDbValue<string>([key], value)
|
await this.embassyApi.setDbValue<string | null>(['name'], value)
|
||||||
} finally {
|
} finally {
|
||||||
loader.dismiss()
|
loader.dismiss()
|
||||||
}
|
}
|
||||||
@@ -393,8 +390,8 @@ export class ServerShowPage {
|
|||||||
disabled$: this.eosService.updatingOrBackingUp$,
|
disabled$: this.eosService.updatingOrBackingUp$,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Set Device Name',
|
title: 'Browser Tab Title',
|
||||||
description: 'Give your device a name for easy identification',
|
description: `Customize the display name of your browser tab. This does not affect your server's LAN address.`,
|
||||||
icon: 'pricetag-outline',
|
icon: 'pricetag-outline',
|
||||||
action: () => this.presentModalName(),
|
action: () => this.presentModalName(),
|
||||||
detail: false,
|
detail: false,
|
||||||
@@ -429,7 +426,7 @@ export class ServerShowPage {
|
|||||||
disabled$: of(false),
|
disabled$: of(false),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
title: 'Sideload Service',
|
title: 'Sideload a Service',
|
||||||
description: `Manually install a service`,
|
description: `Manually install a service`,
|
||||||
icon: 'push-outline',
|
icon: 'push-outline',
|
||||||
action: () =>
|
action: () =>
|
||||||
|
|||||||
@@ -7,17 +7,19 @@
|
|||||||
</ion-toolbar>
|
</ion-toolbar>
|
||||||
</ion-header>
|
</ion-header>
|
||||||
|
|
||||||
<ion-content class="ion-padding with-widgets">
|
<ion-content class="with-widgets">
|
||||||
<ion-item-group *ngIf="data$ | async as data">
|
<ion-item-group *ngIf="data$ | async as data">
|
||||||
<ng-container *ngFor="let host of data.hosts">
|
<ng-container *ngFor="let host of data.hosts">
|
||||||
<ion-item-divider class="header">
|
<div class="header">
|
||||||
<div class="inline">
|
<div class="header_items">
|
||||||
|
<store-icon [url]="host.url" size="48px"></store-icon>
|
||||||
|
<div class="pl-1">
|
||||||
<h1>{{ host.name }}</h1>
|
<h1>{{ host.name }}</h1>
|
||||||
<store-icon [url]="host.url" size="24px"></store-icon>
|
<p>{{ host.url }}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</ion-item-divider>
|
|
||||||
|
|
||||||
<div class="ion-padding-start ion-padding-bottom">
|
|
||||||
<ion-item *ngIf="data.errors.includes(host.url)">
|
<ion-item *ngIf="data.errors.includes(host.url)">
|
||||||
<ion-text color="danger">Request Failed</ion-text>
|
<ion-text color="danger">Request Failed</ion-text>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
@@ -28,28 +30,33 @@
|
|||||||
<ng-container
|
<ng-container
|
||||||
*ngIf="packages | filterUpdates : data.localPkgs as updates"
|
*ngIf="packages | filterUpdates : data.localPkgs as updates"
|
||||||
>
|
>
|
||||||
<div *ngFor="let pkg of updates" class="item-container">
|
<ion-grid>
|
||||||
<ion-item lines="none">
|
<div *ngFor="let pkg of updates">
|
||||||
<ng-container *ngIf="data.localPkgs[pkg.manifest.id] as local">
|
<ng-container *ngIf="data.localPkgs[pkg.manifest.id] as local">
|
||||||
<ion-thumbnail
|
<ion-row>
|
||||||
slot="start"
|
<ion-col>
|
||||||
style="cursor: pointer"
|
<ion-accordion-group class="accordian-padding">
|
||||||
|
<ion-accordion class="item-container">
|
||||||
|
<ion-item slot="header">
|
||||||
|
<ion-col class="accordian-padding">
|
||||||
|
<ion-row
|
||||||
(click)="viewInMarketplace(local)"
|
(click)="viewInMarketplace(local)"
|
||||||
|
style="cursor: pointer"
|
||||||
>
|
>
|
||||||
|
<ion-thumbnail class="align-center">
|
||||||
<img
|
<img
|
||||||
[src]="'data:image/png;base64,' + pkg.icon | trustUrl"
|
[src]="'data:image/png;base64,' + pkg.icon | trustUrl"
|
||||||
/>
|
/>
|
||||||
</ion-thumbnail>
|
</ion-thumbnail>
|
||||||
<ion-label>
|
<ion-label class="pl-1">
|
||||||
<h1
|
<h1>{{ pkg.manifest.title }}</h1>
|
||||||
(click)="viewInMarketplace(local)"
|
|
||||||
style="cursor: pointer"
|
|
||||||
>
|
|
||||||
{{ pkg.manifest.title }}
|
|
||||||
</h1>
|
|
||||||
<h2 class="inline">
|
<h2 class="inline">
|
||||||
<span>{{ local.manifest.version | displayEmver }}</span>
|
<span>
|
||||||
<ion-icon name="arrow-forward"></ion-icon>
|
{{ local.manifest.version | displayEmver }}
|
||||||
|
</span>
|
||||||
|
|
||||||
|
<ion-icon name="arrow-forward"></ion-icon>
|
||||||
|
|
||||||
<ion-text color="success">
|
<ion-text color="success">
|
||||||
{{ pkg.manifest.version | displayEmver }}
|
{{ pkg.manifest.version | displayEmver }}
|
||||||
</ion-text>
|
</ion-text>
|
||||||
@@ -57,16 +64,19 @@
|
|||||||
<p
|
<p
|
||||||
*ngIf="marketplaceService.updateErrors[pkg.manifest.id] as error"
|
*ngIf="marketplaceService.updateErrors[pkg.manifest.id] as error"
|
||||||
>
|
>
|
||||||
<ion-text color="danger">{{ error }}</ion-text>
|
<ion-text color="danger">
|
||||||
|
{{ error }}
|
||||||
|
</ion-text>
|
||||||
</p>
|
</p>
|
||||||
</ion-label>
|
</ion-label>
|
||||||
|
</ion-row>
|
||||||
<div slot="end" style="margin-left: 8px">
|
</ion-col>
|
||||||
|
<div class="align-center">
|
||||||
<round-progress
|
<round-progress
|
||||||
*ngIf="local.state === PackageState.Updating else notUpdating"
|
*ngIf="local.state === PackageState.Updating else notUpdating"
|
||||||
[current]="local['install-progress'] | installProgress"
|
[current]="local['install-progress'] | installProgress"
|
||||||
[max]="100"
|
[max]="100"
|
||||||
[radius]="24"
|
[radius]="15"
|
||||||
[stroke]="4"
|
[stroke]="4"
|
||||||
[rounded]="true"
|
[rounded]="true"
|
||||||
color="var(--ion-color-primary)"
|
color="var(--ion-color-primary)"
|
||||||
@@ -79,25 +89,38 @@
|
|||||||
<ng-template #updateBtn>
|
<ng-template #updateBtn>
|
||||||
<ion-button
|
<ion-button
|
||||||
(click)="tryUpdate(pkg.manifest, host.url, local)"
|
(click)="tryUpdate(pkg.manifest, host.url, local)"
|
||||||
[color]="marketplaceService.updateErrors[pkg.manifest.id] ? 'danger' : 'dark'"
|
[color]="marketplaceService.updateErrors[pkg.manifest.id] ? 'danger' : 'tertiary'"
|
||||||
strong
|
strong
|
||||||
|
size="default"
|
||||||
>
|
>
|
||||||
{{ marketplaceService.updateErrors[pkg.manifest.id] ?
|
{{
|
||||||
'Retry' : 'Update' }}
|
marketplaceService.updateErrors[pkg.manifest.id]
|
||||||
|
? 'Retry' : 'Update' }}
|
||||||
</ion-button>
|
</ion-button>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</div>
|
</div>
|
||||||
</ng-container>
|
|
||||||
</ion-item>
|
</ion-item>
|
||||||
|
<div class="ion-padding" slot="content">
|
||||||
<div class="notes">
|
<div class="notes">
|
||||||
<h5><b>What's New</b></h5>
|
<p
|
||||||
<p [innerHTML]="pkg.manifest['release-notes'] | markdown"></p>
|
[innerHTML]="pkg.manifest['release-notes'] | markdown"
|
||||||
|
></p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</ion-accordion>
|
||||||
<ion-item *ngIf="!updates.length">
|
</ion-accordion-group>
|
||||||
<p>All services are up to date!</p>
|
</ion-col>
|
||||||
|
</ion-row>
|
||||||
|
</ng-container>
|
||||||
|
</div>
|
||||||
|
</ion-grid>
|
||||||
|
<ion-item
|
||||||
|
*ngIf="!updates.length"
|
||||||
|
class="ion-text-center ion-padding"
|
||||||
|
lines="none"
|
||||||
|
>
|
||||||
|
<ion-label>All services are up to date!</ion-label>
|
||||||
</ion-item>
|
</ion-item>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ng-container>
|
</ng-container>
|
||||||
@@ -105,7 +128,6 @@
|
|||||||
<ng-template #loading>
|
<ng-template #loading>
|
||||||
<skeleton-list [showAvatar]="true" [rows]="2"></skeleton-list>
|
<skeleton-list [showAvatar]="true" [rows]="2"></skeleton-list>
|
||||||
</ng-template>
|
</ng-template>
|
||||||
</div>
|
|
||||||
</ng-container>
|
</ng-container>
|
||||||
</ion-item-group>
|
</ion-item-group>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
|
|||||||
@@ -8,9 +8,57 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.header {
|
.header {
|
||||||
margin-bottom: 20px;
|
padding: 1.5rem;
|
||||||
|
background: var(--ion-color-medium-tint);
|
||||||
|
|
||||||
|
&_items {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
flex-direction: row;
|
||||||
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
font-weight: bold;
|
font-size: 28px;
|
||||||
margin: 0 12px 0 0;
|
letter-spacing: 1px;
|
||||||
|
margin: 0 0 5px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 14px;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
height: 85%;
|
||||||
|
width: 85%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.align-center {
|
||||||
|
display: flex;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.pl-1 {
|
||||||
|
padding-left: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
p {
|
||||||
|
font-size: 1rem;
|
||||||
|
margin-top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ion-item {
|
||||||
|
--background-hover: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.accordian-padding {
|
||||||
|
padding: 0.5rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media (max-width: 500px) {
|
||||||
|
.accordian-padding {
|
||||||
|
padding: 0.5rem 0 0.5rem 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -20,7 +20,7 @@ export module Mock {
|
|||||||
updated: true,
|
updated: true,
|
||||||
}
|
}
|
||||||
export const MarketplaceEos: RR.GetMarketplaceEosRes = {
|
export const MarketplaceEos: RR.GetMarketplaceEosRes = {
|
||||||
version: '0.3.3',
|
version: '0.3.4',
|
||||||
headline: 'Our biggest release ever.',
|
headline: 'Our biggest release ever.',
|
||||||
'release-notes': {
|
'release-notes': {
|
||||||
'0.3.3': 'Some **Markdown** release _notes_ for 0.3.3',
|
'0.3.3': 'Some **Markdown** release _notes_ for 0.3.3',
|
||||||
@@ -725,7 +725,7 @@ export module Mock {
|
|||||||
manifest: {
|
manifest: {
|
||||||
...Mock.MockManifestLnd,
|
...Mock.MockManifestLnd,
|
||||||
version: '0.11.1',
|
version: '0.11.1',
|
||||||
'release-notes': 'release notes for LND 0.11.0',
|
'release-notes': 'release notes for LND 0.11.1',
|
||||||
},
|
},
|
||||||
categories: ['bitcoin', 'lightning', 'cryptocurrency'],
|
categories: ['bitcoin', 'lightning', 'cryptocurrency'],
|
||||||
versions: ['0.11.0', '0.11.1'],
|
versions: ['0.11.0', '0.11.1'],
|
||||||
@@ -1838,9 +1838,9 @@ export module Mock {
|
|||||||
export const lnd: PackageDataEntry = {
|
export const lnd: PackageDataEntry = {
|
||||||
state: PackageState.Installed,
|
state: PackageState.Installed,
|
||||||
'static-files': {
|
'static-files': {
|
||||||
license: '/public/package-data/lnd/0.20.0/LICENSE.md',
|
license: '/public/package-data/lnd/0.11.0/LICENSE.md',
|
||||||
icon: '/assets/img/service-icons/lnd.png',
|
icon: '/assets/img/service-icons/lnd.png',
|
||||||
instructions: '/public/package-data/lnd/0.20.0/INSTRUCTIONS.md',
|
instructions: '/public/package-data/lnd/0.11.0/INSTRUCTIONS.md',
|
||||||
},
|
},
|
||||||
manifest: MockManifestLnd,
|
manifest: MockManifestLnd,
|
||||||
installed: {
|
installed: {
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ export const mockPatchData: DataModel = {
|
|||||||
},
|
},
|
||||||
'server-info': {
|
'server-info': {
|
||||||
id: 'abcdefgh',
|
id: 'abcdefgh',
|
||||||
version: '0.3.3',
|
version: '0.3.4',
|
||||||
'last-backup': new Date(new Date().valueOf() - 604800001).toISOString(),
|
'last-backup': new Date(new Date().valueOf() - 604800001).toISOString(),
|
||||||
'lan-address': 'https://embassy-abcdefgh.local',
|
'lan-address': 'https://embassy-abcdefgh.local',
|
||||||
'tor-address': 'http://myveryownspecialtoraddress.onion',
|
'tor-address': 'http://myveryownspecialtoraddress.onion',
|
||||||
@@ -476,7 +476,7 @@ export const mockPatchData: DataModel = {
|
|||||||
manifest: {
|
manifest: {
|
||||||
id: 'lnd',
|
id: 'lnd',
|
||||||
title: 'Lightning Network Daemon',
|
title: 'Lightning Network Daemon',
|
||||||
version: '0.11.1',
|
version: '0.11.0',
|
||||||
description: {
|
description: {
|
||||||
short: 'A bolt spec compliant client.',
|
short: 'A bolt spec compliant client.',
|
||||||
long: 'More info about LND. More info about LND. More info about LND.',
|
long: 'More info about LND. More info about LND. More info about LND.',
|
||||||
@@ -626,7 +626,10 @@ export const mockPatchData: DataModel = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
installed: {
|
installed: {
|
||||||
manifest: {} as Manifest,
|
manifest: {
|
||||||
|
...Mock.MockManifestLnd,
|
||||||
|
version: '0.11.0',
|
||||||
|
},
|
||||||
'last-backup': null,
|
'last-backup': null,
|
||||||
status: {
|
status: {
|
||||||
configured: true,
|
configured: true,
|
||||||
|
|||||||
@@ -25,7 +25,6 @@ export class ClientStorageService {
|
|||||||
constructor(private readonly storage: StorageService) {}
|
constructor(private readonly storage: StorageService) {}
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
console.log('EMBAWD', enableWidgets)
|
|
||||||
this.showDevTools$.next(!!this.storage.get(SHOW_DEV_TOOLS))
|
this.showDevTools$.next(!!this.storage.get(SHOW_DEV_TOOLS))
|
||||||
this.showDiskRepair$.next(!!this.storage.get(SHOW_DISK_REPAIR))
|
this.showDiskRepair$.next(!!this.storage.get(SHOW_DISK_REPAIR))
|
||||||
this.widgetDrawer$.next(
|
this.widgetDrawer$.next(
|
||||||
|
|||||||
@@ -1,29 +0,0 @@
|
|||||||
import { Injectable } from '@angular/core'
|
|
||||||
import { PatchDB } from 'patch-db-client'
|
|
||||||
import { combineLatest, filter, map, Observable } from 'rxjs'
|
|
||||||
import { DataModel } from './patch-db/data-model'
|
|
||||||
|
|
||||||
export interface ServerNameInfo {
|
|
||||||
current: string
|
|
||||||
default: string
|
|
||||||
}
|
|
||||||
|
|
||||||
@Injectable({ providedIn: 'root' })
|
|
||||||
export class ServerNameService {
|
|
||||||
private readonly chosenName$ = this.patch.watch$('ui', 'name')
|
|
||||||
private readonly hostname$ = this.patch.watch$('server-info', 'hostname')
|
|
||||||
|
|
||||||
readonly name$: Observable<ServerNameInfo> = combineLatest([
|
|
||||||
this.chosenName$,
|
|
||||||
this.hostname$,
|
|
||||||
]).pipe(
|
|
||||||
map(([chosen, hostname]) => {
|
|
||||||
return {
|
|
||||||
current: chosen || hostname,
|
|
||||||
default: hostname,
|
|
||||||
}
|
|
||||||
}),
|
|
||||||
)
|
|
||||||
|
|
||||||
constructor(private readonly patch: PatchDB<DataModel>) {}
|
|
||||||
}
|
|
||||||
@@ -1,13 +1,15 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<meta charset="utf-8" />
|
<meta charset="utf-8" />
|
||||||
<title>Embassy</title>
|
<title>embassyOS</title>
|
||||||
|
|
||||||
<base href="/" />
|
<base href="/" />
|
||||||
|
|
||||||
<meta name="viewport" content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no" />
|
<meta
|
||||||
|
name="viewport"
|
||||||
|
content="viewport-fit=cover, width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0, user-scalable=no"
|
||||||
|
/>
|
||||||
<meta name="format-detection" content="telephone=no" />
|
<meta name="format-detection" content="telephone=no" />
|
||||||
<meta name="msapplication-tap-highlight" content="no" />
|
<meta name="msapplication-tap-highlight" content="no" />
|
||||||
|
|
||||||
@@ -16,7 +18,8 @@
|
|||||||
|
|
||||||
<body>
|
<body>
|
||||||
<app-root></app-root>
|
<app-root></app-root>
|
||||||
<noscript>Please enable JavaScript to continue using this application.</noscript>
|
<noscript
|
||||||
|
>Please enable JavaScript to continue using this application.</noscript
|
||||||
|
>
|
||||||
</body>
|
</body>
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
|||||||
Reference in New Issue
Block a user