more styling

This commit is contained in:
Matt Hill
2021-07-02 13:56:34 -06:00
committed by Aiden McClelland
parent da3aa0a2a7
commit b16ef3c621
32 changed files with 314 additions and 271 deletions

View File

@@ -3,7 +3,7 @@
<ion-menu contentId="main-content" type="overlay">
<ion-header>
<ion-toolbar style="--background: var(--ion-background-color);">
<ion-title *ngIf="serverName; else dots">{{ serverName }}</ion-title>
<ion-title>Menu</ion-title>
<ng-template #dots>
<ion-title><ion-spinner name="dots" color="warning"></ion-spinner></ion-title>
</ng-template>

View File

@@ -1,5 +1,5 @@
.selected {
--background: linear-gradient(120deg, #1e1e1e -1%, var(--ion-color-start9) 100%);
--background: linear-gradient(120deg, #1e1e1e -1%, var(--ion-color-danger) 100%);
}
.menu-style {

View File

@@ -113,12 +113,8 @@ export class AppComponent {
}
watchPatch (): void {
combineLatest([
this.patch.watch$('ui', 'server-name'),
this.patch.watch$('server-info', 'unread-notification-count'),
])
.subscribe(([name, unread]) => {
this.serverName = name
this.patch.watch$('server-info', 'unread-notification-count')
.subscribe(unread => {
this.unreadCount = unread
})
}
@@ -233,7 +229,7 @@ export class AppComponent {
side: 'end',
text: 'View',
handler: () => {
this.router.navigate(['/notifications'])
this.router.navigate(['/notifications'], { queryParams: { toast: true } })
},
},
],

View File

@@ -1,14 +1,5 @@
// .ios-badge {
// background-color: var(--ion-color-start9);
// position: absolute;
// top: 1px;
// left: 62%;
// border-radius: 5px;
// z-index: 1;
// }
.md-badge {
background-color: var(--ion-color-start9);
background-color: var(--ion-color-danger);
position: absolute;
top: -8px;
left: 56%;

View File

@@ -2,12 +2,6 @@
margin: 0 16px;
}
.help-button {
position: relative;
bottom: 7px;
right: 9px;
}
.new-tag {
padding: 0px 5px;
font-weight: bold;

View File

@@ -9,7 +9,7 @@
{{ spec.name }}
</ion-title>
<ion-buttons *ngIf="!!saveFn" slot="end">
<ion-button [disabled]="!!error" (click)="save()" color="primary">
<ion-button [disabled]="!!error" (click)="save()">
Save
</ion-button>
</ion-buttons>
@@ -22,7 +22,7 @@
<ion-item-group>
<ion-item-divider>
<ion-button *ngIf="spec.type === 'string' && spec.copyable" style="padding-right: 12px;" size="small" slot="end" fill="clear" color="primary" (click)="copy()">
<ion-button *ngIf="spec.type === 'string' && spec.copyable" style="padding-right: 12px;" size="small" slot="end" fill="clear" (click)="copy()">
<ion-icon slot="icon-only" name="copy-outline" size="small"></ion-icon>
</ion-button>
</ion-item-divider>
@@ -73,7 +73,7 @@
</p>
<p *ngIf="spec.default !== undefined">
<ion-text color="medium">
<p>Default: {{ defaultDescription }} <ion-icon style="padding-left: 8px;" name="refresh-outline" color="primary" (click)="refreshDefault()"></ion-icon></p>
<p>Default: {{ defaultDescription }} <ion-icon style="padding-left: 8px;" name="refresh-outline" color="dark" style="cursor: pointer;" (click)="refreshDefault()"></ion-icon></p>
<p *ngIf="spec.type === 'number' && spec.units">Units: {{ spec.units }}</p>
</ion-text>
</p>

View File

@@ -7,41 +7,43 @@
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding-top">
<ng-container *ngIf="pkg">
<ion-card style="margin-bottom: 16px;" *ngFor="let interface of pkg.installed.manifest.interfaces | keyvalue: asIsOrder">
<ion-card-header>
<ion-card-title>
{{ interface.value.name }}
<ion-button class="vertical-align" *ngIf="interface.value.ui" [disabled]="!(pkg | isLaunchable)" fill="clear" (click)="launch(pkg.installed)">
<ion-icon slot="icon-only" name="rocket-outline" size="small"></ion-icon>
</ion-button>
</ion-card-title>
<ion-card-subtitle>{{ interface.value.description }}</ion-card-subtitle>
</ion-card-header>
<ion-card-content>
<ng-container *ngIf="pkg.installed['interface-info'].addresses[interface.key] as int">
<ion-item>
<ion-label class="ion-text-wrap">
<h2>Tor Address</h2>
<p>{{ 'http://' + int['tor-address'] }}</p>
</ion-label>
<ion-button slot="end" fill="clear" (click)="copy('http://' + int['tor-address'])">
<ion-icon size="small" slot="icon-only" name="copy-outline"></ion-icon>
</ion-button>
</ion-item>
<ion-item>
<ion-label class="ion-text-wrap">
<h2>LAN Address</h2>
<p>{{ 'https://' + int['lan-address'] }}</p>
</ion-label>
<ion-button slot="end" fill="clear" (click)="copy('https://' + int['lan-address'])">
<ion-icon size="small" slot="icon-only" name="copy-outline"></ion-icon>
</ion-button>
</ion-item>
</ng-container>
</ion-card-content>
</ion-card>
</ng-container>
<ion-content>
<ion-grid *ngIf="pkg">
<ion-row>
<ion-col *ngFor="let interface of pkg.installed.manifest.interfaces | keyvalue: asIsOrder" sizeSm="12" sizeMd="6">
<ion-card>
<ion-card-header>
<ion-card-title>{{ interface.value.name }}</ion-card-title>
<ion-card-subtitle>{{ interface.value.description }}</ion-card-subtitle>
<ion-button style="margin-top: 12px;" *ngIf="interface.value.ui" [disabled]="!(pkg | isLaunchable)" fill="outline" color="dark" expand="block" (click)="launch(pkg.installed)">
Launch
<ion-icon slot="end" name="rocket-outline"></ion-icon>
</ion-button>
</ion-card-header>
<ion-card-content>
<ng-container *ngIf="pkg.installed['interface-info'].addresses[interface.key] as int">
<ion-item>
<ion-label class="ion-text-wrap">
<h2>Tor Address</h2>
<p>{{ 'http://' + int['tor-address'] }}</p>
</ion-label>
<ion-button slot="end" fill="clear" (click)="copy('http://' + int['tor-address'])">
<ion-icon size="small" slot="icon-only" name="copy-outline"></ion-icon>
</ion-button>
</ion-item>
<ion-item>
<ion-label class="ion-text-wrap">
<h2>LAN Address</h2>
<p>{{ 'https://' + int['lan-address'] }}</p>
</ion-label>
<ion-button slot="end" fill="clear" (click)="copy('https://' + int['lan-address'])">
<ion-icon size="small" slot="icon-only" name="copy-outline"></ion-icon>
</ion-button>
</ion-item>
</ng-container>
</ion-card-content>
</ion-card>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>

View File

@@ -11,7 +11,7 @@
<div *ngIf="pkgs | empty; else list" class="ion-text-center ion-padding">
<div style="display: flex; flex-direction: column; justify-content: center; height: 40vh">
<h2>Welcome to your <span style="font-style: italic; color: var(--ion-color-start9)">Embassy</span></h2>
<h2>Welcome to your <span style="font-style: italic; color: var(--ion-color-danger)">Embassy</span></h2>
<p class="ion-text-wrap">Get started by installing your first service.</p>
</div>
<ion-button [routerLink]="['/marketplace']" style="width: 50%;" fill="outline">
@@ -24,7 +24,7 @@
<ion-grid>
<ion-row>
<ion-col *ngFor="let pkg of pkgs | keyvalue : asIsOrder" sizeXs="4" sizeSm="3" sizeLg="3" sizeXl="2">
<ion-card class="installed-card" style="position:relative" [routerLink]="['/services', (pkg.value | manifest).id]">
<ion-card class="installed-card" [routerLink]="['/services', (pkg.value | manifest).id]">
<div class="launch-container" *ngIf="pkg.value | hasUi">
<div class="launch-button-triangle" (click)="launchUi(pkg.value, $event)" [class.launch-disabled]="!(pkg.value | isLaunchable)">
<ion-icon name="rocket-outline"></ion-icon>

View File

@@ -1,5 +1,5 @@
.installed-card {
margin: 0;
margin: 2px;
background: linear-gradient(37deg, #333333, #131313);
border-radius: 10px;
text-align: center;
@@ -13,7 +13,7 @@
ion-card-title {
font-size: calc(10px + .4vw);
color: white;
color: var(--ion-color-dark);
margin: 10px 0;
white-space: nowrap;
overflow: hidden;
@@ -24,8 +24,7 @@
.main-img {
width: 50%;
margin: 9px;
color: white;
margin: 12px;
border-radius: var(--icon-border-radius);
}
@@ -48,10 +47,7 @@
}
.launch-button-triangle {
width: 0px;
height: 0px;
right: 0px;
margin: 0px;
border-style: solid;
border-width: 22px;
@@ -81,6 +77,4 @@
.launch-container {
position: absolute;
right: 0px;
top: 0px;
margin: 0px;
}

View File

@@ -4,7 +4,7 @@
<pwa-back-button></pwa-back-button>
</ion-buttons>
<ion-title>Logs</ion-title>
<ion-buttons slot="end" class="ion-padding-end">
<ion-buttons slot="end">
<ion-button (click)="getLogs()">
<ion-icon slot="icon-only" name="refresh-outline"></ion-icon>
</ion-button>

View File

@@ -3,8 +3,8 @@
<ion-buttons slot="start">
<pwa-back-button></pwa-back-button>
</ion-buttons>
<ion-title>Values</ion-title>
<ion-buttons slot="end" class="ion-padding-end">
<ion-title>Properties</ion-title>
<ion-buttons slot="end">
<ion-button (click)="refresh()">
<ion-icon slot="icon-only" name="refresh-outline"></ion-icon>
</ion-button>
@@ -30,7 +30,7 @@
<!-- no properties -->
<ion-item *ngIf="properties | empty">
<ion-label class="ion-text-wrap">
<p>No values.</p>
<p>No properties.</p>
</ion-label>
</ion-item>
@@ -39,8 +39,8 @@
<div *ngFor="let prop of node | keyvalue: asIsOrder">
<!-- object -->
<ion-item button detail="true" *ngIf="prop.value.type === 'object'" (click)="goToNested(prop.key)">
<ion-button *ngIf="prop.value.description" class="help-button" fill="clear" slot="start" (click)="presentDescription(prop, $event)">
<ion-icon size="small" slot="icon-only" name="help-circle-outline"></ion-icon>
<ion-button *ngIf="prop.value.description" fill="clear" slot="start" (click)="presentDescription(prop, $event)">
<ion-icon slot="icon-only" name="help-circle-outline"></ion-icon>
</ion-button>
<ion-label class="ion-text-wrap">
<h2>{{ prop.key }}</h2>
@@ -48,8 +48,8 @@
</ion-item>
<!-- not object -->
<ion-item *ngIf="prop.value.type === 'string'">
<ion-button *ngIf="prop.value.description" class="help-button" fill="clear" slot="start" (click)="presentDescription(prop, $event)">
<ion-icon size="small" slot="icon-only" name="help-circle-outline"></ion-icon>
<ion-button *ngIf="prop.value.description" fill="clear" slot="start" (click)="presentDescription(prop, $event)">
<ion-icon slot="icon-only" name="help-circle-outline"></ion-icon>
</ion-button>
<ion-label class="ion-text-wrap">
<h2>{{ prop.key }}</h2>
@@ -57,13 +57,13 @@
</ion-label>
<div slot="end" *ngIf="prop.value.copyable || prop.value.qr">
<ion-button *ngIf="prop.value.masked" fill="clear" (click)="toggleMask(prop.key)">
<ion-icon slot="icon-only" [name]="unmasked[prop.key] ? 'eye-off-outline' : 'eye-outline'" [color]="unmasked[prop.key] ? 'danger' : 'primary'" size="small"></ion-icon>
<ion-icon slot="icon-only" [name]="unmasked[prop.key] ? 'eye-off-outline' : 'eye-outline'" [color]="unmasked[prop.key] ? 'danger' : 'dark'" size="small"></ion-icon>
</ion-button>
<ion-button *ngIf="prop.value.qr" fill="clear" (click)="showQR(prop.value.value)">
<ion-icon slot="icon-only" name="qr-code-outline" size="small" color="primary"></ion-icon>
<ion-icon slot="icon-only" name="qr-code-outline" size="small"></ion-icon>
</ion-button>
<ion-button *ngIf="prop.value.copyable" fill="clear" (click)="copy(prop.value.value)">
<ion-icon slot="icon-only" name="copy-outline" size="small" color="primary"></ion-icon>
<ion-icon slot="icon-only" name="copy-outline" size="small"></ion-icon>
</ion-button>
</div>
</ion-item>

View File

@@ -3,8 +3,8 @@
<ion-buttons slot="start">
<pwa-back-button></pwa-back-button>
</ion-buttons>
<ion-title>Restore Backup</ion-title>
<ion-buttons slot="end" class="ion-padding-end">
<ion-title>Restore From Backup</ion-title>
<ion-buttons slot="end">
<ion-button (click)="refresh()">
<ion-icon slot="icon-only" name="refresh-outline"></ion-icon>
</ion-button>
@@ -27,49 +27,52 @@
<ion-item *ngIf="error" style="margin-bottom: 16px;">
<ion-text class="ion-text-wrap" color="danger">{{ error }}</ion-text>
</ion-item>
<ion-item class="ion-margin-bottom">
<ion-label class="ion-text-wrap">
<p><ion-text color="dark">About</ion-text></p>
<p>
Select a location from which to restore {{ title }}. This will overwrite all current data.
</p>
<p class="ion-padding-bottom"><ion-text color="warning">Warning</ion-text></p>
<h2>
Restoring from backup will overwrite all current data for {{ title }} .
</h2>
</ion-label>
</ion-item>
<ion-spinner *ngIf="loading; else loaded" name="lines" color="warning" class="center"></ion-spinner>
<ng-template #loaded>
<ion-item *ngIf="allPartitionsMounted">
<ion-text *ngIf="type === 'restore'" class="ion-text-wrap" color="warning">No partitions available. Insert the storage device containing the backup you intend to restore.</ion-text>
</ion-item>
<ion-card *ngFor="let disk of disks | keyvalue">
<ion-card-header>
<ion-card-title>
{{ disk.value.size }}
</ion-card-title>
<ion-card-subtitle>
{{ disk.key }}
</ion-card-subtitle>
</ion-card-header>
<ion-card-content>
<ion-item-group>
<ion-item button *ngFor="let partition of disk.value.partitions | keyvalue" [disabled]="partition.value['is-mounted']" (click)="presentModal(partition.key, partition.value)">
<ion-icon slot="start" name="save-outline"></ion-icon>
<ion-label>
<h2>{{ partition.value.label || partition.key }} ({{ partition.value.size || 'unknown size' }})</h2>
<p *ngIf="!partition.value['is-mounted']; else unavailable"><ion-text color="success">Available</ion-text></p>
<ng-template #unavailable>
<p><ion-text color="danger">Unavailable</ion-text></p>
</ng-template>
</ion-label>
</ion-item>
</ion-item-group>
</ion-card-content>
</ion-card>
</ng-template>
<ion-item-divider>Select Backup Drive</ion-item-divider>
<ion-item *ngIf="allPartitionsMounted">
<ion-text class="ion-text-wrap" color="warning">No partitions available. Insert the storage device containing the backup you intend to restore.</ion-text>
</ion-item>
<ion-grid>
<ion-row>
<ion-col *ngFor="let disk of disks | keyvalue" sizeSm="12" sizeMd="6">
<ion-card>
<ion-card-header>
<ion-card-title>
{{ disk.value.size }}
</ion-card-title>
<ion-card-subtitle>
{{ disk.key }}
</ion-card-subtitle>
</ion-card-header>
<ion-card-content>
<ion-item-group>
<ion-item button *ngFor="let partition of disk.value.partitions | keyvalue" [disabled]="partition.value['is-mounted']" (click)="presentModal(partition.key, partition.value)">
<ion-icon slot="start" name="save-outline"></ion-icon>
<ion-label>
<h2>{{ partition.value.label || partition.key }} ({{ partition.value.size || 'unknown size' }})</h2>
<p *ngIf="!partition.value['is-mounted']; else unavailable"><ion-text color="success">Available</ion-text></p>
<ng-template #unavailable>
<p><ion-text color="danger">Unavailable</ion-text></p>
</ng-template>
</ion-label>
</ion-item>
</ion-item-group>
</ion-card-content>
</ion-card>
</ion-col>
</ion-row>
</ion-grid>
</ng-template>
</ion-content>

View File

@@ -19,39 +19,30 @@
<ng-container *ngIf="pkg">
<!-- top plate -->
<div class="top-plate">
<ion-item class="no-cushion-item" lines="none">
<ion-label class="ion-text-wrap" style="
display: grid;
grid-template-columns: 80px auto;
margin: 0px;
margin-top: 15px;"
>
<ion-avatar style="justify-self: center; height: 55px; width: 55px" slot="start">
<img [src]="pkg['static-files'].icon" />
</ion-avatar>
<div style="display: flex; flex-direction: column;">
<ion-text style="font-family: 'Montserrat'; font-size: x-large; line-height: normal;" [class.less-large]="manifest.title.length > 20">
{{ manifest.title }}
</ion-text>
<ion-text style="margin-top: -5px; margin-left: 2px;">
{{ manifest.version | displayEmver }}
</ion-text>
</div>
<ion-item lines="none">
<ion-thumbnail slot="start">
<img [src]="pkg['static-files'].icon" />
</ion-thumbnail>
<ion-label class="ion-text-wrap">
<h1 style="font-family: 'Montserrat';" [class.less-large]="manifest.title.length > 20">
{{ manifest.title }}
</h1>
<h5>{{ manifest.version | displayEmver }}</h5>
</ion-label>
</ion-item>
<div class="status-readout">
<status *ngIf="connected" size="large" weight="bold" [pkg]="pkg"></status>
<ion-button *ngIf="pkg.status === FeStatus.NeedsConfig" expand="block" fill="outline" [routerLink]="['config']">
<status *ngIf="connected" size="large" weight="500" [pkg]="pkg"></status>
<ion-button *ngIf="pkg.status === FeStatus.NeedsConfig" expand="block" [routerLink]="['config']">
Configure
</ion-button>
<ion-button *ngIf="[FeStatus.Running, FeStatus.StartingUp, FeStatus.NeedsAttention] | includes : pkg.status" expand="block" fill="outline" color="danger" (click)="stop()">
<ion-button *ngIf="[FeStatus.Running, FeStatus.StartingUp, FeStatus.NeedsAttention] | includes : pkg.status" expand="block" color="danger" (click)="stop()">
Stop
</ion-button>
<ion-button *ngIf="pkg.status === FeStatus.DependencyIssue" expand="block" fill="outline" (click)="scrollToRequirements()">
<ion-button *ngIf="pkg.status === FeStatus.DependencyIssue" expand="block" (click)="scrollToRequirements()">
Fix
</ion-button>
<ion-button *ngIf="pkg.status === FeStatus.Stopped" expand="block" fill="outline" color="success" (click)="tryStart()">
<ion-button *ngIf="pkg.status === FeStatus.Stopped" expand="block" color="success" (click)="tryStart()">
Start
</ion-button>
</div>

View File

@@ -5,20 +5,24 @@
.top-plate {
background: var(--ion-item-background);
margin: 0 16px;
padding: 12px;
border-radius: 10px;
border-style: solid;
border-color: #373737;
ion-item {
border-radius: 10px;
}
}
.status-readout {
--background: transparent;
display: flex;
justify-content: space-between;
padding: 0 10px;
padding: 8px 16px;
border-radius: 10px;
align-items: center;
background: var(--ion-background-color);
margin: 10px 10px 0px 10px;
margin: 10px;
border-style: solid;
border-width: 1px;
border-color: #404040;
@@ -39,18 +43,3 @@
border-style: solid;
border-color: #404040;
}
.dep-issue {
background: radial-gradient(var(--ion-color-warning) 40%, transparent)
}
.dep-sat {
background: radial-gradient(var(--ion-color-success) 40%, transparent)
}
ion-item-divider {
text-transform: uppercase;
margin-top: 22px;
font-weight: 400;
}

View File

@@ -239,7 +239,7 @@ export class AppShowPage {
},
{
action: () => this.navCtrl.navigateForward(['properties'], { relativeTo: this.route }),
title: 'Values',
title: 'Properties',
icon: 'briefcase-outline',
color: 'danger',
disabled: [],
@@ -267,7 +267,7 @@ export class AppShowPage {
},
{
action: () => this.navCtrl.navigateForward(['restore'], { relativeTo: this.route }),
title: 'Restore Backup',
title: 'Restore From Backup',
icon: 'color-wand-outline',
color: 'danger',
disabled: [FEStatus.Connecting, FEStatus.Installing, FEStatus.Updating, FEStatus.Stopping, FEStatus.Removing, FEStatus.BackingUp, FEStatus.Restoring],

View File

@@ -3,7 +3,7 @@
<ion-buttons slot="start">
<pwa-back-button></pwa-back-button>
</ion-buttons>
<ion-title>Version History</ion-title>
<ion-title>Release Notes</ion-title>
</ion-toolbar>
</ion-header>

View File

@@ -14,14 +14,14 @@ export class AppReleaseNotes {
constructor (
private readonly route: ActivatedRoute,
public aaService: MarketplaceService,
public marketplaceService: MarketplaceService,
) { }
ngOnInit () {
this.pkgId = this.route.snapshot.paramMap.get('pkgId')
const version = this.route.snapshot.paramMap.get('version')
if (!this.aaService.pkgs[this.pkgId]) {
this.aaService.setPkg(this.pkgId, version)
if (!this.marketplaceService.pkgs[this.pkgId]) {
this.marketplaceService.setPkg(this.pkgId, version)
}
}

View File

@@ -96,7 +96,7 @@
<ion-item-divider>
New in {{ pkg.manifest.version | displayEmver }}
<ion-button [routerLink]="['notes']" style="position: absolute; right: 10px;" fill="clear" color="dark">
Release History
All Release Notes
<ion-icon slot="end" name="arrow-forward-outline"></ion-icon>
</ion-button>
</ion-item-divider>
@@ -109,9 +109,7 @@
<ion-item-divider>Description</ion-item-divider>
<ion-item lines="none" color="transparent">
<ion-label class="ion-text-wrap">
<ion-text>
<h5>{{ pkg.manifest.description.long }}</h5>
</ion-text>
<div id="release-notes" class="release-notes">{{ pkg.manifest.description.long }}</div>
</ion-label>
</ion-item>
<!-- dependencies -->
@@ -137,14 +135,97 @@
</ion-row>
</ion-grid>
</ng-container>
<!-- versions -->
<ion-item-divider>Additional Information</ion-item-divider>
<ion-item lines="none" button (click)="presentAlertVersions()" color="transparent">
<ion-icon color="dark" slot="start" name="file-tray-stacked-outline"></ion-icon>
<ion-label color="dark">Other versions</ion-label>
</ion-item>
</ion-item-group>
<ion-item-divider>Additional Info</ion-item-divider>
<ion-card>
<ion-grid>
<ion-row>
<ion-col sizeSm="12" sizeMd="6">
<ion-item-group>
<ion-item detail="false">
<ion-label>
<h2>Service ID</h2>
<p>{{ pkg.manifest.id }}</p>
</ion-label>
</ion-item>
<ion-item detail="false">
<ion-label>
<h2>Categories</h2>
<p>{{ pkg.categories.join(', ') }}</p>
</ion-label>
</ion-item>
<ion-item detail="false">
<ion-label>
<h2>Other Versions</h2>
<p>Click to view other versions</p>
</ion-label>
<ion-button slot="end" fill="clear" (click)="presentAlertVersions()">
<ion-icon slot="icon-only" name="chevron-forward-outline"></ion-icon>
</ion-button>
</ion-item>
<ion-item detail="false">
<ion-label>
<h2>License</h2>
<p>{{ pkg.manifest.license }}</p>
</ion-label>
<ion-button slot="end" fill="clear" (click)="presentModalLicense()">
<ion-icon slot="icon-only" name="chevron-forward-outline"></ion-icon>
</ion-button>
</ion-item>
</ion-item-group>
</ion-col>
<ion-col>
<ion-item-group>
<ion-item detail="false">
<ion-label>
<h2>Source Repository</h2>
<p>{{ pkg.manifest['upstream-repo'] }}</p>
</ion-label>
<ion-button slot="end" fill="clear" [href]="pkg.manifest['upstream-repo']" target="_blank">
<ion-icon slot="icon-only" name="open-outline"></ion-icon>
</ion-button>
</ion-item>
<ion-item detail="false">
<ion-label>
<h2>Wrapper Repository</h2>
<p>{{ pkg.manifest['wrapper-repo'] }}</p>
</ion-label>
<ion-button slot="end" fill="clear" [href]="pkg.manifest['wrapper-repo']" target="_blank">
<ion-icon slot="icon-only" name="open-outline"></ion-icon>
</ion-button>
</ion-item>
<ion-item detail="false">
<ion-label>
<h2>Support Site</h2>
<p>{{ pkg.manifest['support-site'] }}</p>
</ion-label>
<ion-button slot="end" fill="clear" [href]="pkg.manifest['support-site']" target="_blank">
<ion-icon slot="icon-only" name="open-outline"></ion-icon>
</ion-button>
</ion-item>
<ion-item detail="false">
<ion-label>
<h2>Marketing Site</h2>
<p>{{ pkg.manifest['marketing-site'] }}</p>
</ion-label>
<ion-button slot="end" fill="clear" [href]="pkg.manifest['marketing-site']" target="_blank">
<ion-icon slot="icon-only" name="open-outline"></ion-icon>
</ion-button>
</ion-item>
<ion-item *ngIf="pkg.manifest['donation-url'] as donationUrl" detail="false">
<ion-label>
<h2>Donation Site</h2>
<p>{{ donationUrl }}</p>
</ion-label>
<ion-button slot="end" fill="clear" [href]="donationUrl" target="_blank">
<ion-icon slot="icon-only" name="open-outline"></ion-icon>
</ion-button>
</ion-item>
</ion-item-group>
</ion-col>
</ion-row>
</ion-grid>
</ion-card>
</ng-container>
</ion-content>
</ion-content>

View File

@@ -35,13 +35,7 @@
color: var(--ion-color-danger);
}
ion-item-divider {
text-transform: uppercase;
margin-top: 22px;
font-weight: 400;
}
#release-notes {
overflow: auto;
max-height: 160px;
max-height: 120px;
}

View File

@@ -7,6 +7,7 @@ import { ApiService } from 'src/app/services/api/api.service'
})
export class MarketplaceService {
pkgs: { [id: string]: AvailableShow } = { }
additionalInfo
constructor (
private readonly apiService: ApiService,

View File

@@ -1,6 +1,6 @@
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<ion-buttons slot="start" *ngIf="fromToast">
<pwa-back-button></pwa-back-button>
</ion-buttons>
<ion-title>Notifications</ion-title>

View File

@@ -3,6 +3,7 @@ import { ApiService } from 'src/app/services/api/api.service'
import { LoaderService } from 'src/app/services/loader.service'
import { ServerNotification, ServerNotifications } from 'src/app/services/api/api-types'
import { AlertController } from '@ionic/angular'
import { ActivatedRoute } from '@angular/router'
@Component({
selector: 'notifications',
@@ -15,15 +16,18 @@ export class NotificationsPage {
notifications: ServerNotifications = []
page = 1
needInfinite = false
fromToast = false
readonly perPage = 20
constructor (
private readonly apiService: ApiService,
private readonly loader: LoaderService,
private readonly alertCtrl: AlertController,
private readonly route: ActivatedRoute,
) { }
async ngOnInit () {
this.fromToast = !!this.route.snapshot.queryParamMap.get('toast')
this.notifications = await this.getNotifications()
this.loading = false
}

View File

@@ -4,7 +4,7 @@
<pwa-back-button></pwa-back-button>
</ion-buttons>
<ion-title>SSH Keys</ion-title>
<ion-buttons slot="end" class="ion-padding-end">
<ion-buttons slot="end">
<ion-button (click)="presentModalAdd()">
<ion-icon slot="icon-only" name="add-outline"></ion-icon>
</ion-button>

View File

@@ -13,7 +13,7 @@
<!-- about -->
<ion-item>
<ion-label class="ion-text-wrap">
<p style="padding-bottom: 6px;">About</p>
<p class="ion-padding-bottom">About</p>
<h2>You can connect to your Embassy over your Local Area Network (LAN). This can be useful for achieving a faster experience, as well as a fallback in case the Tor network is experiencing issues.</h2>
</ion-label>
</ion-item>
@@ -26,7 +26,7 @@
<ion-item-divider></ion-item-divider>
<ion-item>
<ion-label class="ion-text-wrap">
<p style="padding-bottom: 4px;">Setup</p>
<p class="ion-padding-bottom">Setup</p>
<ion-text color="warning" [innerHtml]="lanDisabledExplanation[lanDisabled]"></ion-text>
</ion-label>
</ion-item>

View File

@@ -1,3 +0,0 @@
.tiny-icon {
font-size: 12px;
}

View File

@@ -4,7 +4,7 @@
<pwa-back-button></pwa-back-button>
</ion-buttons>
<ion-title>Create Backup</ion-title>
<ion-buttons slot="end" class="ion-padding-end">
<ion-buttons slot="end">
<ion-button (click)="doRefresh()">
<ion-icon slot="icon-only" name="refresh-outline"></ion-icon>
</ion-button>
@@ -18,52 +18,56 @@
<ion-text class="ion-text-wrap" color="danger">{{ error }}</ion-text>
</ion-item>
<ion-item class="ion-margin-bottom">
<ion-label class="ion-text-wrap">
<p><ion-text color="dark">About</ion-text></p>
<p>
Select a location to back up your Embassy. Because are diff-based, so your first backup will likely take much longer than subsequent backups.
</p>
<br />
<p>
During backup, your Embassy will be unusable.
</p>
</ion-label>
</ion-item>
<ion-spinner *ngIf="loading; else loaded" name="lines" color="warning" class="center"></ion-spinner>
<ng-template #loaded>
<ion-item class="ion-margin-bottom">
<ion-label class="ion-text-wrap">
<p class="ion-padding-bottom">About</p>
<h2>
Create frequent backups of your Embassy to avoid loss of data.
</h2>
</ion-label>
</ion-item>
<ion-item-divider>Select Backup Drive</ion-item-divider>
<ion-item *ngIf="allPartitionsMounted">
<ion-text *ngIf="type === 'create'" class="ion-text-wrap" color="warning">No partitions available. To begin a backup, insert a storage device into your Embassy.</ion-text>
<ion-text *ngIf="type === 'restore'" class="ion-text-wrap" color="warning">No partitions available. Insert the storage device containing the backup you wish to restore.</ion-text>
</ion-item>
<ion-card *ngFor="let disk of disks | keyvalue">
<ion-card-header>
<ion-card-title>
{{ disk.value.size }}
</ion-card-title>
<ion-card-subtitle>
{{ disk.key }}
</ion-card-subtitle>
</ion-card-header>
<ion-card-content>
<ion-item-group>
<ion-item button *ngFor="let partition of disk.value.partitions | keyvalue" [disabled]="partition.value['is-mounted']" (click)="presentModal(partition.key, partition.value)">
<ion-icon slot="start" name="save-outline"></ion-icon>
<ion-label>
<h2>{{ partition.value.label || partition.key }} ({{ partition.value.size || 'unknown size' }})</h2>
<p *ngIf="!partition.value['is-mounted']; else unavailable"><ion-text color="success">Available</ion-text></p>
<ng-template #unavailable>
<p><ion-text color="danger">Unavailable</ion-text></p>
</ng-template>
</ion-label>
</ion-item>
</ion-item-group>
</ion-card-content>
</ion-card>
<ion-grid>
<ion-row>
<ion-col *ngFor="let disk of disks | keyvalue" sizeSm="12" sizeMd="6">
<ion-card>
<ion-card-header>
<ion-card-title>
{{ disk.value.size }}
</ion-card-title>
<ion-card-subtitle>
{{ disk.key }}
</ion-card-subtitle>
</ion-card-header>
<ion-card-content>
<ion-item-group>
<ion-item button *ngFor="let partition of disk.value.partitions | keyvalue" [disabled]="partition.value['is-mounted']" (click)="presentModal(partition.key, partition.value)">
<ion-icon slot="start" name="save-outline"></ion-icon>
<ion-label>
<h2>{{ partition.value.label || partition.key }} ({{ partition.value.size || 'unknown size' }})</h2>
<p *ngIf="!partition.value['is-mounted']; else unavailable"><ion-text color="success">Available</ion-text></p>
<ng-template #unavailable>
<p><ion-text color="danger">Unavailable</ion-text></p>
</ng-template>
</ion-label>
</ion-item>
</ion-item-group>
</ion-card-content>
</ion-card>
</ion-col>
</ion-row>
</ion-grid>
</ng-template>
</ion-content>

View File

@@ -4,7 +4,7 @@
<pwa-back-button></pwa-back-button>
</ion-buttons>
<ion-title>Logs</ion-title>
<ion-buttons slot="end" class="ion-padding-end">
<ion-buttons slot="end">
<ion-button (click)="getLogs()">
<ion-icon slot="icon-only" name="refresh-outline"></ion-icon>
</ion-button>

View File

@@ -27,7 +27,7 @@
<p>http://{{ server['tor-address'] }}</p>
</ion-label>
<ion-button slot="end" fill="clear" (click)="copy('http://' + server['tor-address'])">
<ion-icon slot="icon-only" name="copy-outline" color="primary"></ion-icon>
<ion-icon slot="icon-only" name="copy-outline"></ion-icon>
</ion-button>
</ion-item>
<ion-item>
@@ -36,7 +36,7 @@
<p>https://{{ server['lan-address'] }}</p>
</ion-label>
<ion-button slot="end" fill="clear" (click)="copy('https://' + server['lan-address'])">
<ion-icon slot="icon-only" name="copy-outline" color="primary"></ion-icon>
<ion-icon slot="icon-only" name="copy-outline"></ion-icon>
</ion-button>
</ion-item>

View File

@@ -4,7 +4,7 @@
<pwa-back-button></pwa-back-button>
</ion-buttons>
<ion-title>WiFi Settings</ion-title>
<ion-buttons slot="end" class="ion-padding-end">
<ion-buttons slot="end">
<ion-button [routerLink]="['add']">
<ion-icon slot="icon-only" name="add-outline"></ion-icon>
</ion-button>

View File

@@ -410,9 +410,9 @@ export module Mock {
versions: ['0.19.0', '0.20.0', '0.21.0'],
'dependency-metadata': { },
'release-notes': {
'0.19.0': 'release notes for Bitcoin 0.19.0',
'0.19.1': 'release notes for Bitcoin 0.19.1',
'0.19.2': 'Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32.',
'0.19.1': 'release notes for Bitcoin 0.19.1',
'0.19.0': 'release notes for Bitcoin 0.19.0',
},
},
'0.20.0': {
@@ -425,9 +425,9 @@ export module Mock {
versions: ['0.19.0', '0.20.0', '0.21.0'],
'dependency-metadata': { },
'release-notes': {
'0.19.0': 'release notes for Bitcoin 0.19.0',
'0.19.1': 'release notes for Bitcoin 0.19.1',
'0.19.2': 'Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32.',
'0.19.1': 'release notes for Bitcoin 0.19.1',
'0.19.0': 'release notes for Bitcoin 0.19.0',
},
},
'0.21.0': {
@@ -441,9 +441,9 @@ export module Mock {
versions: ['0.19.0', '0.20.0', '0.21.0'],
'dependency-metadata': { },
'release-notes': {
'0.19.0': 'release notes for Bitcoin 0.19.0',
'0.19.1': 'release notes for Bitcoin 0.19.1',
'0.19.2': 'Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32.',
'0.19.1': 'release notes for Bitcoin 0.19.1',
'0.19.0': 'release notes for Bitcoin 0.19.0',
},
},
'latest': {
@@ -456,9 +456,9 @@ export module Mock {
versions: ['0.19.0', '0.20.0', '0.21.0'],
'dependency-metadata': { },
'release-notes': {
'0.19.2': 'release notes for Bitcoin 0.19.2',
'0.20.0': 'release notes for Bitcoin 0.20.0',
'0.21.0': 'Contrary to popular belief, Lorem Ipsum is not simply random text. It has roots in a piece of classical Latin literature from 45 BC, making it over 2000 years old. Richard McClintock, a Latin professor at Hampden-Sydney College in Virginia, looked up one of the more obscure Latin words, consectetur, from a Lorem Ipsum passage, and going through the cites of the word in classical literature, discovered the undoubtable source. Lorem Ipsum comes from sections 1.10.32 and 1.10.33 of "de Finibus Bonorum et Malorum" (The Extremes of Good and Evil) by Cicero, written in 45 BC. This book is a treatise on the theory of ethics, very popular during the Renaissance. The first line of Lorem Ipsum, "Lorem ipsum dolor sit amet..", comes from a line in section 1.10.32.',
'0.20.0': 'release notes for Bitcoin 0.20.0',
'0.19.2': 'release notes for Bitcoin 0.19.2',
},
},
},
@@ -483,9 +483,9 @@ export module Mock {
},
},
'release-notes': {
'0.19.0': 'release notes for LND 0.19.0',
'0.19.1': 'release notes for LND 0.19.1',
'0.19.2': 'release notes for LND 0.19.2',
'0.19.1': 'release notes for LND 0.19.1',
'0.19.0': 'release notes for LND 0.19.0',
},
},
'0.11.1': {
@@ -508,9 +508,9 @@ export module Mock {
},
},
'release-notes': {
'0.19.0': 'release notes for LND 0.19.0',
'0.19.1': 'release notes for LND 0.19.1',
'0.19.2': 'release notes for LND 0.19.2',
'0.19.1': 'release notes for LND 0.19.1',
'0.19.0': 'release notes for LND 0.19.0',
},
},
'latest': {
@@ -529,9 +529,9 @@ export module Mock {
},
},
'release-notes': {
'0.19.0': 'release notes for LND 0.19.0',
'0.19.1': 'release notes for LND 0.19.1',
'0.19.2': 'release notes for LND 0.19.2',
'0.19.1': 'release notes for LND 0.19.1',
'0.19.0': 'release notes for LND 0.19.0',
},
},
},
@@ -548,9 +548,9 @@ export module Mock {
},
},
'release-notes': {
'0.19.0': 'release notes for btc proxy 0.19.0',
'0.19.1': 'release notes for btc proxy 0.19.1',
'0.19.2': 'release notes for btc proxy 0.19.2',
'0.19.1': 'release notes for btc proxy 0.19.1',
'0.19.0': 'release notes for btc proxy 0.19.0',
},
},
},

View File

@@ -47,21 +47,10 @@
z-index: 40000 !important;
}
.alert-danger {
color: var(--ion-color-danger) !important;
& ion-icon {
color: var(--ion-color-danger) !important;
}
}
.borderless {
border-style: none;
}
.help-button {
margin: 0 8px 0 0;
}
.item-interactive {
--highlight-background: transparent !important;
}
@@ -95,6 +84,7 @@
}
ion-card-title {
color: var(--ion-color-dark);
font-family: 'Montserrat';
}
@@ -120,6 +110,9 @@ ion-badge {
ion-item-divider {
--background: transparent;
text-transform: uppercase;
margin-top: 16px;
font-weight: 400;
}
ion-infinite-scroll ion-infinite-scroll-content {
@@ -132,6 +125,13 @@ ion-action-sheet {
ion-alert {
--backdrop-opacity: 0.75 !important;
.alert-button {
color: var(--ion-color-dark) !important;
}
}
ion-button {
--color: var(--ion-color-dark) !important;
}
ion-loading {
@@ -292,3 +292,7 @@ ion-item-divider {
width: 16px !important;
height: 16px !important;
}
h2 {
line-height: unset;
}

View File

@@ -142,8 +142,6 @@ body.dark {
--ion-color-light-contrast-rgb: 255,255,255;
--ion-color-light-shade: #1e2023;
--ion-color-light-tint: #383a3e;
--ion-color-start9: #FF4960;
}
/*