mirror of
https://github.com/Qortal/qortal-ui.git
synced 2025-02-11 17:55:51 +00:00
commit
6e0801d54d
@ -109,6 +109,10 @@ const elementComponents = {
|
||||
file: 'components/settings-view/security-view.js',
|
||||
className: 'SecurityView'
|
||||
},
|
||||
'qr-login-view': {
|
||||
file: 'components/settings-view/qr-login-view.js',
|
||||
className: 'QRLoginView'
|
||||
},
|
||||
'notifications-view': {
|
||||
file: 'components/settings-view/notifications-view.js',
|
||||
className: 'NotificationsView'
|
||||
|
@ -93,6 +93,11 @@
|
||||
"settings": "Settings",
|
||||
"account": "Account",
|
||||
"security": "Security",
|
||||
"qr_login_menu_item": "QR Login",
|
||||
"qr_login_description_1": "Scan this code to unlock your wallet on other device using the same password which you logged in with.",
|
||||
"qr_login_description_2": "Choose a password which you will use to unlock your wallet on other device after scanning the QR code.",
|
||||
"qr_login_button_1": "Show login QR code",
|
||||
"qr_login_button_2": "Generate login QR code",
|
||||
"notifications": "Notifications",
|
||||
"accountsecurity": "Account Security",
|
||||
"password": "Password",
|
||||
|
140
qortal-ui-core/src/components/settings-view/qr-login-view.js
Normal file
140
qortal-ui-core/src/components/settings-view/qr-login-view.js
Normal file
@ -0,0 +1,140 @@
|
||||
import { css, html, LitElement } from 'lit'
|
||||
import { connect } from 'pwa-helpers'
|
||||
import { store } from '../../store.js'
|
||||
import { translate } from 'lit-translate'
|
||||
|
||||
import '@material/mwc-textfield'
|
||||
import '@material/mwc-icon'
|
||||
import '@vaadin/password-field/vaadin-password-field.js'
|
||||
import '../../../../qortal-ui-plugins/plugins/core/components/QortalQrcodeGenerator.js'
|
||||
|
||||
class QRLoginView extends connect(store)(LitElement) {
|
||||
static get properties() {
|
||||
return {
|
||||
theme: { type: String, reflect: true },
|
||||
savedWalletDataJson: { type: String },
|
||||
translateDescriptionKey: { type: String }, // Description text
|
||||
translateButtonKey: { type: String }, // Button text
|
||||
}
|
||||
}
|
||||
|
||||
static get styles() {
|
||||
return css`
|
||||
* {
|
||||
--lumo-primary-text-color: rgb(0, 167, 245);
|
||||
--lumo-primary-color-50pct: rgba(0, 167, 245, 0.5);
|
||||
--lumo-primary-color-10pct: rgba(0, 167, 245, 0.1);
|
||||
--lumo-primary-color: hsl(199, 100%, 48%);
|
||||
--lumo-base-color: var(--white);
|
||||
--lumo-body-text-color: var(--black);
|
||||
--lumo-secondary-text-color: var(--sectxt);
|
||||
--lumo-contrast-60pct: var(--vdicon);
|
||||
}
|
||||
|
||||
.center-box {
|
||||
position: relative;
|
||||
top: 45%;
|
||||
left: 50%;
|
||||
transform: translate(-50%, 0%);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.q-button {
|
||||
display: inline-flex;
|
||||
flex-direction: column;
|
||||
justify-content: center;
|
||||
align-content: center;
|
||||
border: none;
|
||||
border-radius: 20px;
|
||||
padding-left: 25px;
|
||||
padding-right: 25px;
|
||||
color: white;
|
||||
background: #03a9f4;
|
||||
width: 50%;
|
||||
font-size: 17px;
|
||||
cursor: pointer;
|
||||
height: 50px;
|
||||
margin-top: 1rem;
|
||||
text-transform: uppercase;
|
||||
text-decoration: none;
|
||||
transition: all .2s;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.q-button.outlined {
|
||||
background: unset;
|
||||
border: 1px solid #03a9f4;
|
||||
}
|
||||
|
||||
:host([theme="light"]) .q-button.outlined {
|
||||
color: #03a9f4;
|
||||
}
|
||||
|
||||
#qr-toggle-button {
|
||||
margin-left: 12px;
|
||||
}
|
||||
|
||||
#login-qr-code {
|
||||
margin: auto;
|
||||
}
|
||||
`
|
||||
}
|
||||
|
||||
constructor() {
|
||||
super()
|
||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||
this.translateDescriptionKey = 'settings.qr_login_description_' + (this.isWalletStored() ? '1' : '2')
|
||||
this.translateButtonKey = 'settings.qr_login_button_' + (this.isWalletStored() ? '1' : '2')
|
||||
}
|
||||
|
||||
render() {
|
||||
return html`
|
||||
<div style="position: relative;" >
|
||||
<div class="center-box">
|
||||
<p>
|
||||
${translate(this.translateDescriptionKey)}
|
||||
</p>
|
||||
<div style="max-width: 500px; justify-content: center; margin: auto; display: ${this.isWalletStored() ? 'none' : 'flex' }">
|
||||
<mwc-icon style="padding: 10px; padding-left:0; padding-top: 42px;">password</mwc-icon>
|
||||
<vaadin-password-field id="newWalletPassword" style="width: 100%; color: var(--black);" label="${translate("settings.password")}" autofocus></vaadin-password-field>
|
||||
</div>
|
||||
<div style="max-width: 600px; display: flex; justify-content: center; margin: auto;">
|
||||
<div id="qr-toggle-button" @click=${() => this.showQRCode()} class="q-button outlined"> ${translate(this.translateButtonKey)} </div>
|
||||
</div>
|
||||
|
||||
<div id="login-qr-code" style="display: none;">
|
||||
<qortal-qrcode-generator id="login-qr-code" data="${this.savedWalletDataJson}" mode="octet" format="html" auto></qortal-qrcode-generator>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
isWalletStored() {
|
||||
const state = store.getState()
|
||||
const address0 = state.app.wallet._addresses[0].address
|
||||
const savedWalletData = state.user.storedWallets && state.user.storedWallets[address0]
|
||||
return !!savedWalletData
|
||||
}
|
||||
|
||||
async setSavedWalletDataJson() {
|
||||
const state = store.getState()
|
||||
let data
|
||||
if (this.isWalletStored()) { // if the wallet is stored, we use the existing encrypted backup
|
||||
const address0 = state.app.wallet._addresses[0].address
|
||||
data = state.user.storedWallets[address0]
|
||||
} else { // if the wallet is not stored, we generate new `saveWalletData` backup encrypted with the new password
|
||||
const password = this.shadowRoot.getElementById('newWalletPassword').value
|
||||
data = await state.app.wallet.generateSaveWalletData(password, state.config.crypto.kdfThreads, () => { })
|
||||
}
|
||||
this.savedWalletDataJson = JSON.stringify(data)
|
||||
}
|
||||
|
||||
async showQRCode() {
|
||||
await this.setSavedWalletDataJson()
|
||||
let el = this.shadowRoot.getElementById('login-qr-code')
|
||||
el.style.display = 'flex'
|
||||
}
|
||||
}
|
||||
|
||||
window.customElements.define('qr-login-view', QRLoginView)
|
@ -9,6 +9,7 @@ import '@material/mwc-button'
|
||||
import './account-view.js'
|
||||
import './security-view.js'
|
||||
import './notifications-view.js'
|
||||
import './qr-login-view.js'
|
||||
|
||||
import { doLogout } from '../../redux/app/app-actions.js'
|
||||
|
||||
@ -225,6 +226,7 @@ class UserSettings extends connect(store)(LitElement) {
|
||||
<ul>
|
||||
<li @click=${ () => this.setSettingsView('info')} ><a class=${this.selectedView.id === 'info' ? 'active' : ''} href="javascript:void(0)">${translate("settings.account")}</a></li>
|
||||
<li @click=${ () => this.setSettingsView('security')} ><a class=${this.selectedView.id === 'security' ? 'active' : ''} href="javascript:void(0)">${translate("settings.security")}</a></li>
|
||||
<li @click=${ () => this.setSettingsView('qr-login')} ><a class=${this.selectedView.id === 'qr-login' ? 'active' : ''} href="javascript:void(0)">${translate("settings.qr_login_menu_item") }</a></li>
|
||||
<li @click=${ () => this.setSettingsView('notification')} ><a class=${this.selectedView.id === 'notification' ? 'active' : ''} href="javascript:void(0)">${translate("settings.notifications")}</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
@ -250,6 +252,8 @@ class UserSettings extends connect(store)(LitElement) {
|
||||
return html`<security-view></security-view>`;
|
||||
} else if (selectedView.id === 'notification') {
|
||||
return html`<notifications-view></notifications-view>`;
|
||||
} else if (selectedView.id === 'qr-login') {
|
||||
return html`<qr-login-view></qr-login-view>`;
|
||||
}
|
||||
}
|
||||
|
||||
@ -260,6 +264,8 @@ class UserSettings extends connect(store)(LitElement) {
|
||||
return html`${translate("settings.accountsecurity")}`;
|
||||
} else if (this.selectedView.id === 'notification') {
|
||||
return html`UI ${translate("settings.notifications")}`;
|
||||
} else if (this.selectedView.id === 'qr-login') {
|
||||
return html`${translate("settings.qr_login_menu_item")}`;
|
||||
}
|
||||
}
|
||||
|
||||
@ -270,6 +276,8 @@ class UserSettings extends connect(store)(LitElement) {
|
||||
return this.selectedView = { id: 'security', name: 'Account Security' }
|
||||
} else if (pageId === 'notification') {
|
||||
return this.selectedView = { id: 'notification', name: 'UI Notifications' }
|
||||
} else if (pageId === 'qr-login') {
|
||||
return this.selectedView = { id: 'qr-login', name: 'QR Login' }
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user