0.2.5 initial commit

Makefile incomplete
This commit is contained in:
Aiden McClelland
2020-11-23 13:44:28 -07:00
commit 95d3845906
503 changed files with 53448 additions and 0 deletions

View File

@@ -0,0 +1,28 @@
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 { PwaBackComponentModule } from 'src/app/components/pwa-back-button/pwa-back.component.module'
import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module'
const routes: Routes = [
{
path: '',
component: WifiAddPage,
},
]
@NgModule({
imports: [
CommonModule,
FormsModule,
IonicModule,
RouterModule.forChild(routes),
PwaBackComponentModule,
BadgeMenuComponentModule,
],
declarations: [WifiAddPage],
})
export class WifiAddPageModule { }

View File

@@ -0,0 +1,52 @@
<ion-header>
<ion-buttons slot="start">
<pwa-back-button></pwa-back-button>
</ion-buttons>
<ion-toolbar>
<ion-title>Add Network</ion-title>
</ion-toolbar>
<ion-buttons slot="end">
<badge-menu-button></badge-menu-button>
</ion-buttons>
</ion-header>
<ion-content class="ion-padding-top">
<ion-item *ngIf="error">
<ion-text class="ion-text-wrap" color="danger">{{ error }}</ion-text>
</ion-item>
<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 [disabled]="!ssid" expand="block" fill="outline" color="primary" (click)="add()">
Add
</ion-button>
</ion-col>
<ion-col size="6">
<ion-button [disabled]="!ssid" expand="block" fill="outline" color="success" (click)="addAndConnect()">
Add and Connect
</ion-button>
</ion-col>
</ion-row>
</ion-grid>
</ion-content>

View File

@@ -0,0 +1,67 @@
import { Component } from '@angular/core'
import { NavController } from '@ionic/angular'
import { ApiService } from 'src/app/services/api/api.service'
import { WifiService } from '../wifi.service'
import { LoaderService } from 'src/app/services/loader.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 = ''
error = ''
constructor (
private readonly navCtrl: NavController,
private readonly apiService: ApiService,
private readonly loader: LoaderService,
private readonly wifiService: WifiService,
) { }
async add (): Promise<void> {
this.loader.of({
message: 'Saving...',
spinner: 'lines',
cssClass: 'loader',
}).displayDuringAsync( async () => {
await this.apiService.addWifi(this.ssid, this.password, this.countryCode, false)
this.wifiService.addWifi(this.ssid)
this.ssid = ''
this.password = ''
this.error = ''
this.navCtrl.back()
}).catch(e => {
console.error(e)
this.error = e.message
})
}
async addAndConnect (): Promise<void> {
this.loader.of({
message: 'Connecting. This could take while...',
spinner: 'lines',
cssClass: 'loader',
}).displayDuringAsync( async () => {
await this.apiService.addWifi(this.ssid, this.password, this.countryCode, true)
const success = await this.wifiService.confirmWifi(this.ssid)
if (!success) { return }
this.wifiService.addWifi(this.ssid)
this.ssid = ''
this.password = ''
this.error = ''
this.navCtrl.back()
}).catch (e => {
console.error(e)
this.error = e.message
})
}
asIsOrder (a: any, b: any) {
return 0
}
}

View File

@@ -0,0 +1,30 @@
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 { PwaBackComponentModule } from 'src/app/components/pwa-back-button/pwa-back.component.module'
import { BadgeMenuComponentModule } from 'src/app/components/badge-menu-button/badge-menu.component.module'
const routes: Routes = [
{
path: '',
component: WifiListPage,
},
{
path: 'add',
loadChildren: () => import('./wifi-add/wifi-add.module').then(m => m.WifiAddPageModule),
},
]
@NgModule({
imports: [
CommonModule,
IonicModule,
RouterModule.forChild(routes),
PwaBackComponentModule,
BadgeMenuComponentModule,
],
declarations: [WifiListPage],
})
export class WifiListPageModule { }

View File

@@ -0,0 +1,47 @@
<ion-header>
<ion-toolbar>
<ion-buttons slot="start">
<pwa-back-button></pwa-back-button>
</ion-buttons>
<ion-title>Wifi</ion-title>
<ion-buttons slot="end">
<badge-menu-button></badge-menu-button>
</ion-buttons>
</ion-toolbar>
</ion-header>
<ion-content class="ion-padding-top">
<ion-refresher slot="fixed" (ionRefresh)="doRefresh($event)">
<ion-refresher-content pullingIcon="lines" refreshingSpinner="lines"></ion-refresher-content>
</ion-refresher>
<ion-item *ngIf="error">
<ion-text class="ion-text-wrap" color="danger">{{ error }}</ion-text>
</ion-item>
<ion-item-group>
<ion-item>
<ion-label class="ion-text-wrap">
<p>
Add WiFi credentials to your Embassy so it can connect to the Internet without an ethernet cable.
</p>
</ion-label>
</ion-item>
<ion-item-divider class="borderless"></ion-item-divider>
<ion-item-divider>Saved Networks</ion-item-divider>
<ion-item button detail="false" *ngFor="let ssid of (server.wifi | async)?.ssids" (click)="presentAction(ssid)">
<ion-label>{{ ssid }}</ion-label>
<ion-icon *ngIf="ssid === (server.wifi | async).current" name="wifi" color="success"></ion-icon>
</ion-item>
</ion-item-group>
<ion-fab vertical="bottom" horizontal="end" slot="fixed">
<ion-fab-button [routerLink]="['add']" class="fab-button">
<ion-icon name="add"></ion-icon>
</ion-fab-button>
</ion-fab>
</ion-content>

