mirror of
https://github.com/Start9Labs/start-os.git
synced 2026-03-30 20:14:49 +00:00
revamp wifi, fix error messaging in forms
This commit is contained in:
committed by
Aiden McClelland
parent
bcb6d9d673
commit
62b523ebde
@@ -5,7 +5,7 @@ import { IonicModule } from '@ionic/angular'
|
||||
import { AppActionsPage, AppActionsItemComponent } from './app-actions.page'
|
||||
import { QRComponentModule } from 'src/app/components/qr/qr.component.module'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
import { AppActionInputPageModule } from 'src/app/modals/app-action-input/app-action-input.module'
|
||||
import { GenericFormPageModule } from 'src/app/modals/generic-form/generic-form.module'
|
||||
import { AppRestoreComponentModule } from 'src/app/modals/app-restore/app-restore.component.module'
|
||||
|
||||
const routes: Routes = [
|
||||
@@ -22,7 +22,7 @@ const routes: Routes = [
|
||||
RouterModule.forChild(routes),
|
||||
QRComponentModule,
|
||||
SharingModule,
|
||||
AppActionInputPageModule,
|
||||
GenericFormPageModule,
|
||||
AppRestoreComponentModule,
|
||||
],
|
||||
declarations: [
|
||||
|
||||
@@ -7,7 +7,7 @@ import { Action, Manifest, PackageDataEntry, PackageMainStatus } from 'src/app/s
|
||||
import { wizardModal } from 'src/app/components/install-wizard/install-wizard.component'
|
||||
import { WizardBaker } from 'src/app/components/install-wizard/prebaked-wizards'
|
||||
import { Subscription } from 'rxjs'
|
||||
import { AppActionInputPage } from 'src/app/modals/app-action-input/app-action-input.page'
|
||||
import { GenericFormPage } from 'src/app/modals/generic-form/generic-form.page'
|
||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
import { AppRestoreComponent } from 'src/app/modals/app-restore/app-restore.component'
|
||||
|
||||
@@ -50,15 +50,20 @@ export class AppActionsPage {
|
||||
if ((action.value['allowed-statuses'] as PackageMainStatus[]).includes(pkg.installed.status.main.status)) {
|
||||
if (action.value['input-spec']) {
|
||||
const modal = await this.modalCtrl.create({
|
||||
component: AppActionInputPage,
|
||||
component: GenericFormPage,
|
||||
componentProps: {
|
||||
action: action.value,
|
||||
title: action.value.name,
|
||||
spec: action.value['input-spec'],
|
||||
buttons: [
|
||||
{
|
||||
text: 'Execute',
|
||||
handler: (value: any) => {
|
||||
return this.executeAction(pkg.manifest.id, action.key, value)
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
modal.onWillDismiss().then(({ data }) => {
|
||||
if (!data) return
|
||||
this.executeAction(pkg.manifest.id, action.key, data)
|
||||
})
|
||||
await modal.present()
|
||||
} else {
|
||||
const alert = await this.alertCtrl.create({
|
||||
@@ -135,7 +140,7 @@ export class AppActionsPage {
|
||||
return this.navCtrl.navigateRoot('/services')
|
||||
}
|
||||
|
||||
private async executeAction (pkgId: string, actionId: string, input?: object): Promise<void> {
|
||||
private async executeAction (pkgId: string, actionId: string, input?: object): Promise<boolean> {
|
||||
const loader = await this.loadingCtrl.create({
|
||||
spinner: 'lines',
|
||||
message: 'Executing action...',
|
||||
@@ -155,9 +160,12 @@ export class AppActionsPage {
|
||||
message: res.message.split('\n').join('</br ></br />'),
|
||||
buttons: ['OK'],
|
||||
})
|
||||
await successAlert.present()
|
||||
|
||||
setTimeout(() => successAlert.present(), 400)
|
||||
|
||||
} catch (e) {
|
||||
this.errToast.present(e)
|
||||
return false
|
||||
} finally {
|
||||
loader.dismiss()
|
||||
}
|
||||
|
||||
@@ -3,9 +3,14 @@
|
||||
<ion-grid style="height: 100%;">
|
||||
<ion-row class="ion-align-items-center ion-text-center" style="height: 100%;">
|
||||
<ion-col>
|
||||
<ion-spinner name="lines" color="warning"></ion-spinner>
|
||||
<p *ngIf="status === ServerStatus.Updating">Embassy is updating</p>
|
||||
<p *ngIf="status === ServerStatus.BackingUp">Embassy is backing up</p>
|
||||
<ng-container *ngIf="status === ServerStatus.Updating">
|
||||
<h1>Embassy Updating</h1>
|
||||
<img src="assets/img/gifs/cube.gif" />
|
||||
</ng-container>
|
||||
<ng-container *ngIf="status === ServerStatus.BackingUp">
|
||||
<h1>Backing Up</h1>
|
||||
<img src="assets/img/gifs/backing-up.gif" />
|
||||
</ng-container>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
img {
|
||||
width: 20%;
|
||||
border-radius: 0;
|
||||
}
|
||||
@@ -22,9 +22,9 @@ export class SessionsPage {
|
||||
|
||||
async ngOnInit () {
|
||||
try {
|
||||
this.sessionInfo = await this.embassyApi.getSessions({})
|
||||
this.sessionInfo = await this.embassyApi.getSessions({ })
|
||||
} catch (e) {
|
||||
this.errToast.present(e.message)
|
||||
this.errToast.present(e)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding-top">
|
||||
|
||||
<!-- always -->
|
||||
<ion-item-group>
|
||||
|
||||
<!-- always -->
|
||||
<ion-item>
|
||||
<ion-label>
|
||||
<h2>
|
||||
@@ -22,7 +22,7 @@
|
||||
|
||||
<ion-item-divider>Saved Keys</ion-item-divider>
|
||||
|
||||
<ion-item button detail="false" (click)="serverConfig.presentInputModal('ssh')">
|
||||
<ion-item button detail="false" (click)="serverConfig.presentModalInput('ssh')">
|
||||
<ion-icon slot="start" name="add" size="large"></ion-icon>
|
||||
<ion-label>Add new key</ion-label>
|
||||
</ion-item>
|
||||
|
||||
@@ -24,7 +24,7 @@ const routes: Routes = [
|
||||
},
|
||||
{
|
||||
path: 'wifi',
|
||||
loadChildren: () => import('./wifi/wifi.module').then(m => m.WifiListPageModule),
|
||||
loadChildren: () => import('./wifi/wifi.module').then(m => m.WifiPageModule),
|
||||
},
|
||||
{
|
||||
path: 'lan',
|
||||
|
||||
@@ -1,26 +0,0 @@
|
||||
import { NgModule } from '@angular/core'
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { FormsModule } from '@angular/forms'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { WifiAddPage } from './wifi-add.page'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: WifiAddPage,
|
||||
},
|
||||
]
|
||||
|
||||
@NgModule({
|
||||
imports: [
|
||||
CommonModule,
|
||||
FormsModule,
|
||||
IonicModule,
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
],
|
||||
declarations: [WifiAddPage],
|
||||
})
|
||||
export class WifiAddPageModule { }
|
||||
@@ -1,44 +0,0 @@
|
||||
<ion-header>
|
||||
<ion-toolbar>
|
||||
<ion-buttons slot="start">
|
||||
<pwa-back-button></pwa-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>Add Network</ion-title>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding-top">
|
||||
<ion-item-group>
|
||||
<ion-item>
|
||||
<ion-label>Select Country</ion-label>
|
||||
<ion-select slot="end" placeholder="Select" [(ngModel)]="countryCode" [selectedText]="countryCode">
|
||||
<ion-select-option *ngFor="let country of countries | keyvalue : asIsOrder" [value]="country.key">
|
||||
{{ country.key }} - {{ country.value }}
|
||||
</ion-select-option>
|
||||
</ion-select>
|
||||
</ion-item>
|
||||
<ion-item-divider>Network and Password</ion-item-divider>
|
||||
<ion-item>
|
||||
<ion-input placeholder="Network Name (SSID)" [(ngModel)]="ssid"></ion-input>
|
||||
</ion-item>
|
||||
<ion-item>
|
||||
<ion-input type="password" placeholder="Password" [(ngModel)]="password"></ion-input>
|
||||
</ion-item>
|
||||
</ion-item-group>
|
||||
|
||||
<ion-grid style="margin-top: 40px;">
|
||||
<ion-row>
|
||||
<ion-col size="6">
|
||||
<ion-button class="ion-text-wrap" [disabled]="!ssid" expand="block" fill="outline" color="primary" (click)="save()">
|
||||
<p>Save</p>
|
||||
</ion-button>
|
||||
</ion-col>
|
||||
<ion-col size="6">
|
||||
<ion-button class="ion-text-wrap" [disabled]="!ssid" expand="block" fill="outline" color="primary" (click)="saveAndConnect()">
|
||||
<p>Save & Connect</p>
|
||||
</ion-button>
|
||||
</ion-col>
|
||||
</ion-row>
|
||||
</ion-grid>
|
||||
|
||||
</ion-content>
|
||||
@@ -1,80 +0,0 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { LoadingController, NavController } from '@ionic/angular'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { WifiService } from '../wifi.service'
|
||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
|
||||
@Component({
|
||||
selector: 'wifi-add',
|
||||
templateUrl: 'wifi-add.page.html',
|
||||
styleUrls: ['wifi-add.page.scss'],
|
||||
})
|
||||
export class WifiAddPage {
|
||||
countries = require('../../../../util/countries.json')
|
||||
countryCode = 'US'
|
||||
ssid = ''
|
||||
password = ''
|
||||
|
||||
constructor (
|
||||
private readonly navCtrl: NavController,
|
||||
private readonly errToast: ErrorToastService,
|
||||
private readonly embassyApi: ApiService,
|
||||
private readonly loadingCtrl: LoadingController,
|
||||
private readonly wifiService: WifiService,
|
||||
) { }
|
||||
|
||||
async save (): Promise<void> {
|
||||
const loader = await this.loadingCtrl.create({
|
||||
spinner: 'lines',
|
||||
message: 'Saving...',
|
||||
cssClass: 'loader',
|
||||
})
|
||||
await loader.present()
|
||||
|
||||
try {
|
||||
await this.embassyApi.addWifi({
|
||||
ssid: this.ssid,
|
||||
password: this.password,
|
||||
country: this.countryCode,
|
||||
priority: 0,
|
||||
connect: false,
|
||||
})
|
||||
this.navCtrl.back()
|
||||
} catch (e) {
|
||||
this.errToast.present(e)
|
||||
} finally {
|
||||
loader.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
async saveAndConnect (): Promise<void> {
|
||||
const loader = await this.loadingCtrl.create({
|
||||
spinner: 'lines',
|
||||
message: 'Connecting. This could take while...',
|
||||
cssClass: 'loader',
|
||||
})
|
||||
await loader.present()
|
||||
|
||||
try {
|
||||
await this.embassyApi.addWifi({
|
||||
ssid: this.ssid,
|
||||
password: this.password,
|
||||
country: this.countryCode,
|
||||
priority: 0,
|
||||
connect: true,
|
||||
})
|
||||
const success = this.wifiService.confirmWifi(this.ssid)
|
||||
if (success) {
|
||||
this.navCtrl.back()
|
||||
}
|
||||
} catch (e) {
|
||||
this.errToast.present(e)
|
||||
} finally {
|
||||
loader.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
asIsOrder (a: any, b: any) {
|
||||
return 0
|
||||
}
|
||||
}
|
||||
@@ -2,17 +2,13 @@ import { NgModule } from '@angular/core'
|
||||
import { CommonModule } from '@angular/common'
|
||||
import { IonicModule } from '@ionic/angular'
|
||||
import { RouterModule, Routes } from '@angular/router'
|
||||
import { WifiListPage } from './wifi.page'
|
||||
import { WifiPage } from './wifi.page'
|
||||
import { SharingModule } from 'src/app/modules/sharing.module'
|
||||
|
||||
const routes: Routes = [
|
||||
{
|
||||
path: '',
|
||||
component: WifiListPage,
|
||||
},
|
||||
{
|
||||
path: 'add',
|
||||
loadChildren: () => import('./wifi-add/wifi-add.module').then(m => m.WifiAddPageModule),
|
||||
component: WifiPage,
|
||||
},
|
||||
]
|
||||
|
||||
@@ -23,6 +19,6 @@ const routes: Routes = [
|
||||
RouterModule.forChild(routes),
|
||||
SharingModule,
|
||||
],
|
||||
declarations: [WifiListPage],
|
||||
declarations: [WifiPage],
|
||||
})
|
||||
export class WifiListPageModule { }
|
||||
export class WifiPageModule { }
|
||||
|
||||
@@ -4,30 +4,70 @@
|
||||
<pwa-back-button></pwa-back-button>
|
||||
</ion-buttons>
|
||||
<ion-title>WiFi Settings</ion-title>
|
||||
<ion-buttons slot="end">
|
||||
<ion-button [routerLink]="['add']">
|
||||
<ion-icon slot="icon-only" name="add-outline"></ion-icon>
|
||||
</ion-button>
|
||||
</ion-buttons>
|
||||
</ion-toolbar>
|
||||
</ion-header>
|
||||
|
||||
<ion-content class="ion-padding-top">
|
||||
<ion-item-group>
|
||||
|
||||
<!-- always -->
|
||||
<ion-item>
|
||||
<ion-label>
|
||||
<p style="padding-bottom: 6px;">About</p>
|
||||
<h2>Embassy will automatically connect to saved WiFi networks when they are available, allowing you to remove the Ethernet cable.</h2>
|
||||
<h2>
|
||||
Embassy will automatically connect to saved WiFi networks when they are available, allowing you to remove the Ethernet cable.
|
||||
</h2>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
|
||||
<ion-item-divider>Saved Networks</ion-item-divider>
|
||||
<ng-container *ngIf="patch.data['server-info']?.wifi as wifi">
|
||||
<ion-item button detail="false" *ngFor="let ssid of wifi.ssids" (click)="presentAction(ssid, wifi)">
|
||||
<ion-item-divider>Country</ion-item-divider>
|
||||
|
||||
<!-- loading -->
|
||||
<ng-container *ngIf="loading">
|
||||
<ion-item class="skeleton-parts">
|
||||
<ion-button slot="start" fill="clear">
|
||||
<ion-skeleton-text animated style="width: 30px; height: 30px; border-radius: 0;"></ion-skeleton-text>
|
||||
</ion-button>
|
||||
<ion-label>
|
||||
<ion-skeleton-text animated style="width: 150px;"></ion-skeleton-text>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- not loading -->
|
||||
<ng-container *ngIf="!loading">
|
||||
<ion-item button detail="false" (click)="presentAlertCountry()">
|
||||
<ion-icon slot="start" name="earth-outline" size="large"></ion-icon>
|
||||
<ion-label *ngIf="wifi.country">{{ wifi.country }} - {{ this.countries[wifi.country] }}</ion-label>
|
||||
<ion-label *ngIf="!wifi.country">Select Country</ion-label>
|
||||
</ion-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- loading -->
|
||||
<ng-container *ngIf="loading">
|
||||
<ion-item-divider>Saved Networks</ion-item-divider>
|
||||
<ion-item *ngFor="let entry of ['', '']" class="skeleton-parts">
|
||||
<ion-button slot="start" fill="clear">
|
||||
<ion-skeleton-text animated style="width: 30px; height: 30px; border-radius: 0;"></ion-skeleton-text>
|
||||
</ion-button>
|
||||
<ion-label>
|
||||
<ion-skeleton-text animated style="width: 18%;"></ion-skeleton-text>
|
||||
</ion-label>
|
||||
</ion-item>
|
||||
</ng-container>
|
||||
|
||||
<!-- not loading -->
|
||||
<ng-container *ngIf="!loading && wifi.country">
|
||||
<ion-item-divider>Saved Networks</ion-item-divider>
|
||||
<ion-item button detail="false" (click)="presentModalAdd()">
|
||||
<ion-icon slot="start" name="add" size="large"></ion-icon>
|
||||
<ion-label>Add new network</ion-label>
|
||||
</ion-item>
|
||||
<ion-item button detail="false" *ngFor="let ssid of wifi.ssids" (click)="presentAction(ssid)">
|
||||
<div *ngIf="ssid !== wifi.connected" slot="start" style="padding-right: 32px;"></div>
|
||||
<ion-icon *ngIf="ssid === wifi.connected" slot="start" size="large" name="checkmark" color="success"></ion-icon>
|
||||
<ion-label>{{ ssid }}</ion-label>
|
||||
<ion-note slot="end" *ngIf="ssid === wifi.connected"><ion-text color="success">Connected</ion-text></ion-note>
|
||||
<img *ngIf="ssid === wifi.connected" slot="end" [src]="getWifiIcon()" style="max-width: 32px;" />
|
||||
</ion-item>
|
||||
</ng-container>
|
||||
</ion-item-group>
|
||||
|
||||
</ion-content>
|
||||
@@ -0,0 +1,6 @@
|
||||
.skeleton-parts {
|
||||
ion-button::part(native) {
|
||||
padding-inline-start: 0;
|
||||
padding-inline-end: 0;
|
||||
}
|
||||
}
|
||||
@@ -1,44 +1,124 @@
|
||||
import { Component } from '@angular/core'
|
||||
import { ActionSheetController, LoadingController } from '@ionic/angular'
|
||||
import { ActionSheetController, AlertController, LoadingController, ModalController, ToastController } from '@ionic/angular'
|
||||
import { AlertInput } from '@ionic/core'
|
||||
import { ApiService } from 'src/app/services/api/embassy-api.service'
|
||||
import { ActionSheetButton } from '@ionic/core'
|
||||
import { WifiService } from './wifi.service'
|
||||
import { WiFiInfo } from 'src/app/services/patch-db/data-model'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
import { Subscription } from 'rxjs'
|
||||
import { ErrorToastService } from 'src/app/services/error-toast.service'
|
||||
import { ValueSpecObject } from 'src/app/pkg-config/config-types'
|
||||
import { RR } from 'src/app/services/api/api.types'
|
||||
import { pauseFor } from 'src/app/util/misc.util'
|
||||
import { GenericFormPage } from 'src/app/modals/generic-form/generic-form.page'
|
||||
|
||||
@Component({
|
||||
selector: 'wifi',
|
||||
templateUrl: 'wifi.page.html',
|
||||
styleUrls: ['wifi.page.scss'],
|
||||
})
|
||||
export class WifiListPage {
|
||||
subs: Subscription[] = []
|
||||
export class WifiPage {
|
||||
loading = true
|
||||
wifi: RR.GetWifiRes = { } as any
|
||||
countries = require('../../../util/countries.json') as { [key: string]: string }
|
||||
|
||||
constructor (
|
||||
private readonly embassyApi: ApiService,
|
||||
private readonly api: ApiService,
|
||||
private readonly toastCtrl: ToastController,
|
||||
private readonly alertCtrl: AlertController,
|
||||
private readonly loadingCtrl: LoadingController,
|
||||
private readonly modalCtrl: ModalController,
|
||||
private readonly errToast: ErrorToastService,
|
||||
private readonly actionCtrl: ActionSheetController,
|
||||
private readonly wifiService: WifiService,
|
||||
public readonly patch: PatchDbService,
|
||||
) { }
|
||||
|
||||
async presentAction (ssid: string, wifi: WiFiInfo) {
|
||||
async ngOnInit () {
|
||||
try {
|
||||
await this.getWifi()
|
||||
} catch (e) {
|
||||
this.errToast.present(e.message)
|
||||
} finally {
|
||||
this.loading = false
|
||||
}
|
||||
}
|
||||
|
||||
async getWifi (timeout?: number): Promise<void> {
|
||||
this.wifi = await this.api.getWifi({ }, timeout)
|
||||
if (!this.wifi.country) {
|
||||
await this.presentAlertCountry()
|
||||
}
|
||||
}
|
||||
|
||||
async presentAlertCountry (): Promise<void> {
|
||||
const inputs: AlertInput[] = Object.entries(this.countries).map(([country, fullName]) => {
|
||||
return {
|
||||
name: fullName,
|
||||
type: 'radio',
|
||||
label: `${country} - ${fullName}`,
|
||||
value: country,
|
||||
checked: country === this.wifi.country,
|
||||
}
|
||||
})
|
||||
|
||||
const alert = await this.alertCtrl.create({
|
||||
header: 'Select Country',
|
||||
inputs,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Cancel',
|
||||
role: 'cancel',
|
||||
},
|
||||
{
|
||||
text: 'Save',
|
||||
handler: async (country: string) => {
|
||||
this.setCountry(country)
|
||||
},
|
||||
},
|
||||
],
|
||||
cssClass: 'wide-alert',
|
||||
})
|
||||
await alert.present()
|
||||
}
|
||||
|
||||
async presentModalAdd () {
|
||||
const modal = await this.modalCtrl.create({
|
||||
component: GenericFormPage,
|
||||
componentProps: {
|
||||
title: wifiSpec.name,
|
||||
spec: wifiSpec.spec,
|
||||
buttons: [
|
||||
{
|
||||
text: 'Save',
|
||||
handler: async (value: { ssid: string, password: string }) => {
|
||||
await this.save(value.ssid, value.password)
|
||||
},
|
||||
},
|
||||
{
|
||||
text: 'Save and Connect',
|
||||
handler: async (value: { ssid: string, password: string }) => {
|
||||
await this.saveAndConnect(value.ssid, value.password)
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
})
|
||||
|
||||
await modal.present()
|
||||
}
|
||||
|
||||
async presentAction (ssid: string) {
|
||||
const buttons: ActionSheetButton[] = [
|
||||
{
|
||||
text: 'Forget',
|
||||
icon: 'trash',
|
||||
handler: () => {
|
||||
this.delete(ssid)
|
||||
},
|
||||
},
|
||||
]
|
||||
|
||||
if (ssid !== wifi.connected) {
|
||||
if (ssid !== this.wifi.connected) {
|
||||
buttons.unshift(
|
||||
{
|
||||
text: 'Connect',
|
||||
icon: 'wifi',
|
||||
handler: () => {
|
||||
this.connect(ssid)
|
||||
},
|
||||
@@ -47,14 +127,113 @@ export class WifiListPage {
|
||||
}
|
||||
|
||||
const action = await this.actionCtrl.create({
|
||||
header: ssid,
|
||||
subHeader: 'Manage network',
|
||||
mode: 'ios',
|
||||
buttons,
|
||||
})
|
||||
|
||||
await action.present()
|
||||
}
|
||||
|
||||
// Let's add country code here
|
||||
async connect (ssid: string): Promise<void> {
|
||||
getWifiIcon (): string {
|
||||
const strength = this.wifi['signal-strength']
|
||||
if (!strength) return
|
||||
|
||||
let path = 'assets/img/icons/wifi-'
|
||||
|
||||
switch (true) {
|
||||
case strength > 66:
|
||||
path = path + '3'
|
||||
break
|
||||
case strength > 33 || strength <= 66:
|
||||
path = path + '2'
|
||||
break
|
||||
case strength < 33:
|
||||
path = path + '1'
|
||||
break
|
||||
}
|
||||
|
||||
return path + '.png'
|
||||
}
|
||||
|
||||
private async setCountry (country: string): Promise<void> {
|
||||
const loader = await this.loadingCtrl.create({
|
||||
spinner: 'lines',
|
||||
cssClass: 'loader',
|
||||
})
|
||||
await loader.present()
|
||||
|
||||
try {
|
||||
await this.api.setWifiCountry({ country })
|
||||
this.wifi.country = country
|
||||
} catch (e) {
|
||||
this.errToast.present(e)
|
||||
} finally {
|
||||
loader.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private async confirmWifi (ssid: string): Promise<void> {
|
||||
const timeout = 4000
|
||||
const maxAttempts = 5
|
||||
let attempts = 0
|
||||
|
||||
while (attempts < maxAttempts) {
|
||||
try {
|
||||
const start = new Date().valueOf()
|
||||
await this.getWifi(timeout)
|
||||
const end = new Date().valueOf()
|
||||
if (this.wifi.connected === ssid) {
|
||||
this.presentAlertSuccess(ssid)
|
||||
break
|
||||
} else {
|
||||
attempts++
|
||||
const diff = end - start
|
||||
await pauseFor(Math.max(1000, timeout - diff))
|
||||
if (attempts === maxAttempts) {
|
||||
this.presentToastFail()
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
attempts++
|
||||
console.error(e)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async presentAlertSuccess (ssid: string): Promise<void> {
|
||||
const alert = await this.alertCtrl.create({
|
||||
header: `Connected to "${ssid}"`,
|
||||
message: 'Note. It may take several minutes to an hour for your Embassy to reconnect over Tor.',
|
||||
buttons: ['OK'],
|
||||
})
|
||||
|
||||
await alert.present()
|
||||
}
|
||||
|
||||
private async presentToastFail (): Promise<void> {
|
||||
const toast = await this.toastCtrl.create({
|
||||
header: 'Failed to connect:',
|
||||
message: `Check credentials and try again`,
|
||||
position: 'bottom',
|
||||
duration: 4000,
|
||||
buttons: [
|
||||
{
|
||||
side: 'start',
|
||||
icon: 'close',
|
||||
handler: () => {
|
||||
return true
|
||||
},
|
||||
},
|
||||
],
|
||||
cssClass: 'warning-toast',
|
||||
})
|
||||
|
||||
await toast.present()
|
||||
}
|
||||
|
||||
private async connect (ssid: string): Promise<void> {
|
||||
const loader = await this.loadingCtrl.create({
|
||||
spinner: 'lines',
|
||||
message: 'Connecting. This could take while...',
|
||||
@@ -63,8 +242,8 @@ export class WifiListPage {
|
||||
await loader.present()
|
||||
|
||||
try {
|
||||
await this.embassyApi.connectWifi({ ssid })
|
||||
this.wifiService.confirmWifi(ssid)
|
||||
await this.api.connectWifi({ ssid })
|
||||
await this.confirmWifi(ssid)
|
||||
} catch (e) {
|
||||
this.errToast.present(e)
|
||||
} finally {
|
||||
@@ -72,7 +251,7 @@ export class WifiListPage {
|
||||
}
|
||||
}
|
||||
|
||||
async delete (ssid: string): Promise<void> {
|
||||
private async delete (ssid: string): Promise<void> {
|
||||
const loader = await this.loadingCtrl.create({
|
||||
spinner: 'lines',
|
||||
message: 'Deleting...',
|
||||
@@ -81,7 +260,55 @@ export class WifiListPage {
|
||||
await loader.present()
|
||||
|
||||
try {
|
||||
await this.embassyApi.deleteWifi({ ssid })
|
||||
await this.api.deleteWifi({ ssid })
|
||||
} catch (e) {
|
||||
this.errToast.present(e)
|
||||
} finally {
|
||||
loader.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private async save (ssid: string, password: string): Promise<void> {
|
||||
const loader = await this.loadingCtrl.create({
|
||||
spinner: 'lines',
|
||||
message: 'Saving...',
|
||||
cssClass: 'loader',
|
||||
})
|
||||
await loader.present()
|
||||
|
||||
try {
|
||||
await this.api.addWifi({
|
||||
ssid,
|
||||
password,
|
||||
priority: 0,
|
||||
connect: false,
|
||||
})
|
||||
await this.getWifi()
|
||||
} catch (e) {
|
||||
this.errToast.present(e)
|
||||
} finally {
|
||||
loader.dismiss()
|
||||
}
|
||||
}
|
||||
|
||||
private async saveAndConnect (ssid: string, password: string): Promise<void> {
|
||||
const loader = await this.loadingCtrl.create({
|
||||
spinner: 'lines',
|
||||
message: 'Connecting. This could take while...',
|
||||
cssClass: 'loader',
|
||||
})
|
||||
await loader.present()
|
||||
|
||||
try {
|
||||
await this.api.addWifi({
|
||||
ssid,
|
||||
password,
|
||||
priority: 0,
|
||||
connect: true,
|
||||
})
|
||||
|
||||
await this.confirmWifi(ssid)
|
||||
|
||||
} catch (e) {
|
||||
this.errToast.present(e)
|
||||
} finally {
|
||||
@@ -89,3 +316,26 @@ export class WifiListPage {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const wifiSpec: ValueSpecObject = {
|
||||
type: 'object',
|
||||
name: 'WiFi Credentials',
|
||||
description: 'Enter the network SSID and password. You can connect now or save the network for later.',
|
||||
'unique-by': null,
|
||||
spec: {
|
||||
ssid: {
|
||||
type: 'string',
|
||||
name: 'Network SSID',
|
||||
nullable: false,
|
||||
masked: false,
|
||||
copyable: false,
|
||||
},
|
||||
password: {
|
||||
type: 'string',
|
||||
name: 'Password',
|
||||
nullable: false,
|
||||
masked: true,
|
||||
copyable: false,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
import { Injectable } from '@angular/core'
|
||||
import { AlertController, ToastController } from '@ionic/angular'
|
||||
import { merge, Observable, timer } from 'rxjs'
|
||||
import { filter, map, take, tap } from 'rxjs/operators'
|
||||
import { PatchDbService } from 'src/app/services/patch-db/patch-db.service'
|
||||
|
||||
@Injectable({
|
||||
providedIn: 'root',
|
||||
})
|
||||
export class WifiService {
|
||||
|
||||
constructor (
|
||||
private readonly toastCtrl: ToastController,
|
||||
private readonly alertCtrl: AlertController,
|
||||
private readonly patch: PatchDbService,
|
||||
) { }
|
||||
|
||||
confirmWifi (ssid: string): Observable<boolean> {
|
||||
const success$ = this.patch.watch$('server-info', 'wifi', 'connected')
|
||||
.pipe(
|
||||
filter(connected => connected === ssid),
|
||||
tap(connected => this.presentAlertSuccess(connected)),
|
||||
map(_ => true),
|
||||
)
|
||||
|
||||
const timer$ = timer(20000)
|
||||
.pipe(
|
||||
map(_ => false),
|
||||
tap(_ => this.presentToastFail()),
|
||||
)
|
||||
|
||||
return merge(success$, timer$).pipe(take(1))
|
||||
}
|
||||
|
||||
private async presentAlertSuccess (ssid: string): Promise<void> {
|
||||
const alert = await this.alertCtrl.create({
|
||||
header: `Connected to "${ssid}"`,
|
||||
message: 'Note. It may take several minutes to an hour for your Embassy to reconnect over Tor.',
|
||||
buttons: ['OK'],
|
||||
})
|
||||
|
||||
await alert.present()
|
||||
}
|
||||
|
||||
private async presentToastFail (): Promise<void> {
|
||||
const toast = await this.toastCtrl.create({
|
||||
header: 'Failed to connect:',
|
||||
message: `Check credentials and try again`,
|
||||
position: 'bottom',
|
||||
duration: 4000,
|
||||
buttons: [
|
||||
{
|
||||
side: 'start',
|
||||
icon: 'close',
|
||||
handler: () => {
|
||||
return true
|
||||
},
|
||||
},
|
||||
],
|
||||
cssClass: 'warning-toast',
|
||||
})
|
||||
|
||||
await toast.present()
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user