This commit is contained in:
AlphaX-Projects 2022-04-09 11:35:10 -07:00 committed by GitHub
parent c7d111cd07
commit f484227ca6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 573 additions and 213 deletions

View File

@ -2,6 +2,7 @@ import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../store.js'
import { doPageUrl } from '../redux/app/app-actions.js'
import { translate, translateUnsafeHTML } from 'lit-translate'
import '@material/mwc-icon'
import '@material/mwc-button'
@ -13,7 +14,8 @@ class AppInfo extends connect(store)(LitElement) {
nodeStatus: { type: Object },
nodeInfo: { type: Object },
nodeConfig: { type: Object },
pageUrl: { type: String }
pageUrl: { type: String },
theme: { type: String, reflect: true }
}
}
@ -89,13 +91,14 @@ class AppInfo extends connect(store)(LitElement) {
this.nodeInfo = {}
this.nodeStatus = {}
this.pageUrl = ''
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
return html`
<div id="profileInMenu">
<span class="info">Block Height: ${this.blockInfo.height ? this.blockInfo.height : ''} <span class=${this.cssStatus}>${this._renderStatus()}</span></span>
<span class="info">UI Version: ${this.nodeConfig.version ? this.nodeConfig.version : ''}</span>
<span class="info">${translate("appinfo.blockheight")}: ${this.blockInfo.height ? this.blockInfo.height : ''} <span class=${this.cssStatus}>${this._renderStatus()}</span></span>
<span class="info">${translate("appinfo.uiversion")}: ${this.nodeConfig.version ? this.nodeConfig.version : ''}</span>
${this._renderCoreVersion()}
<a id="pageLink"></a>
</div>
@ -108,13 +111,13 @@ class AppInfo extends connect(store)(LitElement) {
_renderStatus() {
if (this.nodeStatus.isMintingPossible === true && this.nodeStatus.isSynchronizing === true) {
this.cssStatus = 'blue'
return '(Minting)'
return html`${translate("appinfo.minting")}`
} else if (this.nodeStatus.isMintingPossible === true && this.nodeStatus.isSynchronizing === false) {
this.cssStatus = 'blue'
return '(Minting)'
return html`${translate("appinfo.minting")}`
} else if (this.nodeStatus.isMintingPossible === false && this.nodeStatus.isSynchronizing === true) {
this.cssStatus = 'black'
return `(Synchronizing... ${this.nodeStatus.syncPercent !== undefined ? this.nodeStatus.syncPercent + '%' : ''})`
return `(${translate("appinfo.synchronizing")}... ${this.nodeStatus.syncPercent !== undefined ? this.nodeStatus.syncPercent + '%' : ''})`
} else if (this.nodeStatus.isMintingPossible === false && this.nodeStatus.isSynchronizing === false) {
this.cssStatus = 'black'
return ''
@ -124,7 +127,7 @@ class AppInfo extends connect(store)(LitElement) {
}
_renderCoreVersion() {
return html`<span class="info">Core Version: ${this.nodeInfo.buildVersion ? this.nodeInfo.buildVersion : ''}</span>`
return html`<span class="info">${translate("appinfo.coreversion")}: ${this.nodeInfo.buildVersion ? this.nodeInfo.buildVersion : ''}</span>`
setTimeout(_renderCoreVersion(), 60000)
}

View File

@ -1,6 +1,7 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../store.js'
import { translate, translateUnsafeHTML } from 'lit-translate'
import '@polymer/paper-icon-button/paper-icon-button.js'
import '@polymer/iron-icons/iron-icons.js'
@ -10,8 +11,10 @@ import './app-info.js'
import './sidenav-menu.js'
import './show-plugin.js'
import './qort-theme-toggle.js'
import './language-selector.js'
import '@material/mwc-drawer'
import '@material/mwc-icon'
import '@polymer/app-layout/app-layout.js'
import '@polymer/paper-ripple'
@ -22,13 +25,20 @@ import './logout-view/logout-view.js'
class AppView extends connect(store)(LitElement) {
static get properties() {
return {
config: { type: Object }
config: { type: Object },
theme: { type: String, reflect: true }
}
}
static get styles() {
return [
css`
* {
--mdc-theme-primary: rgb(3, 169, 244);
--mdc-theme-secondary: var(--mdc-theme-primary);
--mdc-theme-error: rgb(255, 89, 89);
}
:host {
--app-drawer-width: 260px;
}
@ -82,6 +92,11 @@ class AppView extends connect(store)(LitElement) {
]
}
constructor() {
super()
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
return html`
<app-drawer-layout responsive-width='${getComputedStyle(document.body).getPropertyValue('--layout-breakpoint-desktop')}' fullbleed >
@ -105,13 +120,21 @@ class AppView extends connect(store)(LitElement) {
<img src="${this.config.coin.logo}" style="height:32px; padding-left:12px;">
</span>
</div>
<div style="display: inline;">
<span>
<img src="/img/${translate("selectmenu.languageflag")}-flag-round-icon-32.png" style="width: 32px; height: 32px; padding-top: 4px;">
</span>
</div>
<div>&nbsp;&nbsp;</div>
<language-selector></language-selector>
<div>&nbsp;&nbsp;&nbsp;&nbsp;</div>
<qort-theme-toggle></qort-theme-toggle>
<div>&nbsp;&nbsp;&nbsp;&nbsp;</div>
<div style="display:inline">
<div style="display: inline;">
<paper-icon-button icon="icons:settings" @click=${() => this.openSettings()} title="Settings"></paper-icon-button>
</div>
<div>&nbsp;&nbsp;</div>
<div style="display:inline">
<div style="display: inline;">
<paper-icon-button icon="icons:exit-to-app" @click=${() => this.openLogout()} title="Logout"></paper-icon-button>
</div>
<div>&nbsp;&nbsp;</div>
@ -125,11 +148,8 @@ class AppView extends connect(store)(LitElement) {
`
}
constructor() {
super()
}
firstUpdated() {
// ...
}
stateChanged(state) {

View File

@ -0,0 +1,86 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../store.js'
import { use, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
registerTranslateConfig({
loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
})
const checkLanguage = localStorage.getItem('qortalLanguage')
if (checkLanguage === null || checkLanguage.length === 0) {
localStorage.setItem('qortalLanguage', 'us')
use('us')
} else {
use(checkLanguage)
}
class LanguageSelector extends connect(store)(LitElement) {
static get properties() {
return {
config: { type: Object },
theme: { type: String, reflect: true }
}
}
static get styles() {
return [
css`
select {
width: 175px;
height: 34px;
padding: 5px 0px 5px 5px;
font-size: 16px;
border: 1px solid var(--black);
border-radius: 3px;
color: var(--black);
background: var(--white);
}
*:focus {
outline: none;
}
select option {
line-height: 34px;
}
`
]
}
constructor() {
super()
}
render() {
return html`
<div style="display: inline;">
<select @change="${this.changeLanguage}">
<option value="us">${translate("selectmenu.selectlanguage")}</option>
<option value="us">US - ${translate("selectmenu.english")}</option>
<option value="cn">CN - ${translate("selectmenu.chinese")}</option>
<option value="de">DE - ${translate("selectmenu.german")}</option>
<option value="fr">FR - ${translate("selectmenu.french")}</option>
<option value="pl">PL - ${translate("selectmenu.polish")}</option>
<option value="sp">SP - ${translate("selectmenu.spanish")}</option>
</select>
</div>
`
}
firstUpdated() {
// ...
}
changeLanguage(event) {
use(event.target.value)
localStorage.setItem('qortalLanguage', event.target.value)
}
stateChanged(state) {
this.config = state.config
}
}
window.customElements.define('language-selector', LanguageSelector)

View File

@ -1,6 +1,7 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../../store.js'
import { translate, translateUnsafeHTML } from 'lit-translate'
import { createWallet } from '../../../../qortal-ui-crypto/api/createWallet.js'
import FileSaver from 'file-saver'
@ -47,19 +48,33 @@ class CreateAccountSection extends connect(store)(LitElement) {
_pass: { type: String },
_name: { type: String },
isDownloadedBackup: { type: Boolean },
nodeConfig: { type: Object }
nodeConfig: { type: Object },
theme: { type: String, reflect: true }
}
}
static get styles() {
return [
css`
* {
* {
--mdc-theme-primary: rgb(3, 169, 244);
--mdc-theme-secondary: var(--mdc-theme-primary);
--paper-input-container-focus-color: var(--mdc-theme-primary);
--mdc-theme-surface: var(--white);
--mdc-dialog-content-ink-color: var(--black);
--mdc-checkbox-unchecked-color: var(--black);
--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);
--_lumo-grid-border-color: var(--border);
--_lumo-grid-secondary-border-color: var(--border2);
}
.red {
--mdc-theme-primary: red;
}
@ -69,26 +84,27 @@ class CreateAccountSection extends connect(store)(LitElement) {
constructor() {
super()
this.nextText = 'Next'
this.backText = 'Back'
this.nextText = this.renderNextText()
this.backText = this.renderBackText()
this.nextDisabled = false
this._pass = ''
this._name = ''
this.selectedPage = 'info'
this.nextButtonText = 'Next'
this.nextButtonText = this.renderNextText()
this.saveAccount = true
this.showSeedphrase = false
this.isDownloadedBackup = true
this.createAccountLoading = false
const welcomeMessage = 'Welcome to Qortal'
const welcomeMessage = this.renderWelcomeText()
this.welcomeMessage = welcomeMessage
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
this.pages = {
info: {
next: e => {
this.error = false
this.errorMessage = ''
this.nextButtonText = 'Create'
this.nextButtonText = this.renderCreateText()
this.selectPage('password')
this.updateNext()
},
@ -106,7 +122,7 @@ class CreateAccountSection extends connect(store)(LitElement) {
if (password === '') {
snackbar.add({
labelText: 'Please enter a Password!',
labelText: this.renderEnterPassText(),
dismiss: true
})
return
@ -114,7 +130,7 @@ class CreateAccountSection extends connect(store)(LitElement) {
if (password != rePassword) {
snackbar.add({
labelText: 'Passwords not match!',
labelText: this.renderNotMatchText(),
dismiss: true
})
return
@ -122,7 +138,7 @@ class CreateAccountSection extends connect(store)(LitElement) {
if (password.length < 8 && lastPassword !== password) {
snackbar.add({
labelText: 'Your password is less than 8 characters! This is not recommended. You can continue to ignore this warning.',
labelText: this.renderLessText(),
dismiss: true
})
lastPassword = password
@ -131,7 +147,7 @@ class CreateAccountSection extends connect(store)(LitElement) {
if (this.saveAccount === true && nameInput === '') {
snackbar.add({
labelText: 'Please enter a Name!',
labelText: this.renderEnterNameText(),
dismiss: true
})
return
@ -179,19 +195,19 @@ class CreateAccountSection extends connect(store)(LitElement) {
next: e => {
if (!this.isDownloadedBackup) {
snackbar.add({
labelText: 'Your Wallet BackUp file get downloaded!',
labelText: this.renderBackupText(),
dismiss: true
})
} else {
if (this.saveAccount) {
ripple.welcomeMessage = 'Preparing Your Account'
ripple.welcomeMessage = this.renderPrepareText()
ripple.open({
x: e.clientX,
y: e.clientY
})
.then(() => {
store.dispatch(doStoreWallet(this._wallet, this._pass, this._name, () => {
ripple.loadingMessage = 'Loading, Please wait...'
ripple.loadingMessage = this.renderLoadingText()
}))
.then(() => {
store.dispatch(doLogin(this._wallet))
@ -345,21 +361,24 @@ class CreateAccountSection extends connect(store)(LitElement) {
<div page="info">
<div id="infoContent" class="section-content">
<br>
<h3 style="text-align:center; margin-top: 0; font-weight: 100; font-family: 'Roboto Mono', monospace;">Create account</h3>
<p>
Welcome to Qortal, you will find it to be similar to that of an RPG game,
you, as a minter on the Qortal network (if you choose to become one) will have the chance to level your account up,
giving you both more of the QORT block reward and also larger influence over the network in terms of voting on decisions for the platform.
<h3 style="text-align: center; margin-top: 0; color: var(--black); font-weight: 100; font-family: 'Roboto Mono', monospace;">${translate("login.createaccount")}</h3>
<p style="color: var(--black);">
${translate("login.createwelcome")}
</p>
<p style="margin-bottom:0;">
A <paper-button id="myseedshow" @click=${() => this.shadowRoot.querySelector('#mySeedDialog').show()}>seedphrase</paper-button><paper-tooltip for="myseedshow" position="top" animation-delay="0">Click to view seedphrase</paper-tooltip> will be randomly generated in background. This is used as your private key generator for your blockchain account in Qortal.
<p style="color: var(--black); margin-bottom:0;">
${translate("login.createa")} <paper-button id="myseedshow" @click=${() => this.shadowRoot.querySelector('#mySeedDialog').show()}>${translate("login.seedphrase")}</paper-button><paper-tooltip for="myseedshow" position="top" animation-delay="0">${translate("login.click")}</paper-tooltip> ${translate("login.willbe")}
</p>
<p style="margin-bottom:0; text-align:center;">
Create your Qortal account by clicking NEXT below.
<p style="color: var(--black); margin-bottom: 0; text-align: center;">
${translate("login.clicknext")}
</p><br>
</div>
<mwc-dialog id="mySeedDialog" heading="Your created Seedphrase">
<mwc-dialog id="mySeedDialog">
<div style="min-height:250px; min-width: 300px; box-sizing: border-box; position: relative;">
<div style="text-align: center;">
<h2 style="color: var(--black);">${translate("login.createdseed")}</h2>
<hr>
</div>
<br>
<div style="border-radius: 4px; padding-top: 8px; background: rgba(3,169,244,0.1); margin-top: 24px;">
<div style="display: inline-block; padding:12px; width:calc(100% - 84px);">
<random-sentence-generator
@ -383,33 +402,32 @@ class CreateAccountSection extends connect(store)(LitElement) {
-->
</div><br>
<div class="horizontal-center">
<mwc-button raised label="Save Seedphrase" icon="save" @click=${() => this.downloadSeedphrase()}></mwc-button>
<mwc-button raised label="${translate("login.saveseed")}" icon="save" @click=${() => this.downloadSeedphrase()}></mwc-button>
</div>
</div>
<mwc-button slot="primaryAction" dialogAction="cancel" class="red">Close</mwc-button>
<mwc-button slot="primaryAction" dialogAction="cancel" class="red">${translate("general.close")}</mwc-button>
</mwc-dialog>
</div>
<div page="password">
<div id="saveContent" class="section-content">
<h3 style="text-align: center;">Save in browser</h3>
<p style="text-align: justify;">Your account is now ready to be created. It will be saved in this browser. If you do not want your new account to be saved in your browser, you can uncheck the box below.
You will still be able to login with your new account(after logging out), using your wallet backup file that you MUST download once you create your account.</p>
<h3 style="color: var(--black); text-align: center;">${translate("login.savein")}</h3>
<p style="color: var(--black); text-align: justify;">${translate("login.ready")}</p>
<div style="display:flex;" ?hidden="${!this.saveAccount}">
<mwc-icon style="padding: 10px; padding-left:0; padding-top: 42px;">perm_identity</mwc-icon>
<vaadin-text-field style="width:100%;" label="Name" id="nameInput"></vaadin-text-field>
<mwc-icon style="color: var(--black); padding: 10px; padding-left:0; padding-top: 42px;">perm_identity</mwc-icon>
<vaadin-text-field style="width:100%;" label="${translate("login.name")}" id="nameInput"></vaadin-text-field>
</div>
<div style="display:flex;">
<mwc-icon style="padding: 10px; padding-left:0; padding-top: 42px;">password</mwc-icon>
<vaadin-password-field style="width:100%;" label="Password" id="password" autofocus></vaadin-password-field>
<mwc-icon style="color: var(--black); padding: 10px; padding-left:0; padding-top: 42px;">password</mwc-icon>
<vaadin-password-field style="width:100%;" label="${translate("login.password")}" id="password" autofocus></vaadin-password-field>
</div>
<div style="display:flex;">
<mwc-icon style="padding: 10px; padding-left:0; padding-top: 42px;">password</mwc-icon>
<vaadin-password-field style="width:100%;" label="Confirm Password" id="rePassword"></vaadin-password-field>
<mwc-icon style="color: var(--black); padding: 10px; padding-left:0; padding-top: 42px;">password</mwc-icon>
<vaadin-password-field style="width:100%;" label="${translate("login.confirmpass")}" id="rePassword"></vaadin-password-field>
</div>
<div style="text-align:right; vertical-align: top; line-height: 40px; margin:0;">
<mwc-formfield alignEnd label="Save in this browser.">
<label for="saveInBrowserCheckbox" @click=${() => this.shadowRoot.getElementById('saveInBrowserCheckbox').click()}></label>
<mwc-formfield alignEnd>
<label for="saveInBrowserCheckbox" @click=${() => this.shadowRoot.getElementById('saveInBrowserCheckbox').click()}><span style="color: var(--black);">${translate("login.save")}</span></label>
<mwc-checkbox style="display: inline; id="saveInBrowserCheckbox" @click=${e => { this.saveAccount = !e.target.checked }} ?checked=${this.saveAccount}></mwc-checkbox>
</mwc-formfield>
</div>
@ -418,16 +436,16 @@ class CreateAccountSection extends connect(store)(LitElement) {
<div page="backup">
<div id="downloadBackup" class="section-content">
<h3 style="text-align: center;">Save Wallet BackUp File</h3>
<p style="text-align: justify;">Your account is now created${this.saveAccount ? ' and will be saved in this browser.' : '.'}</p>
<p style="margin:0;">
This file is the <strong>ONLY</strong> way to access your account on a system that doesn't have it saved to the app/browser. <strong>BE SURE TO BACKUP THIS FILE IN MULTIPLE PLACES.</strong> The file is encrypted very securely and decrypted with your local password you created in the previous step. You can save it anywhere securely, but be sure to do that in multiple locations.
</p>
<h3 style="color: var(--black); text-align: center;">${translate("login.savewallet")}</h3>
<p style="color: var(--black); text-align: justify;">${translate("login.created1")}${this.saveAccount ? this.renderCreateSaveText() : '.'}</p>
<p style="color: var(--black); margin: 0;">
${translate("login.backup")}
</p><br>
<div id="download-area">
<div style="line-height:40px;">
<span style="padding-top:6px; margin-right: 10px;">Download Wallet BackUp File</span>
<slot id="trigger" name="inputTrigger" @click=${() => this.downloadBackup(this._wallet)} style="dispay: inline;">
<mwc-button><mwc-icon>cloud_download</mwc-icon>&nbsp; Save</mwc-button>
<div style="line-height: 40px;">
<span style="color: var(--black); padding-top: 6px; margin-right: 10px; text-align: center;">${translate("login.downloadbackup")}</span>
<slot id="trigger" name="inputTrigger" @click=${() => this.downloadBackup(this._wallet)} style="dispay: inline; text-align: center;">
<mwc-button><mwc-icon>cloud_download</mwc-icon>&nbsp; ${translate("general.save")}</mwc-button>
</slot>
</div>
</div>
@ -456,6 +474,62 @@ class CreateAccountSection extends connect(store)(LitElement) {
this._name = ''
}
renderBackText() {
return html`${translate("general.back")}`
}
renderNextText() {
return html`${translate("general.next")}`
}
renderCreateText() {
return html`${translate("general.create")}`
}
renderContinueText() {
return html`${translate("general.continue")}`
}
renderPrepareText() {
return html`${translate("login.prepare")}`
}
renderBackupText() {
return html`${translate("login.downloaded")}`
}
renderWelcomeText() {
return html`${translate("login.welmessage")}`
}
renderEnterPassText() {
return html`${translate("login.pleaseenter")}`
}
renderNotMatchText() {
return html`${translate("login.notmatch")}`
}
renderLessText() {
return html`${translate("login.lessthen8")}`
}
renderEnterNameText() {
return html`${translate("login.entername")}`
}
renderLoadingText() {
return html`${translate("login.loading")}`
}
renderCreateAccountText() {
return html`${translate("login.createaccount")}`
}
renderCreateSaveText() {
return html`${translate("login.created2")}`
}
_pageChange(newPage, oldPage) {
if (!this.shadowRoot.querySelector('#createAccountPages') || !newPage) {
return
@ -482,16 +556,16 @@ class CreateAccountSection extends connect(store)(LitElement) {
updateNext() {
if (this.selectedPage === 'info') {
this.nextText = 'Next'
this.nextText = this.renderNextText()
this.nextDisabled = false
} else if (this.selectedPage === 'password') {
this.nextDisabled = false
this.nextText = 'Create Account'
this.nextText = this.renderCreateAccountText()
} else if (this.selectedPage === 'backup') {
this.downloadBackup(this._wallet)
this.nextDisabled = false
this.backHidden = true
this.nextText = 'Continue'
this.nextText = this.renderContinueText()
}
this.updatedProperty()
}

View File

@ -2,6 +2,7 @@ import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../../store.js'
import { checkApiKey } from '../../apiKeyUtils.js'
import { translate, translateUnsafeHTML } from 'lit-translate'
import '@material/mwc-button'
import '@material/mwc-checkbox'
@ -43,19 +44,40 @@ class LoginSection extends connect(store)(LitElement) {
saveInBrowser: { type: Boolean },
backedUpWalletJSON: { type: Object },
backedUpSeedLoading: { type: Boolean },
nodeConfig: { type: Object }
nodeConfig: { type: Object },
theme: { type: String, reflect: true }
}
}
static get styles() {
return [
css`
* {
* {
--mdc-theme-primary: rgb(3, 169, 244);
--mdc-theme-secondary: var(--mdc-theme-primary);
--paper-input-container-focus-color: var(--mdc-theme-primary);
--mdc-theme-surface: var(--white);
--mdc-dialog-content-ink-color: var(--black);
--mdc-checkbox-unchecked-color: var(--black);
--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);
--_lumo-grid-border-color: var(--border);
--_lumo-grid-secondary-border-color: var(--border2);
}
mwc-formfield {
color: var(--black);
}
.red {
--mdc-theme-primary: red;
}
`
]
}
@ -63,33 +85,34 @@ class LoginSection extends connect(store)(LitElement) {
constructor() {
super()
this.nextHidden = true
this.backText = 'Back'
this.backText = this.renderBackText()
this.backedUpSeedLoading = false
this.hasStoredWallets = Object.keys(store.getState().user.storedWallets).length > 0
this.selectedPage = this.hasStoredWallets ? 'storedWallet' : 'loginOptions'
this.selectedWallet = {}
this.loginErrorMessage = ''
this.saveInBrowser = false
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
this.loginOptions = [
{
page: 'phrase',
linkText: 'Seedphrase',
linkText: this.renderSeedText(),
icon: 'short_text'
},
{
page: 'storedWallet',
linkText: 'Saved account',
linkText: this.renderSavedText(),
icon: 'save'
},
{
page: 'seed',
linkText: 'Qora address seed',
linkText: this.renderQoraText(),
icon: 'clear_all'
},
{
page: 'backedUpSeed',
linkText: 'Qortal wallet backup',
linkText: this.renderBackupText(),
icon: 'insert_drive_file'
}
]
@ -121,7 +144,7 @@ class LoginSection extends connect(store)(LitElement) {
border-top: 1px solid #eee;
overflow-y: auto;
box-shadow: 0 0 15px 0px rgb(0 0 0 / 10%);
background: rgb(253 253 253 / 50%);
background: var(--white);
margin: 2vh;
}
@ -153,13 +176,15 @@ class LoginSection extends connect(store)(LitElement) {
.wallet .walletAddress {
height: 40px !important;
line-height: 40px !important;
color: var(--black);
}
.wallet .walletName {
color: var(--black);
}
.wallet p span {
color: #888;
color: var(--black);
font-size: 12px;
width: 50px;
display: inline-block;
@ -184,6 +209,7 @@ class LoginSection extends connect(store)(LitElement) {
.loginIcon {
padding-right: 12px;
margin-top: -2px;
color: var(--black);
}
*[hidden] {
@ -247,7 +273,7 @@ class LoginSection extends connect(store)(LitElement) {
<div id="pagesContainer">
<iron-pages style="padding: 0;" selected="${this.selectedPage}" attr-for-selected="page" id="loginPages">
<div page="loginOptions">
<h3>How would you like to login?</h3>
<h3 style="color: var(--black);">${translate("login.howlogin")}</h3>
${this.loginOptions.map(({ page, linkText, icon }) => html`
<div class="login-option" @click=${() => { this.selectedPage = page }}>
<paper-ripple></paper-ripple>
@ -255,7 +281,7 @@ class LoginSection extends connect(store)(LitElement) {
<mwc-icon class='loginIcon'>${icon}</mwc-icon>
</div>
<div>
${linkText}
<span style="color: var(--black)">${linkText}</span>
</div>
</div>
`)}
@ -263,23 +289,44 @@ class LoginSection extends connect(store)(LitElement) {
<div page="storedWallet" id="walletsPage">
<div style="text-align: center; padding-left:0;">
<h1 style="padding:0;">Your accounts</h1>
<p style="margin:0; padding: 0 0 12px 0;">Click your account to login with it</p>
<h1 style="padding:0; color: var(--black);">${translate("login.youraccounts")}</h1>
<p style="margin:0; padding: 0 0 12px 0; color: var(--black);">${translate("login.click")}</p>
</div>
<div id="wallets">
${(Object.entries(this.wallets || {}).length < 1) ? html`
<p style="padding: 0 0 6px 0;">You need to create or save an account before you can log in!</p>
<p style="color: var(--black); padding: 0 0 6px 0;">${translate("login.needcreate")}</p>
` : ''}
${Object.entries(this.wallets || {}).map(wallet => html`
<div class="wallet">
<div class="selectWallet" @click=${() => this.selectWallet(wallet[1])}>
<paper-ripple></paper-ripple>
<div class='wallet-details'>
<p class='walletName'><span>Name</span>${wallet[1].name || "No saved name"}</p>
<p class="walletAddress"><span>Address</span>${wallet[1].address0}</p>
<p class='walletName'><span style="color: var(--black);">${translate("login.name")}</span>${wallet[1].name || "No saved name"}</p>
<p class="walletAddress"><span style="color: var(--black);">${translate("login.address")}</span>${wallet[1].address0}</p>
</div>
</div>
<mwc-icon-button class="removeWallet" @click=${(e) => this.removeWallet(wallet[1].address0)} icon="clear"></mwc-icon-button>
<mwc-icon-button class="removeWallet" @click="${(e) => this.toDeleteWallet(wallet[1].address0)}" icon="clear"></mwc-icon-button>
<mwc-dialog id="deleteWalletDialog">
<div style="text-align: center;">
<h2>Qortal UI</h2>
<hr>
</div>
<br>
<p>${translate("login.areyousure")}</p>
<mwc-button
slot="primaryAction"
@click="${(e) => this.removeWallet(this.myToDeleteWallet)}"
>
${translate("general.yes")}
</mwc-button>
<mwc-button
slot="secondaryAction"
dialogAction="cancel"
class="red"
>
${translate("general.no")}
</mwc-button>
</mwc-dialog>
</div>
`)}
</div>
@ -288,32 +335,32 @@ class LoginSection extends connect(store)(LitElement) {
<div page="phrase" id="phrasePage">
<div style="padding:0;">
<div style="display:flex;">
<mwc-icon style="padding: 10px; padding-left:0; padding-top: 42px;">short_text</mwc-icon>
<vaadin-password-field style="width:100%;" label="Seedphrase" id="existingSeedPhraseInput"></vaadin-password-field>
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">short_text</mwc-icon>
<vaadin-password-field style="width:100%;" label="${translate("login.seed")}" id="existingSeedPhraseInput" autofocus></vaadin-password-field>
</div>
</div>
</div>
<div page="seed" id="seedPage">
<div>
<div style="display:flex;">
<mwc-icon style="padding: 10px; padding-left:0; padding-top: 42px;">clear_all</mwc-icon>
<vaadin-password-field style="width:100%;" label="Qora address seed" id="v1SeedInput"></vaadin-password-field>
<div style="display: flex;">
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">clear_all</mwc-icon>
<vaadin-password-field style="width: 100%;" label="${translate("login.qora")}" id="v1SeedInput" autofocus></vaadin-password-field>
</div>
</div>
</div>
<div page="unlockStored" id="unlockStoredPage">
<div style="text-align:center;">
<mwc-icon id='accountIcon' style=" padding-bottom:24px;">account_circle</mwc-icon>
<mwc-icon id='accountIcon' style="padding-bottom: 24px; color: var(--black);">account_circle</mwc-icon>
<br>
<span style="font-size:14px; font-weight:100; font-family: 'Roboto Mono', monospace;">${this.selectedWallet.address0}</span>
<span style="font-size:14px; font-weight: 100; font-family: 'Roboto Mono', monospace; color: var(--black);">${this.selectedWallet.address0}</span>
</div>
</div>
<div page="backedUpSeed">
${!this.backedUpSeedLoading ? html`
<h3>Upload your qortal backup</h3>
<h3 style="color: var(--black);">${translate("login.upload")}</h3>
<frag-file-input accept=".zip,.json" @file-read-success="${e => this.loadBackup(e.detail.result)}"></frag-file-input>
` : html`
<paper-spinner-lite active style="display: block; margin: 0 auto;"></paper-spinner-lite>
@ -321,20 +368,20 @@ class LoginSection extends connect(store)(LitElement) {
</div>
<div page="unlockBackedUpSeed">
<h3>Decrypt backup</h3>
<h3 style="text-align: center; color: var(--black);">${translate("login.decrypt")}</h3>
</div>
</iron-pages>
<iron-collapse style="" ?opened=${this.showName(this.selectedPage)} id="passwordCollapse">
<div style="display:flex;">
<mwc-icon style="padding: 10px; padding-left:0; padding-top: 42px;">perm_identity</mwc-icon>
<vaadin-text-field style="width:100%;" label="Name" id="nameInput"></vaadin-text-field>
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">perm_identity</mwc-icon>
<vaadin-text-field style="width:100%;" label="${translate("login.name")}" id="nameInput"></vaadin-text-field>
</div>
</iron-collapse>
<iron-collapse style="" ?opened=${this.showPassword(this.selectedPage)} id="passwordCollapse">
<div style="display:flex;">
<mwc-icon style="padding: 10px; padding-left:0; padding-top: 42px;">password</mwc-icon>
<vaadin-password-field style="width:100%;" label="Password" id="password" @keyup=${e => this.keyupEnter(e, e => this.emitNext(e))} autofocus></vaadin-password-field>
<mwc-icon style="padding: 10px; padding-left: 0; padding-top: 42px; color: var(--black);">password</mwc-icon>
<vaadin-password-field style="width:100%;" label="${translate("login.password")}" id="password" @keyup=${e => this.keyupEnter(e, e => this.emitNext(e))} autofocus></vaadin-password-field>
</div>
</iron-collapse>
@ -342,9 +389,9 @@ class LoginSection extends connect(store)(LitElement) {
${this.loginErrorMessage}
</div>
${this.showPasswordCheckboxPages.includes(this.selectedPage) ? html`
<div style="text-align:right; vertical-align: top; line-height: 40px; margin:0;">
<mwc-formfield alignEnd label="Save in this browser.">
<label for="storeCheckbox" class="checkboxLabel" @click=${() => this.shadowRoot.getElementById('storeCheckbox').click()}></label>
<div style="text-align: right; vertical-align: top; line-height: 40px; margin:0;">
<mwc-formfield alignEnd>
<label for="storeCheckbox" class="checkboxLabel" @click=${() => this.shadowRoot.getElementById('storeCheckbox').click()}><span style="color: var(--black);">${translate("login.save")}</span></label>
<mwc-checkbox style="display: inline;" id="storeCheckbox" @click=${e => { this.saveInBrowser = !e.target.checked }} ?checked="${this.saveInBrowser}"></mwc-checkbox>
</mwc-formfield>
</div>
@ -370,20 +417,63 @@ class LoginSection extends connect(store)(LitElement) {
})
}
renderBackText() {
return html`${translate("general.back")}`
}
renderNextText() {
return html`${translate("general.next")}`
}
renderLoginText() {
return html`${translate("login.login")}`
}
renderSeedText() {
return html`${translate("login.seed")}`
}
renderSavedText() {
return html`${translate("login.saved")}`
}
renderQoraText() {
return html`${translate("login.qora")}`
}
renderBackupText() {
return html`${translate("login.backup")}`
}
renderPrepareText() {
return html`${translate("login.prepare")}`
}
renderError1Text() {
return html`${translate("login.error1")}`
}
renderError2Text() {
return html`${translate("login.error2")}`
}
selectWallet(wallet) {
this.selectedWallet = wallet
this.selectedPage = 'unlockStored'
}
toDeleteWallet(deleteAddress) {
this.myToDeleteWallet = deleteAddress
this.shadowRoot.querySelector('#deleteWalletDialog').show()
}
removeWallet(walletAddress) {
if (window.confirm('Are you sure you want to remove this wallet from saved wallets?')) {
delete store.getState().user.storedWallets[walletAddress]
this.wallets = store.getState().user.storedWallets
store.dispatch(
doRemoveWallet(walletAddress)
)
this.cleanup()
}
delete store.getState().user.storedWallets[walletAddress]
this.wallets = store.getState().user.storedWallets
store.dispatch(
doRemoveWallet(walletAddress)
)
this.cleanup()
}
stateChanged(state) {
@ -414,7 +504,7 @@ class LoginSection extends connect(store)(LitElement) {
try {
pf = JSON.parse(file)
} catch (e) {
this.loginErrorMessage = 'Backup must be valid JSON'
this.loginErrorMessage = this.renderError1Text()
}
try {
@ -460,7 +550,7 @@ class LoginSection extends connect(store)(LitElement) {
].includes(selectedPage)
) || (['unlockBackedUpSeed', 'unlockStored'].includes(selectedPage))
if (willBeShown)//if the password will be displayed lt's give it focus
if (willBeShown)
this.shadowRoot.getElementById('password').focus()
return willBeShown
@ -522,11 +612,11 @@ class LoginSection extends connect(store)(LitElement) {
type = type === 'unlockBackedUpSeed' ? 'backedUpSeed' : type
if (!this.loginOptionIsSelected(type)) {
throw new Error('Login option not selected page')
throw new Error(this.renderError2Text())
}
// First decrypt...
this.loadingRipple.welcomeMessage = 'Preparing Your Account'
this.loadingRipple.welcomeMessage = this.renderPrepareText()
this.loadingRipple.open({
x: e.clientX,
y: e.clientY
@ -585,12 +675,12 @@ class LoginSection extends connect(store)(LitElement) {
updateNext() {
if (['phrase', 'seed', 'unlockStored', 'unlockBackedUpSeed'].includes(this.selectedPage)) {
this.nextText = 'Login'
this.nextText = this.renderLoginText()
this.nextHidden = false
// Should enable/disable the next button based on whether or not password are inputted
} else if (['storedWallet', 'loginOptions', 'backedUpSeed'].includes(this.selectedPage)) {
this.nextHidden = true
this.nextText = 'Next'
this.nextText = this.renderNextText()
}
this.updatedProperty()
@ -618,6 +708,7 @@ class LoginSection extends connect(store)(LitElement) {
this.shadowRoot.querySelector('#password').value = ''
this.hasStoredWallets = Object.keys(store.getState().user.storedWallets).length > 0
this.selectedPage = this.hasStoredWallets ? 'storedWallet' : 'loginOptions'
this.shadowRoot.querySelector('#deleteWalletDialog').close()
}
}

View File

@ -27,20 +27,18 @@ class LoginView extends connect(store)(LitElement) {
rippleIsOpen: { type: Boolean },
config: { type: Object },
rippleLoadingMessage: { type: String },
selectedPageElement: {}
selectedPageElement: {},
theme: { type: String, reflect: true }
}
}
static get styles() {
return [
css`
`
css``
]
}
getPreSelectedPage() {
return 'welcome'
}
@ -55,6 +53,7 @@ class LoginView extends connect(store)(LitElement) {
login: 2
}
this.rippleLoadingMessage = 'Getting information'
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
firstUpdated() {
@ -107,7 +106,7 @@ class LoginView extends connect(store)(LitElement) {
}
.login-page {
background: url("/img/qortal_background_light_.jpg");
background: var(--background);
background-repeat: no-repeat;
background-attachment: fixed;
background-position: center;

View File

@ -1,4 +1,5 @@
import { LitElement, html, css } from 'lit'
import { translate, translateUnsafeHTML } from 'lit-translate'
import '@material/mwc-button'
@ -11,19 +12,27 @@ class WelcomePage extends LitElement {
backHidden: { type: Boolean, notify: true },
backDisabled: { type: Boolean, notify: true },
backText: { type: String, notify: true },
hideNav: { type: Boolean, notify: true }
hideNav: { type: Boolean, notify: true },
theme: { type: String, reflect: true }
}
}
static get styles() {
return [
css`
* {
--mdc-theme-primary: rgb(3, 169, 244);
--mdc-theme-secondary: var(--mdc-theme-primary);
--mdc-button-outline-color: #03a9f4;
}
mwc-button {
margin: 6px;
width: 90%;
max-width:90vw;
margin: 4px;
}
.welcome-page {
padding: 12px 0;
}
@ -37,6 +46,7 @@ class WelcomePage extends LitElement {
this.nextText = ''
const welcomeMessage = 'Welcome to Qortal';
this.welcomeMessage = welcomeMessage
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
firstUpdate() {
@ -56,8 +66,8 @@ class WelcomePage extends LitElement {
</style>
<div class='welcome-page' style="overflow:hidden;">
<div id="mobile-logo"></div>
<mwc-button @click=${() => this.navigate('login')} outlined style="border-top:0; border-bottom:0;">Login</mwc-button>
<mwc-button @click=${() => this.navigate('create-account')} outlined style="border-top:0; border-bottom:0;">Create account</mwc-button>
<mwc-button @click=${() => this.navigate('login')} outlined style="border-top:0; border-bottom:0;">${translate("login.login")}</mwc-button>
<mwc-button @click=${() => this.navigate('create-account')} outlined style="border-top:0; border-bottom:0;">${translate("login.createaccount")}</mwc-button>
</div>
`
}

View File

@ -1,15 +1,16 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../../store.js'
import { doLogout } from '../../redux/app/app-actions.js'
import { translate, translateUnsafeHTML } from 'lit-translate'
import '@polymer/paper-dialog/paper-dialog.js'
import '@material/mwc-button'
import { doLogout } from '../../redux/app/app-actions.js'
class LogoutView extends connect(store)(LitElement) {
static get properties() {
return {
theme: { type: String, reflect: true }
}
}
@ -34,6 +35,7 @@ class LogoutView extends connect(store)(LitElement) {
constructor() {
super()
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
@ -44,11 +46,11 @@ class LogoutView extends connect(store)(LitElement) {
<hr>
</div>
<div style="text-align: center;">
<h2 style="color: var(--black);">Are you sure you want to logout?</h2>
<h2 style="color: var(--black);">${translate("logout.confirmlogout")}</h2>
</div>
<div class="buttons">
<mwc-button class='decline' @click=${e => this.decline(e)} dialog-dismiss>NO</mwc-button>
<mwc-button class='confirm' @click=${e => this.confirm(e)} dialog-confirm autofocus>YES</mwc-button>
<mwc-button class='decline' @click=${e => this.decline(e)} dialog-dismiss>${translate("general.no")}</mwc-button>
<mwc-button class='confirm' @click=${e => this.confirm(e)} dialog-confirm autofocus>${translate("general.yes")}</mwc-button>
</div>
</paper-dialog>
`

View File

@ -1,11 +1,13 @@
import { LitElement, html, css } from 'lit';
import { connect } from 'pwa-helpers';
import { store } from '../../store.js';
import { translate, translateUnsafeHTML } from 'lit-translate'
class AccountView extends connect(store)(LitElement) {
static get properties() {
return {
accountInfo: { type: Object }
accountInfo: { type: Object },
theme: { type: String, reflect: true }
}
}
@ -62,7 +64,8 @@ class AccountView extends connect(store)(LitElement) {
constructor() {
super()
this.accountInfo = { names: [], addressInfo: {} };
this.accountInfo = { names: [], addressInfo: {} }
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
@ -74,10 +77,10 @@ class AccountView extends connect(store)(LitElement) {
${this.accountInfo.names.length !== 0 ? this.accountInfo.names[0].name : 'No Registered Name'}
</span>
<div class="content-box">
<span class="title">Address: </span>
<span class="title">${translate("settings.address")}: </span>
<span class="value">${store.getState().app.selectedAddress.address}</span>
<br/>
<span class="title">Public Key: </span>
<span class="title">${translate("settings.publickey")}: </span>
<span class="value">${store.getState().app.selectedAddress.base58PublicKey}</span>
</div>
</div>

View File

@ -1,8 +1,8 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../../store.js'
import { doSetQChatNotificationConfig } from '../../redux/user/user-actions.js'
import { translate, translateUnsafeHTML } from 'lit-translate'
import '@material/mwc-checkbox'
@ -12,7 +12,8 @@ class NotificationsView extends connect(store)(LitElement) {
return {
notificationConfig: { type: Object },
q_chatConfig: { type: Object },
blockConfig: { type: Object }
blockConfig: { type: Object },
theme: { type: String, reflect: true }
}
}
@ -21,6 +22,7 @@ class NotificationsView extends connect(store)(LitElement) {
this.notificationConfig = {}
this.q_chatConfig = {}
this.blockConfig = {}
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
static get styles() {
@ -29,6 +31,7 @@ class NotificationsView extends connect(store)(LitElement) {
position: relative;
text-align: center;
}
.notification-box {
display: block;
position: relative;
@ -37,6 +40,7 @@ class NotificationsView extends connect(store)(LitElement) {
transform: translate(-50%, 0%);
text-align: center;
}
@media(min-width: 1150px) {
.notification-box {
display: grid;
@ -44,6 +48,7 @@ class NotificationsView extends connect(store)(LitElement) {
grid-gap: 30px;
}
}
.content-box {
border: 1px solid #a1a1a1;
padding: 10px 25px;
@ -53,15 +58,19 @@ class NotificationsView extends connect(store)(LitElement) {
min-height: 150px;
margin: 20px 0;
}
h4 {
margin-bottom: 0;
}
mwc-checkbox::shadow .mdc-checkbox::after, mwc-checkbox::shadow .mdc-checkbox::before {
background-color:var(--mdc-theme-primary)
}
label:hover {
cursor: pointer;
}
.title {
font-weight: 600;
font-size: 15px;
@ -82,14 +91,14 @@ class NotificationsView extends connect(store)(LitElement) {
<div class="sub-main">
<div class="notification-box">
<div class="content-box">
<h4> Q-Chat Notifications </h4>
<h4> Q-Chat ${translate("settings.notifications")} </h4>
<div style="line-height: 3rem;">
<mwc-checkbox id="qChatPlaySound" @click=${e => this.setQChatNotificationConfig({ type: 'PLAY_SOUND', value: e.target.checked })} ?checked=${this.q_chatConfig.playSound}></mwc-checkbox>
<label
for="qChatPlaySound"
@click=${() => this.shadowRoot.getElementById('qChatPlaySound').click()}
>Play Sound</label>
>${translate("settings.playsound")}</label>
</div>
<div style="line-height: 3rem;">
@ -97,20 +106,20 @@ class NotificationsView extends connect(store)(LitElement) {
<label
for="qChatShowNotification"
@click=${() => this.shadowRoot.getElementById('qChatShowNotification').click()}
>Show Notifications</label>
>${translate("settings.shownotifications")}</label>
</div>
</div>
<div class="content-box">
<h4> Block Notifications ("Coming Soon...") </h4>
<h4> ${translate("settings.block")} </h4>
<div style="line-height: 3rem;">
<mwc-checkbox indeterminate disabled id="blockPlaySound"></mwc-checkbox>
<label for="blockPlaySound">Play Sound</label>
<label for="blockPlaySound">${translate("settings.playsound")}</label>
</div>
<div style="line-height: 3rem;">
<mwc-checkbox indeterminate disabled id="blockShowNotification"></mwc-checkbox>
<label for="blockShowNotification">Show Notifications</label>
<label for="blockShowNotification">${translate("settings.shownotifications")}</label>
</div>
</div>
</div>

View File

@ -1,6 +1,7 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../../store.js'
import { translate, translateUnsafeHTML } from 'lit-translate'
import '@material/mwc-textfield'
import '@material/mwc-icon'
@ -10,6 +11,7 @@ import FileSaver from 'file-saver'
class SecurityView extends connect(store)(LitElement) {
static get properties() {
return {
theme: { type: String, reflect: true }
}
}
@ -58,19 +60,24 @@ class SecurityView extends connect(store)(LitElement) {
`
}
constructor() {
super()
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
return html`
<div style="position: relative;" >
<div class="center-box">
<p>
Please choose a password to encrypt your backup with (this can be the same as the one you logged in with, or different)
${translate("settings.choose")}
</p>
<div style="max-width: 500px; display: flex; justify-content: center; margin: auto;">
<mwc-icon style="padding: 10px; padding-left:0; padding-top: 42px;">password</mwc-icon>
<vaadin-password-field style="width: 100%; color: var(--black);" label="Password" id="downloadBackupPassword" autofocus></vaadin-password-field>
<vaadin-password-field style="width: 100%; color: var(--black);" label="${translate("settings.password")}" id="downloadBackupPassword" autofocus></vaadin-password-field>
</div>
<div style="max-width: 500px; display: flex; justify-content: center; margin: auto;">
<div @click=${() => this.downloadBackup()} class="q-button"> Download BackUp File </div>
<div @click=${() => this.downloadBackup()} class="q-button"> ${translate("settings.download")} </div>
</div>
</div>
</div>

View File

@ -1,6 +1,7 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../../store.js'
import { translate, translateUnsafeHTML } from 'lit-translate'
import '@polymer/paper-dialog/paper-dialog.js'
import '@material/mwc-button'
@ -16,7 +17,8 @@ class UserSettings extends connect(store)(LitElement) {
return {
loggedIn: { type: Boolean },
pages: { type: Array },
selectedView: { type: Object }
selectedView: { type: Object },
theme: { type: String, reflect: true }
}
}
@ -206,6 +208,7 @@ class UserSettings extends connect(store)(LitElement) {
constructor() {
super()
this.selectedView = { id: 'info', name: 'General Account Info' }
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
@ -218,15 +221,15 @@ class UserSettings extends connect(store)(LitElement) {
<div class="container">
<div class="wrapper">
<div class="leftBar" style="display: table; width: 100%;">
<div class="slug">Qortal UI Settings</div>
<div class="slug">Qortal UI ${translate("settings.settings")}</div>
<ul>
<li @click=${ () => this.setSettingsView('info')} ><a class=${this.selectedView.id === 'info' ? 'active' : ''} href="javascript:void(0)">Account</a></li>
<li @click=${ () => this.setSettingsView('security')} ><a class=${this.selectedView.id === 'security' ? 'active' : ''} href="javascript:void(0)">Security</a></li>
<li @click=${ () => this.setSettingsView('notification')} ><a class=${this.selectedView.id === 'notification' ? 'active' : ''} href="javascript:void(0)">Notifications</a></li>
<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('notification')} ><a class=${this.selectedView.id === 'notification' ? 'active' : ''} href="javascript:void(0)">${translate("settings.notifications")}</a></li>
</ul>
</div>
<div class="mainPage">
<h1>${ this.selectedView.name}</h1>
<h1>${this.renderHeaderViews()}</h1>
<hr>
${html`${this.renderSettingViews(this.selectedView)}`}
</div>
@ -250,6 +253,16 @@ class UserSettings extends connect(store)(LitElement) {
}
}
renderHeaderViews() {
if (this.selectedView.id === 'info') {
return html`${translate("settings.generalinfo")}`;
} else if (this.selectedView.id === 'security') {
return html`${translate("settings.accountsecurity")}`;
} else if (this.selectedView.id === 'notification') {
return html`UI ${translate("settings.notifications")}`;
}
}
setSettingsView(pageId) {
if (pageId === 'info') {
return this.selectedView = { id: 'info', name: 'General Account Info' }

View File

@ -1,6 +1,7 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../store.js'
import { translate, translateUnsafeHTML } from 'lit-translate'
import '@material/mwc-icon'
import '@polymer/paper-ripple'
@ -14,8 +15,10 @@ class SidenavMenu extends connect(store)(LitElement) {
static get properties() {
return {
config: { type: Object },
urls: { type: Object }
urls: { type: Object },
theme: { type: String, reflect: true }
}
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
static get styles() {
@ -54,34 +57,34 @@ class SidenavMenu extends connect(store)(LitElement) {
return html`
<div class="s-menu">
<side-menu>
<side-menu-item label="MINTING DETAILS" href="/app/minting">
<side-menu-item label="${translate("sidemenu.mintingdetails")}" href="/app/minting">
<vaadin-icon icon="vaadin:info-circle" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="WALLETS" href="/app/wallet" selected>
<side-menu-item label="${translate("sidemenu.wallets")}" href="/app/wallet" selected>
<vaadin-icon icon="vaadin:wallet" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="TRADE PORTAL" href="/app/trade-portal">
<side-menu-item label="${translate("sidemenu.tradeportal")}" href="/app/trade-portal">
<vaadin-icon icon="vaadin:bullets" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="REWARD SHARE" href="/app/reward-share">
<side-menu-item label="${translate("sidemenu.rewardshare")}" href="/app/reward-share">
<vaadin-icon icon="vaadin:share-square" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="NAME REGISTRATION" href="/app/name-registration">
<side-menu-item label="${translate("sidemenu.nameregistration")}" href="/app/name-registration">
<vaadin-icon icon="vaadin:user-check" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="WEBSITES" href="/app/websites">
<side-menu-item label="${translate("sidemenu.websites")}" href="/app/websites">
<vaadin-icon icon="vaadin:desktop" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="DATA MANAGEMENT" href="/app/data-management">
<side-menu-item label="${translate("sidemenu.datamanagement")}" href="/app/data-management">
<vaadin-icon icon="vaadin:database" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="Q-CHAT" href="/app/q-chat">
<side-menu-item label="${translate("sidemenu.qchat")}" href="/app/q-chat">
<vaadin-icon icon="vaadin:chat" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="GROUP MANAGEMENT" href="/app/group-management">
<side-menu-item label="${translate("sidemenu.groupmanagement")}" href="/app/group-management">
<vaadin-icon icon="vaadin:group" slot="icon"></vaadin-icon>
</side-menu-item>
<side-menu-item label="PUZZLES" href="/app/puzzles">
<side-menu-item label="${translate("sidemenu.puzzles")}" href="/app/puzzles">
<vaadin-icon icon="vaadin:puzzle-piece" slot="icon"></vaadin-icon>
</side-menu-item>
${this.renderNodeManagement()}
@ -98,13 +101,12 @@ class SidenavMenu extends connect(store)(LitElement) {
const checkNodeManagement = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
if (checkNodeManagement.enableManagement = true) {
return html`
<side-menu-item label="NODE MANAGEMENT" href="/app/node-management">
<side-menu-item label="${translate("sidemenu.nodemanagement")}" href="/app/node-management">
<vaadin-icon icon="vaadin:cloud" slot="icon"></vaadin-icon>
</side-menu-item>
`
} else {
return html`
`
return html``
}
}

View File

@ -1,6 +1,7 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../store.js'
import { translate, translateUnsafeHTML } from 'lit-translate'
import '@polymer/paper-toast'
import '@material/mwc-icon-button'
@ -10,7 +11,8 @@ class WalletProfile extends connect(store)(LitElement) {
return {
wallet: { type: Object },
nodeConfig: { type: Object },
accountInfo: { type: Object }
accountInfo: { type: Object },
theme: { type: String, reflect: true }
}
}
@ -28,6 +30,7 @@ class WalletProfile extends connect(store)(LitElement) {
names: [],
addressInfo: {}
}
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
@ -81,8 +84,8 @@ class WalletProfile extends connect(store)(LitElement) {
<span id="accountName">
${this.accountInfo.names.length !== 0 ? this.accountInfo.names[0].name : ''}
</span>
${this.accountInfo.addressInfo ? html`<span style="margin-bottom: 8px; display: inline-block; font-size: 14px;">Minter Level - <span style="color: #03a9f4;">${this.accountInfo.addressInfo.level} ${this.accountInfo.addressInfo.flags === 1 ? html`<strong>(F)</strong>` : ''}</span>` : ''}
<p id="blocksMinted">Blocks Minted - ${this.accountInfo.addressInfo.blocksMinted + this.accountInfo.addressInfo.blocksMintedAdjustment}</p>
${this.accountInfo.addressInfo ? html`<span style="margin-bottom: 8px; display: inline-block; font-size: 14px;">${translate("walletprofile.minterlevel")} - <span style="color: #03a9f4;">${this.accountInfo.addressInfo.level} ${this.accountInfo.addressInfo.flags === 1 ? html`<strong>(F)</strong>` : ''}</span>` : ''}
<p id="blocksMinted">${translate("walletprofile.blocksminted")} - ${this.accountInfo.addressInfo.blocksMinted + this.accountInfo.addressInfo.blocksMintedAdjustment}</p>
<p id="address">${this.wallet.addresses[0].address}</p>
</div>
</div>

View File

@ -3,15 +3,13 @@ import { LitElement, html, css } from 'lit'
import '@material/mwc-button'
import '@material/mwc-icon'
import { translate, translateUnsafeHTML } from 'lit-translate'
class FragFileInput extends LitElement {
static get properties () {
return {
accept: {
type: String
},
readAs: {
type: String
}
accept: { type: String },
readAs: { type: String }
}
}
@ -22,18 +20,23 @@ class FragFileInput extends LitElement {
font-family: "Roboto", sans-serif;
padding: 20px;
}
#trigger:hover {
cursor: pointer;
}
#drop-area.highlight {
border-color: var(--mdc-theme-primary, #000);
}
p {
margin-top: 0;
}
form {
margin-bottom: 10px;
}
#fileInput {
display: none;
}
@ -47,30 +50,21 @@ class FragFileInput extends LitElement {
render () {
return html`
<style>
</style>
<div id="drop-area">
<slot name="info-text"></slot>
<div style="line-height:40px;">
<div style="line-height: 40px; text-align: center;">
<slot id="trigger" name="inputTrigger" @click=${() => this.shadowRoot.getElementById('fileInput').click()} style="dispay:inline;">
<mwc-button><mwc-icon>cloud_upload</mwc-icon>&nbsp; Select file</mwc-button>
</slot>
<span style="padding-top:6px;">Drag and drop backup here</span>
<mwc-button><mwc-icon>cloud_upload</mwc-icon><span style="color: var(--black);">&nbsp; ${translate("fragfile.selectfile")}</span></mwc-button>
</slot><br>
<span style="text-align: center; padding-top: 4px; color: var(--black);">${translate("fragfile.dragfile")}</span>
</div>
</div>
<input type="file" id="fileInput" accept="${this.accept}" @change="${e => this.readFile(e.target.files[0])}">
`
}
readFile (file) {
const fr = new FileReader()
fr.onload = () => {
this.dispatchEvent(new CustomEvent('file-read-success', {
detail: { result: fr.result },
@ -78,7 +72,6 @@ class FragFileInput extends LitElement {
composed: true
}))
}
fr['readAs' + this.readAs](file)
}

View File

@ -10,7 +10,8 @@ import '@material/mwc-button'
class ConfirmTransactionDialog extends connect(store)(LitElement) {
static get properties() {
return {
txInfo: { type: Object }
txInfo: { type: Object },
theme: { type: String, reflect: true }
}
}
@ -53,6 +54,7 @@ class ConfirmTransactionDialog extends connect(store)(LitElement) {
}
this.txInfo = html``
listenForRequest(args => this.requestTransaction(args))
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light';
}
render() {

View File

@ -16,7 +16,8 @@ let mykeyDialog
class MykeyPage extends connect(store)(LitElement) {
static get properties() {
return {
nodeConfig: { type: Object }
nodeConfig: { type: Object },
theme: { type: String, reflect: true }
}
}
@ -31,6 +32,7 @@ class MykeyPage extends connect(store)(LitElement) {
constructor() {
super()
this.nodeConfig = {}
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light';
}
render() {

View File

@ -1,31 +1,50 @@
import { LitElement, html, css } from 'lit'
import { connect } from 'pwa-helpers'
import { store } from '../store.js'
import { doAddNode, doSetNode } from '../redux/app/app-actions.js'
import snackbar from './snackbar.js'
import { translate, translateUnsafeHTML } from 'lit-translate'
import '../components/language-selector.js'
import '@material/mwc-dialog'
import '@material/mwc-button'
import '@material/mwc-select'
import '@material/mwc-textfield'
import '@material/mwc-icon'
import '@material/mwc-list/mwc-list-item.js'
import snackbar from './snackbar.js'
let settingsDialog
class SettingsPage extends connect(store)(LitElement) {
static get properties() {
return {
lastSelected: { type: Number },
nodeConfig: { type: Object }
nodeConfig: { type: Object },
theme: { type: String, reflect: true }
}
}
static get styles() {
return css`
* {
--mdc-theme-primary: rgb(3, 169, 244);
--mdc-theme-secondary: var(--mdc-theme-primary);
--mdc-dialog-content-ink-color: var(--black);
--mdc-theme-surface: var(--white);
--mdc-theme-text-primary-on-background: var(--black);
}
#main {
width: 210px;
display: flex;
align-items: center;
}
.globe {
color: var(--black);
--mdc-icon-size: 36px;
}
.red {
--mdc-theme-primary: red;
}
@ -35,57 +54,79 @@ class SettingsPage extends connect(store)(LitElement) {
constructor() {
super()
this.nodeConfig = {}
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light';
}
render() {
return html`
<mwc-dialog id="settingsDialog" heading="Settings" opened=false>
<div style="min-height:450px; min-width: 300px; box-sizing: border-box; position: relative;">
<mwc-select icon="link" id="nodeSelect" label="Node Url" index="0" @selected="${(e) => this.nodeSelected(e)}" style="min-width: 130px; max-width:100%; width:100%;">
<mwc-dialog id="settingsDialog" opened=false>
<div style="display: inline; text-align: center;">
<h1>${translate("settings.settings")}</h1>
<hr>
</div>
<br>
<div style="min-height: 250px; min-width: 300px; box-sizing: border-box; position: relative;">
<mwc-select icon="link" id="nodeSelect" label="${translate("settings.nodeurl")}" index="0" @selected="${(e) => this.nodeSelected(e)}" style="min-width: 130px; max-width:100%; width:100%;">
${this.nodeConfig.knownNodes.map((n, index) => html`
<mwc-list-item value="${index}">${n.protocol + '://' + n.domain + ':' + n.port}</mwc-list-item>
`)}
</mwc-select>
<p style="margin-top: 45px;">Select a node from the default list of nodes above or add a custom node to the list above by clicking on the button below</p>
<mwc-button outlined style="display: block; position: absolute; left: 30%;" @click="${() => this.shadowRoot.querySelector('#addNodeDialog').show()}"><mwc-icon>add</mwc-icon>Add Custom Node</mwc-button>
<p style="margin-top: 30px;">${translate("settings.nodehint")}</p>
<center>
<mwc-button outlined @click="${() => this.shadowRoot.querySelector('#addNodeDialog').show()}"><mwc-icon>add</mwc-icon>${translate("settings.addcustomnode")}</mwc-button>
</center>
</div>
<div style="min-height:100px; min-width: 300px; box-sizing: border-box; position: relative;">
<hr><br>
<center>
<div id="main">
<mwc-icon class="globe">language</mwc-icon>&nbsp;<language-selector></language-selector>
</div>
</center>
</div>
<mwc-button
slot="primaryAction"
dialogAction="close"
class="red"
>
Close
${translate("general.close")}
</mwc-button>
</mwc-dialog>
<mwc-dialog id="addNodeDialog" heading="Add Custom Node">
<mwc-select id="protocolList" label="Protocol" style="width:100%;">
<mwc-dialog id="addNodeDialog">
<div style="text-align: center;">
<h2>${translate("settings.addcustomnode")}</h2>
<hr>
</div>
<br>
<mwc-select id="protocolList" label="${translate("settings.protocol")}" style="width:100%;">
<mwc-list-item value="http">http</mwc-list-item>
<mwc-list-item value="https">https</mwc-list-item>
</mwc-select>
<br>
<mwc-textfield id="domainInput" style="width:100%;" label="Domain"></mwc-textfield>
<mwc-textfield id="portInput" style="width:100%;" label="Port"></mwc-textfield>
<mwc-textfield id="domainInput" style="width:100%;" label="${translate("settings.domain")}"></mwc-textfield>
<mwc-textfield id="portInput" style="width:100%;" label="${translate("settings.port")}"></mwc-textfield>
<mwc-button
slot="secondaryAction"
dialogAction="close"
class="red"
>
Close
${translate("general.close")}
</mwc-button>
<mwc-button
slot="primaryAction"
@click="${this.addNode}"
>
Add And Save
${translate("settings.addandsave")}
</mwc-button>
</mwc-dialog>
`
}
firstUpdated() {
// ...
}
stateChanged(state) {
this.config = state.config
this.nodeConfig = state.app.nodeConfig

View File

@ -3,12 +3,12 @@ import { css } from 'lit'
export const sideMenuItemStyle = css`
:host {
--font-family: "Roboto", sans-serif;
--item-font-size: 1rem;
--sub-item-font-size: 0.85rem;
--item-padding: 1rem;
--item-content-padding: 1rem;
--icon-height: 1.25rem;
--icon-width: 1.25rem;
--item-font-size: 0.9375rem;
--sub-item-font-size: 0.75rem;
--item-padding: 0.875rem;
--item-content-padding: 0.875rem;
--icon-height: 1.125rem;
--icon-width: 1.125rem;
--item-border-radius: 5px;
--item-selected-color: #dddddd;
--item-selected-color-text: #333333;

View File

@ -1 +1 @@
export const UI_VERSION = "1.7.4";
export const UI_VERSION = "1.8.2";