View File

@@ -0,0 +1,102 @@
import { Component } from '@angular/core'
import { ActionSheetController } from '@ionic/angular'
import { ApiService } from 'src/app/services/api/api.service'
import { ActionSheetButton } from '@ionic/core'
import { pauseFor } from 'src/app/util/misc.util'
import { WifiService } from './wifi.service'
import { PropertySubject } from 'src/app/util/property-subject.util'
import { S9Server } from 'src/app/models/server-model'
import { LoaderService } from 'src/app/services/loader.service'
import { ModelPreload } from 'src/app/models/model-preload'
@Component({
selector: 'wifi',
templateUrl: 'wifi.page.html',
styleUrls: ['wifi.page.scss'],
})
export class WifiListPage {
server: PropertySubject<S9Server> = { } as any
error: string
constructor (
private readonly apiService: ApiService,
private readonly loader: LoaderService,
private readonly actionCtrl: ActionSheetController,
private readonly wifiService: WifiService,
private readonly preload: ModelPreload,
) { }
async ngOnInit () {
this.loader.displayDuring$(
this.preload.server(),
).subscribe(s => this.server = s)
}
async doRefresh (event: any) {
await Promise.all([
this.apiService.getServer(),
pauseFor(600),
])
event.target.complete()
}
async presentAction (ssid: string) {
const buttons: ActionSheetButton[] = [
{
text: 'Forget',
cssClass: 'alert-danger',
handler: () => {
this.delete(ssid)
},
},
]
if (ssid !== this.server.wifi.getValue().current) {
buttons.unshift(
{
text: 'Connect',
handler: () => {
this.connect(ssid)
},
},
)
}
const action = await this.actionCtrl.create({
buttons,
})
await action.present()
}
// Let's add country code here.
async connect (ssid: string): Promise<void> {
this.loader.of({
message: 'Connecting. This could take while...',
spinner: 'lines',
cssClass: 'loader',
}).displayDuringAsync(async () => {
await this.apiService.connectWifi(ssid)
await this.wifiService.confirmWifi(ssid)
this.error = ''
}).catch(e => {
console.error(e)
this.error = e.message
})
}
async delete (ssid: string): Promise<void> {
this.loader.of({
message: 'Deleting...',
spinner: 'lines',
cssClass: 'loader',
}).displayDuringAsync( async () => {
await this.apiService.deleteWifi(ssid)
this.wifiService.removeWifi(ssid)
this.error = ''
}).catch(e => {
console.error(e)
this.error = e.message
})
}
}

View File

@@ -0,0 +1,80 @@
import { Injectable } from '@angular/core'
import { ToastController } from '@ionic/angular'
import { ApiService } from 'src/app/services/api/api.service'
import { pauseFor } from 'src/app/util/misc.util'
import { ServerModel } from 'src/app/models/server-model'
@Injectable({
providedIn: 'root',
})
export class WifiService {
constructor (
private readonly apiService: ApiService,
private readonly toastCtrl: ToastController,
private readonly serverModel: ServerModel,
) { }
addWifi (ssid: string): void {
const wifi = this.serverModel.peek().wifi
this.serverModel.update({ wifi: { ...wifi, ssids: [...new Set([ssid, ...wifi.ssids])] } })
}
removeWifi (ssid: string): void {
const wifi = this.serverModel.peek().wifi
this.serverModel.update({ wifi: { ...wifi, ssids: wifi.ssids.filter(s => s !== ssid) } })
}
async confirmWifi (ssid: string): Promise<boolean> {
const timeout = 4000
const maxAttempts = 5
let attempts = 0
while (attempts < maxAttempts) {
try {
const start = new Date().valueOf()
const { current, ssids } = (await this.apiService.getServer(timeout)).wifi
const end = new Date().valueOf()
if (current === ssid) {
this.serverModel.update({ wifi: { current, ssids } })
break
} else {
attempts++
const diff = end - start
await pauseFor(Math.max(0, timeout - diff))
if (attempts === maxAttempts) {
this.serverModel.update({ wifi: { current, ssids } })
}
}
} catch (e) {
attempts++
console.error(e)
}
}
if (this.serverModel.peek().wifi.current === ssid) {
return true
} else {
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: 'notification-toast',
})
setTimeout(() => toast.present(), 300)
return false
}
}
}