diff --git a/src/app/app.component.ts b/src/app/app.component.ts
index a3665e62b..99c972a56 100644
--- a/src/app/app.component.ts
+++ b/src/app/app.component.ts
@@ -1,14 +1,16 @@
import { Component } from '@angular/core';
-import { Platform } from 'ionic-angular';
+import { Platform, ModalController } from 'ionic-angular';
import { StatusBar } from '@ionic-native/status-bar';
import { SplashScreen } from '@ionic-native/splash-screen';
import { Logger } from '@nsalaun/ng-logger';
import { AppProvider } from '../providers/app/app';
import { ProfileProvider } from '../providers/profile/profile';
+import { ConfigProvider } from '../providers/config/config';
import { TabsPage } from '../pages/tabs/tabs';
import { OnboardingPage } from '../pages/onboarding/onboarding';
+import { PinModalPage } from '../pages/pin/pin';
@Component({
templateUrl: 'app.html'
@@ -22,7 +24,9 @@ export class CopayApp {
private splashScreen: SplashScreen,
private logger: Logger,
private app: AppProvider,
- private profile: ProfileProvider
+ private profile: ProfileProvider,
+ private config: ConfigProvider,
+ private modalCtrl: ModalController
) {
this.initializeApp();
@@ -44,6 +48,7 @@ export class CopayApp {
this.profile.get().then((profile: any) => {
if (profile) {
this.logger.info('Profile read. Go to HomePage.');
+ this.openLockModal();
this.rootPage = TabsPage;
} else {
// TODO: go to onboarding page
@@ -53,4 +58,16 @@ export class CopayApp {
});
});
}
+
+ openLockModal() {
+ let config = this.config.get();
+ let lockMethod = config['lock'] && config['lock']['method'];
+ if (!config['lock']['method']) return;
+ if (config['lock']['method'] == 'PIN') this.openPINModal('checkPin');
+ }
+
+ openPINModal(action) {
+ let modal = this.modalCtrl.create(PinModalPage, { action }, { showBackdrop: false, enableBackdropDismiss: false });
+ modal.present();
+ }
}
diff --git a/src/app/app.module.ts b/src/app/app.module.ts
index c71f9bd69..57aabcfd5 100644
--- a/src/app/app.module.ts
+++ b/src/app/app.module.ts
@@ -42,6 +42,8 @@ import { SettingsPage } from '../pages/settings/settings';
import { AboutPage } from '../pages/settings/about/about';
import { AdvancedPage } from '../pages/settings/advanced/advanced';
import { AltCurrencyPage } from '../pages/settings/alt-currency/alt-currency';
+import { LockPage } from '../pages/settings/lock/lock';
+import { PinModalPage } from '../pages/pin/pin';
import { TermsOfUsePage } from '../pages/settings/about/terms-of-use/terms-of-use';
/* Send */
@@ -84,7 +86,9 @@ let pages: any = [
DisclaimerPage,
EmailPage,
HomePage,
+ LockPage,
OnboardingPage,
+ PinModalPage,
ReceivePage,
SendPage,
ScanPage,
diff --git a/src/pages/pin/pin.html b/src/pages/pin/pin.html
new file mode 100644
index 000000000..da3f88781
--- /dev/null
+++ b/src/pages/pin/pin.html
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+ Please enter your PIN
+ Confirm your PIN
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/pages/pin/pin.scss b/src/pages/pin/pin.scss
new file mode 100644
index 000000000..bb4ee9289
--- /dev/null
+++ b/src/pages/pin/pin.scss
@@ -0,0 +1,41 @@
+page-pin {
+ .block-code {
+ display: flex;
+ justify-content: space-between;
+ max-width: 300px;
+ margin: auto;
+ }
+ .block-buttons{
+ .row {
+ font-size: 1.7rem;
+ cursor: pointer;
+ display: flex;
+ justify-content: space-around;
+ div {
+ padding: 40px;
+ }
+ }
+ }
+ @mixin circle {
+ border-radius: 50%;
+ box-shadow: 0 0 3px 0px #5b5b5b;
+ transition: background-color .2s ease-in-out;
+ width: 5rem;
+ height: 5rem;
+ margin: 10px;
+ }
+ .circle-copay {
+ @include circle;
+ border: 1px solid #1f3598;
+ }
+ .circle-bitpay {
+ @include circle;
+ border: 1px solid #1f3598;
+ }
+ .filled-copay {
+ background-color: #1f3598;
+ }
+ .filled-bitpay {
+ background-color: #1f3598;
+ }
+}
\ No newline at end of file
diff --git a/src/pages/pin/pin.ts b/src/pages/pin/pin.ts
new file mode 100644
index 000000000..a7e1191e8
--- /dev/null
+++ b/src/pages/pin/pin.ts
@@ -0,0 +1,95 @@
+import { Component } from '@angular/core';
+import { NavController, NavParams, ViewController } from 'ionic-angular';
+import { ConfigProvider } from '../../providers/config/config';
+import { Logger } from '@nsalaun/ng-logger';
+
+import * as _ from 'lodash';
+
+@Component({
+ selector: 'page-pin',
+ templateUrl: 'pin.html',
+})
+export class PinModalPage {
+
+ public currentPin: string = '';
+ public firstPinEntered: string = '';
+ public confirmingPin: boolean = false;
+ public action: string = '';
+ public appName: string = 'copay';
+
+ constructor(
+ public navCtrl: NavController,
+ public navParams: NavParams,
+ private config: ConfigProvider,
+ private logger: Logger,
+ public viewCtrl: ViewController
+ ) {
+
+ switch (this.navParams.get('action')) {
+ case 'checkPin':
+ this.action = 'checkPin';
+ break;
+ case 'pinSetUp':
+ this.action = 'pinSetUp';
+ break;
+ case 'removeLock':
+ this.action = 'removeLock'
+ }
+
+ }
+
+ goBack(): void {
+ this.navCtrl.pop();
+ }
+
+ newEntry(value: string): void {
+ this.currentPin = this.currentPin + value;
+ if (!this.isComplete()) return;
+ if (this.action === 'checkPin' || this.action === 'removeLock') this.checkIfCorrect();
+ if (this.action === 'pinSetUp') {
+ if (!this.confirmingPin) {
+ this.confirmingPin = true;
+ this.firstPinEntered = this.currentPin;
+ this.currentPin = '';
+ }
+ else if (this.firstPinEntered === this.currentPin) this.save();
+ else {
+ this.firstPinEntered = this.currentPin = '';
+ }
+ }
+ }
+
+ delete(): void {
+ this.currentPin = this.currentPin.substring(0, this.currentPin.length - 1);
+ }
+
+ isComplete(): boolean {
+ if (this.currentPin.length < 4) return false;
+ else return true;
+ };
+
+ save(): void {
+ let lock = { method: 'PIN', value: this.currentPin, bannedUntil: null };
+ this.config.set({ lock });
+ this.viewCtrl.dismiss();
+ }
+
+ checkIfCorrect(): void {
+ let config = this.config.get();
+ let pinValue = config['lock'] && config['lock']['value'];
+ if (pinValue == this.currentPin) {
+ if (this.action === 'removeLock') {
+ let lock = { method: 'Disabled', value: null, bannedUntil: null };
+ this.config.set({ lock });
+ this.viewCtrl.dismiss();
+ }
+ if (this.action === 'checkPin') this.viewCtrl.dismiss();
+ }
+ else this.currentPin = '';
+ }
+
+ getFilledClass(limit): string {
+ return this.currentPin.length >= limit ? 'filled-' + this.appName : null;
+ }
+
+}
diff --git a/src/pages/settings/lock/lock.html b/src/pages/settings/lock/lock.html
new file mode 100644
index 000000000..59198d87c
--- /dev/null
+++ b/src/pages/settings/lock/lock.html
@@ -0,0 +1,20 @@
+
+
+
+ Lock
+
+
+
+
+
+
+
+ Startup lock by
+
+
+
+ {{opt.method}}
+
+
+
+
\ No newline at end of file
diff --git a/src/pages/settings/lock/lock.ts b/src/pages/settings/lock/lock.ts
new file mode 100644
index 000000000..ee4082aad
--- /dev/null
+++ b/src/pages/settings/lock/lock.ts
@@ -0,0 +1,47 @@
+import { Component } from '@angular/core';
+import { NavController, NavParams, ModalController } from 'ionic-angular';
+import { ConfigProvider } from '../../../providers/config/config';
+
+import { PinModalPage } from '../../pin/pin';
+
+@Component({
+ selector: 'page-lock',
+ templateUrl: 'lock.html',
+})
+export class LockPage {
+ public options: Array<{ method: string, enabled: boolean }> = [];
+ public lockOptions: Object;
+
+ constructor(
+ private modalCtrl: ModalController,
+ private config: ConfigProvider
+ ) {
+
+ this.lockOptions = this.config.get()['lock'];
+ this.options = [
+ {
+ method: 'Disabled',
+ enabled: this.lockOptions['method'] == 'Disabled' ? true : false
+ },
+ {
+ method: 'PIN',
+ enabled: this.lockOptions['method'] == 'PIN' ? true : false
+ },
+ ];
+ }
+
+ select(method): void {
+ switch (method) {
+ case 'PIN':
+ this.openPinModal('pinSetUp');
+ break;
+ case 'Disabled':
+ this.openPinModal('removeLock');
+ }
+ }
+
+ openPinModal(action) {
+ let modal = this.modalCtrl.create(PinModalPage, { action });
+ modal.present();
+ }
+}
diff --git a/src/pages/settings/settings.html b/src/pages/settings/settings.html
index 09ba0acd4..f846fa240 100644
--- a/src/pages/settings/settings.html
+++ b/src/pages/settings/settings.html
@@ -57,18 +57,12 @@
Urgent
-
+
Lock
-
- Disabled
- Lock by PIN
- Lock by fingerprint
-
-
Wallets & integrations
@@ -81,13 +75,13 @@
More
-
- Advanced
-
+
+ Advanced
+
About {{appName}}
-
+
\ No newline at end of file
diff --git a/src/pages/settings/settings.ts b/src/pages/settings/settings.ts
index 09f3eb541..2ccef15c1 100644
--- a/src/pages/settings/settings.ts
+++ b/src/pages/settings/settings.ts
@@ -5,7 +5,7 @@ import { AppProvider } from '../../providers/app/app';
import { LanguageProvider } from '../../providers/language/language';
import { RateProvider } from '../../providers/rate/rate';
import { AltCurrencyPage } from './alt-currency/alt-currency';
-
+import { LockPage } from './lock/lock';
import { AboutPage } from './about/about';
import { AdvancedPage } from './advanced/advanced';
@@ -55,4 +55,8 @@ export class SettingsPage {
this.navCtrl.push(AboutPage);
}
+ openLockPage() {
+ this.navCtrl.push(LockPage);
+ }
+
}
diff --git a/src/providers/app/app.ts b/src/providers/app/app.ts
index 0dc234e79..d3d8b527b 100644
--- a/src/providers/app/app.ts
+++ b/src/providers/app/app.ts
@@ -75,6 +75,6 @@ export class AppProvider {
getInfo() {
return this.http.get(this.jsonPath)
- .map((res:Response) => res.json());
+ .map((res: Response) => res.json());
}
}
diff --git a/src/providers/config/config.ts b/src/providers/config/config.ts
index 2da6b00b2..c382e5e4c 100644
--- a/src/providers/config/config.ts
+++ b/src/providers/config/config.ts
@@ -123,7 +123,6 @@ export class ConfigProvider {
if (_.isString(newOpts)) {
newOpts = JSON.parse(newOpts);
}
-
_.merge(config, this.configCache, newOpts);
this.configCache = config;
this.persistence.storeConfig(this.configCache).then(() => {