diff --git a/package-lock.json b/package-lock.json index b3b96de..a15e6bc 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2176,6 +2176,14 @@ "@types/cordova": "^0.0.34" } }, + "@ionic-native/native-storage": { + "version": "5.22.0", + "resolved": "https://registry.npmjs.org/@ionic-native/native-storage/-/native-storage-5.22.0.tgz", + "integrity": "sha512-jk4Pwe1ruS7aQ2/fZSrUc3viMeMHoOkbpmeMn6Ht+A7qQk/krItxlhW3QzT0EAhvrrgNy+70fOlGKvLkwItBbg==", + "requires": { + "@types/cordova": "^0.0.34" + } + }, "@ionic-native/splash-screen": { "version": "5.22.0", "resolved": "https://registry.npmjs.org/@ionic-native/splash-screen/-/splash-screen-5.22.0.tgz", @@ -2232,6 +2240,16 @@ "tslib": "^1.10.0" } }, + "@ionic/storage": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@ionic/storage/-/storage-2.2.0.tgz", + "integrity": "sha512-2pszrzmI+fAar2Rx0WmJDVpc15D1k5tvLkB49NLYWJ2pOMaO/3/vp7mg/mEbg3rdsPE9FRbYI6vdKjQ2pP1EWA==", + "requires": { + "localforage": "1.7.1", + "localforage-cordovasqlitedriver": "1.7.0", + "tslib": "^1.7.1" + } + }, "@istanbuljs/schema": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", @@ -6178,8 +6196,7 @@ "immediate": { "version": "3.0.6", "resolved": "https://registry.npmjs.org/immediate/-/immediate-3.0.6.tgz", - "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=", - "dev": true + "integrity": "sha1-nbHb0Pr43m++D13V5Wu2BigN5ps=" }, "import-cwd": { "version": "2.1.0", @@ -7826,6 +7843,32 @@ "json5": "^1.0.1" } }, + "localforage": { + "version": "1.7.1", + "resolved": "https://registry.npmjs.org/localforage/-/localforage-1.7.1.tgz", + "integrity": "sha1-5JJ+BCMCuGTbMPMhHxO1xvDell0=", + "requires": { + "lie": "3.1.1" + }, + "dependencies": { + "lie": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/lie/-/lie-3.1.1.tgz", + "integrity": "sha1-mkNrLMd0bKWd56QfpGmz77dr2H4=", + "requires": { + "immediate": "~3.0.5" + } + } + } + }, + "localforage-cordovasqlitedriver": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/localforage-cordovasqlitedriver/-/localforage-cordovasqlitedriver-1.7.0.tgz", + "integrity": "sha1-i5OVd1nuaI06WNW6fAR39sy1ODg=", + "requires": { + "localforage": ">=1.5.0" + } + }, "locate-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz", diff --git a/package.json b/package.json index 731d716..053edc1 100644 --- a/package.json +++ b/package.json @@ -23,9 +23,11 @@ "@angular/router": "~8.2.14", "@capacitor/core": "1.5.1", "@ionic-native/core": "^5.0.0", + "@ionic-native/native-storage": "^5.22.0", "@ionic-native/splash-screen": "^5.0.0", "@ionic-native/status-bar": "^5.0.0", "@ionic/angular": "^5.0.0", + "@ionic/storage": "^2.2.0", "@types/leaflet": "^1.5.11", "chart.js": "^2.9.3", "chartjs-plugin-zoom": "^0.7.5", diff --git a/src/app/app-routing.module.ts b/src/app/app-routing.module.ts index 18927d7..d41cbbb 100644 --- a/src/app/app-routing.module.ts +++ b/src/app/app-routing.module.ts @@ -6,6 +6,10 @@ const routes: Routes = [ path: "", loadChildren: () => import("./navigations/tabs/tabs.module").then(m => m.TabsPageModule) + }, + { + path: 'settings', + loadChildren: () => import('./pages/settings/settings.module').then( m => m.SettingsPageModule) } ]; @NgModule({ diff --git a/src/app/app.module.ts b/src/app/app.module.ts index 67fb36f..58a3cca 100644 --- a/src/app/app.module.ts +++ b/src/app/app.module.ts @@ -9,6 +9,7 @@ import { StatusBar } from "@ionic-native/status-bar/ngx"; import { AppRoutingModule } from "./app-routing.module"; import { AppComponent } from "./app.component"; import { HttpClientModule } from "@angular/common/http"; +import { NativeStorage } from "@ionic-native/native-storage/ngx"; import "chartjs-plugin-zoom"; @@ -23,6 +24,7 @@ import "chartjs-plugin-zoom"; ], providers: [ StatusBar, + NativeStorage, SplashScreen, { provide: RouteReuseStrategy, useClass: IonicRouteStrategy } ], diff --git a/src/app/navigations/tabs/tabs-routing.module.ts b/src/app/navigations/tabs/tabs-routing.module.ts index 8bc9f2c..645d7bf 100644 --- a/src/app/navigations/tabs/tabs-routing.module.ts +++ b/src/app/navigations/tabs/tabs-routing.module.ts @@ -39,6 +39,18 @@ const routes: Routes = [ } ] }, + { + path: "settings", + children: [ + { + path: "", + loadChildren: () => + import("../../pages/settings/settings.module").then( + m => m.SettingsPageModule + ) + } + ] + }, { path: "", redirectTo: "/tabs/home", diff --git a/src/app/navigations/tabs/tabs.page.html b/src/app/navigations/tabs/tabs.page.html index 31b09d5..9df7963 100644 --- a/src/app/navigations/tabs/tabs.page.html +++ b/src/app/navigations/tabs/tabs.page.html @@ -13,5 +13,9 @@ About + + + Settings + diff --git a/src/app/pages/about/about.page.html b/src/app/pages/about/about.page.html index 003dce2..d8d0ecc 100644 --- a/src/app/pages/about/about.page.html +++ b/src/app/pages/about/about.page.html @@ -42,23 +42,4 @@ - - - - Settings - - - - - - - - Toggle Dark Theme - - - - - - - \ No newline at end of file diff --git a/src/app/pages/about/about.page.ts b/src/app/pages/about/about.page.ts index a780dad..122c5ee 100644 --- a/src/app/pages/about/about.page.ts +++ b/src/app/pages/about/about.page.ts @@ -1,29 +1,18 @@ -import { Component, OnInit } from '@angular/core'; +import { Component, OnInit } from "@angular/core"; @Component({ - selector: 'app-about', - templateUrl: './about.page.html', - styleUrls: ['./about.page.scss'], + selector: "app-about", + templateUrl: "./about.page.html", + styleUrls: ["./about.page.scss"] }) export class AboutPage implements OnInit { - - prefersDark = window.matchMedia('(prefers-color-scheme: dark)'); + prefersDark = window.matchMedia("(prefers-color-scheme: dark)"); darkTheme: boolean = false; - constructor() { } + constructor() {} ngOnInit() { // checkToggle(prefersDark.matches); - this.toggleDarkTheme(this.prefersDark.matches); - } - - toggle(event) { - this.toggleDarkTheme(this.darkTheme); } - - toggleDarkTheme(shouldAdd) { - document.body.classList.toggle('dark', shouldAdd); - } - } diff --git a/src/app/pages/home/home.module.ts b/src/app/pages/home/home.module.ts index 5b71de1..9fc8dd6 100644 --- a/src/app/pages/home/home.module.ts +++ b/src/app/pages/home/home.module.ts @@ -9,6 +9,7 @@ import { HomePageRoutingModule } from "./home-routing.module"; import { HomePage } from "./home.page"; import { ApiService } from "../../services/api.service"; import { ChartsModule } from "ng2-charts"; +import { DatabaseService } from "../../services/database.service"; @NgModule({ imports: [ @@ -19,6 +20,6 @@ import { ChartsModule } from "ng2-charts"; HomePageRoutingModule ], declarations: [HomePage], - providers: [ApiService] + providers: [ApiService, DatabaseService] }) export class HomePageModule {} diff --git a/src/app/pages/home/home.page.html b/src/app/pages/home/home.page.html index fdbe1d8..249f636 100644 --- a/src/app/pages/home/home.page.html +++ b/src/app/pages/home/home.page.html @@ -20,7 +20,7 @@
Select a country - + All {{location.name}} diff --git a/src/app/pages/home/home.page.ts b/src/app/pages/home/home.page.ts index 91c988c..7eb9e64 100644 --- a/src/app/pages/home/home.page.ts +++ b/src/app/pages/home/home.page.ts @@ -3,6 +3,7 @@ import { ApiService } from "../../services/api.service"; import { ToastController } from "@ionic/angular"; import { ChartDataSets } from "chart.js"; import { Label, Color } from "ng2-charts"; +import { DatabaseService } from "../../services/database.service"; declare var Chart: any; @Component({ @@ -12,7 +13,7 @@ declare var Chart: any; }) export class HomePage implements OnInit { latest: any; - loading: boolean = true; + loading: boolean = false; locations = []; location: any; searchLocation: string = ""; @@ -93,19 +94,53 @@ export class HomePage implements OnInit { chartType = "line"; showLegend = false; - constructor(private toast: ToastController, private api: ApiService) { } + constructor( + private toast: ToastController, + private database: DatabaseService, + private api: ApiService + ) {} ngOnInit() { this.loadLatest(); + this.loading = true; + this.database.getLocations().then( + data => { + if (data) { + this.locations = data; + this.loading = false; + } else { + this.loadLocations(); + this.loading = false; + } + }, + error => { + this.loading = false; + } + ); + + this.database.getSetting("defaultLocation").then( + data => { + if (data) { + console.log(data); + this.searchLocation = data; + this.search(); + } + }, + error => { + this.loading = false; + } + ); + } + + loadLocations() { this.loading = true; this.api.getLocations().subscribe(data => { this.loading = false; this.locations = []; data.forEach(element => { this.locations.push({ - id: element.id, name: - element.province !== "" ? element.province : - element.country + id: element.id, + name: element.province !== "" ? element.province : element.country }); }); this.locations.sort((a, b) => { @@ -120,6 +155,8 @@ export class HomePage implements OnInit { } return comparison; }); + console.log(this.locations); + this.database.setLocations(this.locations); }); } @@ -130,7 +167,7 @@ export class HomePage implements OnInit { }); } - search(event) { + search() { if (this.searchLocation !== "") { this.loading = true; this.api.getLocation(this.searchLocation).subscribe(data => { @@ -139,6 +176,7 @@ export class HomePage implements OnInit { this.renderCharts(); }); } else { + this.loading = false; this.location = null; this.loadLatest; } @@ -176,7 +214,7 @@ export class HomePage implements OnInit { i % rest === 1 || i === 0 || i === - Object.keys(this.location.timelines.confirmed.timeline).length - 1 + Object.keys(this.location.timelines.confirmed.timeline).length - 1 ) { this.confirmedChartLabels.push(key.substring(0, 10)); this.confirmedChartData[0].data.push( @@ -192,7 +230,7 @@ export class HomePage implements OnInit { i % rest === 1 || i === 0 || i === - Object.keys(this.location.timelines.recovered.timeline).length - 1 + Object.keys(this.location.timelines.recovered.timeline).length - 1 ) { this.recoveredChartLabels.push(key.substring(0, 10)); this.recoveredChartData[0].data.push( diff --git a/src/app/pages/settings/settings-routing.module.ts b/src/app/pages/settings/settings-routing.module.ts new file mode 100644 index 0000000..59decc0 --- /dev/null +++ b/src/app/pages/settings/settings-routing.module.ts @@ -0,0 +1,17 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; + +import { SettingsPage } from './settings.page'; + +const routes: Routes = [ + { + path: '', + component: SettingsPage + } +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule], +}) +export class SettingsPageRoutingModule {} diff --git a/src/app/pages/settings/settings.module.ts b/src/app/pages/settings/settings.module.ts new file mode 100644 index 0000000..faa3cad --- /dev/null +++ b/src/app/pages/settings/settings.module.ts @@ -0,0 +1,18 @@ +import { NgModule } from "@angular/core"; +import { CommonModule } from "@angular/common"; +import { FormsModule } from "@angular/forms"; + +import { IonicModule } from "@ionic/angular"; + +import { SettingsPageRoutingModule } from "./settings-routing.module"; + +import { SettingsPage } from "./settings.page"; +import { DatabaseService } from "../../services/database.service"; +import { ApiService } from "../../services/api.service"; + +@NgModule({ + imports: [CommonModule, FormsModule, IonicModule, SettingsPageRoutingModule], + declarations: [SettingsPage], + providers: [DatabaseService, ApiService] +}) +export class SettingsPageModule {} diff --git a/src/app/pages/settings/settings.page.html b/src/app/pages/settings/settings.page.html new file mode 100644 index 0000000..e1dc22d --- /dev/null +++ b/src/app/pages/settings/settings.page.html @@ -0,0 +1,25 @@ + + + + Settings + + + + + + + + Settings + + + + + Default location + + All + {{location.name}} + + + + + diff --git a/src/app/pages/settings/settings.page.scss b/src/app/pages/settings/settings.page.scss new file mode 100644 index 0000000..e69de29 diff --git a/src/app/pages/settings/settings.page.spec.ts b/src/app/pages/settings/settings.page.spec.ts new file mode 100644 index 0000000..220f3e1 --- /dev/null +++ b/src/app/pages/settings/settings.page.spec.ts @@ -0,0 +1,24 @@ +import { async, ComponentFixture, TestBed } from '@angular/core/testing'; +import { IonicModule } from '@ionic/angular'; + +import { SettingsPage } from './settings.page'; + +describe('SettingsPage', () => { + let component: SettingsPage; + let fixture: ComponentFixture; + + beforeEach(async(() => { + TestBed.configureTestingModule({ + declarations: [ SettingsPage ], + imports: [IonicModule.forRoot()] + }).compileComponents(); + + fixture = TestBed.createComponent(SettingsPage); + component = fixture.componentInstance; + fixture.detectChanges(); + })); + + it('should create', () => { + expect(component).toBeTruthy(); + }); +}); diff --git a/src/app/pages/settings/settings.page.ts b/src/app/pages/settings/settings.page.ts new file mode 100644 index 0000000..02a0246 --- /dev/null +++ b/src/app/pages/settings/settings.page.ts @@ -0,0 +1,35 @@ +import { Component, OnInit } from "@angular/core"; +import { DatabaseService } from "../../services/database.service"; +import { ApiService } from "../../services/api.service"; + +@Component({ + selector: "app-settings", + templateUrl: "./settings.page.html", + styleUrls: ["./settings.page.scss"] +}) +export class SettingsPage implements OnInit { + locations = []; + defaultLocation: string = ""; + + constructor(private database: DatabaseService, private api: ApiService) {} + + ngOnInit() { + this.database.getLocations().then(data => { + if (data) { + this.locations = data; + } + }); + + this.database.getSetting("defaultLocation").then(data => { + console.log(data); + if (data) { + this.defaultLocation = data; + console.log(this.defaultLocation); + } + }); + } + + setDefaultLocation(event) { + this.database.setSetting("defaultLocation", this.defaultLocation); + } +} diff --git a/src/app/services/database.service.spec.ts b/src/app/services/database.service.spec.ts new file mode 100644 index 0000000..2270b52 --- /dev/null +++ b/src/app/services/database.service.spec.ts @@ -0,0 +1,12 @@ +import { TestBed } from '@angular/core/testing'; + +import { DatabaseService } from './database.service'; + +describe('DatabaseService', () => { + beforeEach(() => TestBed.configureTestingModule({})); + + it('should be created', () => { + const service: DatabaseService = TestBed.get(DatabaseService); + expect(service).toBeTruthy(); + }); +}); diff --git a/src/app/services/database.service.ts b/src/app/services/database.service.ts new file mode 100644 index 0000000..408b233 --- /dev/null +++ b/src/app/services/database.service.ts @@ -0,0 +1,40 @@ +import { Injectable } from "@angular/core"; + +import { Plugins } from "@capacitor/core"; +const { Storage } = Plugins; + +@Injectable({ + providedIn: "root" +}) +export class DatabaseService { + constructor() {} + + public async setSetting(key, value) { + await Storage.set({ key, value }); + } + + public async getSetting(key): Promise { + return (await Storage.get({ key })).value; + } + + public async setLocations(value) { + await Storage.set({ key: "locations", value: JSON.stringify(value) }); + } + + public async getLocations(): Promise { + const ret = await Storage.get({ key: "locations" }); + return JSON.parse(ret.value); + } + + // public async getSetting(name) { + // return await this.storage.getItem(`setting:${name}`); + // } + + // public setLocations(value) { + // return this.storage.setItem(`locations`, JSON.stringify(value)); + // } + + // public async getLocations() { + // return await this.storage.getItem(`locations`); + // } +}