forked from Qortal/qortal-ui
Merge branch 'master' into master
This commit is contained in:
commit
6778decd5a
@ -26,8 +26,8 @@ Easiest way to install the lastest required packages on Linux is via nvm.
|
|||||||
``` source ~/.profile ``` (For Debian based distro) <br/>
|
``` source ~/.profile ``` (For Debian based distro) <br/>
|
||||||
``` source ~/.bashrc ``` (For Fedora / CentOS) <br/>
|
``` source ~/.bashrc ``` (For Fedora / CentOS) <br/>
|
||||||
``` nvm ls-remote ``` (Fetch list of available versions) <br/>
|
``` nvm ls-remote ``` (Fetch list of available versions) <br/>
|
||||||
``` nvm install v18.17.1 ``` (LTS: Hydrogen supported by Electron V27) <br/>
|
``` nvm install v20.11.1 ``` (LTS: Iron supported by Electron V30) <br/>
|
||||||
``` npm --location=global install npm@10.5.0 ``` <br/>
|
``` npm --location=global install npm@10.7.0 ``` <br/>
|
||||||
|
|
||||||
Adding via binary package mirror will only work if you have set the package path. You can do a node or java build via ports instead by downloading ports with portsnap fetch method.
|
Adding via binary package mirror will only work if you have set the package path. You can do a node or java build via ports instead by downloading ports with portsnap fetch method.
|
||||||
|
|
||||||
|
29
build.js
29
build.js
@ -1,28 +1,23 @@
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
const uiCore = require('./core/ui-core.js')
|
const uiCore = require('./core/ui-core.js')
|
||||||
|
const config = require('./config/config.js')
|
||||||
|
const pluginsController = require('./plugins/default-plugins.js')
|
||||||
const generateBuildConfig = uiCore('generate_build_config')
|
const generateBuildConfig = uiCore('generate_build_config')
|
||||||
const build = uiCore('build')
|
const build = uiCore('build')
|
||||||
|
|
||||||
const config = require('./config/config.js')
|
|
||||||
|
|
||||||
const pluginsController = require('./plugins/default-plugins.js')
|
|
||||||
const buildDefalutPlugins = pluginsController('build')
|
const buildDefalutPlugins = pluginsController('build')
|
||||||
|
|
||||||
|
|
||||||
srcConfig = {
|
srcConfig = {
|
||||||
...config.build,
|
...config.build,
|
||||||
options: {
|
options: {
|
||||||
...config.build.options,
|
...config.build.options,
|
||||||
outputDir: path.join(__dirname, '/builtWWW'),
|
outputDir: path.join(__dirname, '/builtWWW'),
|
||||||
sassOutputDir: path.join(__dirname, '/builtWWW/styles.bundle.css'),
|
sassOutputDir: path.join(__dirname, '/builtWWW/styles.bundle.css')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const { buildConfig, inlineConfigs } = generateBuildConfig(srcConfig)
|
const { buildConfig, inlineConfigs } = generateBuildConfig(srcConfig)
|
||||||
|
|
||||||
build(buildConfig.options, buildConfig.outputs, buildConfig.outputOptions, buildConfig.inputOptions, inlineConfigs)
|
build(buildConfig.options, buildConfig.outputs, buildConfig.outputOptions, buildConfig.inputOptions, inlineConfigs).then(() => {
|
||||||
.then(() => {
|
console.log("Building and Bundling Plugins")
|
||||||
console.log("Building and Bundling Plugins");
|
buildDefalutPlugins()
|
||||||
buildDefalutPlugins()
|
})
|
||||||
})
|
|
@ -2,13 +2,13 @@ const path = require('path')
|
|||||||
const defaultConfig = require('./default.config.js')
|
const defaultConfig = require('./default.config.js')
|
||||||
|
|
||||||
const build = {
|
const build = {
|
||||||
options: {
|
options: {
|
||||||
outputDir: path.join(__dirname, '../build'),
|
outputDir: path.join(__dirname, '../build'),
|
||||||
imgDir: path.join(__dirname, '../img')
|
imgDir: path.join(__dirname, '../img')
|
||||||
},
|
},
|
||||||
aliases: {
|
aliases: {
|
||||||
'qortal-ui-crypto': path.join(__dirname, '../crypto/api.js')
|
'qortal-ui-crypto': path.join(__dirname, '../crypto/api.js')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = build
|
module.exports = build
|
@ -1,8 +1,8 @@
|
|||||||
const defaultConfig = require('./default.config.js')
|
const defaultConfig = require('./default.config.js')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
name: 'Qortal',
|
name: 'Qortal',
|
||||||
symbol: 'Qort',
|
symbol: 'Qort',
|
||||||
addressVersion: 58, // Q for Qortal
|
addressVersion: 58, // Q for Qortal
|
||||||
logo: '/img/QORT_LOGO.svg'
|
logo: '/img/QORT_LOGO.svg'
|
||||||
}
|
}
|
@ -1,27 +1,33 @@
|
|||||||
let config = require('./default.config.js')
|
let config = require('./default.config.js')
|
||||||
let userConfig = {}
|
|
||||||
try {
|
|
||||||
userConfig = require('./customConfig.js')
|
|
||||||
} catch (e) {
|
|
||||||
console.warn(e)
|
|
||||||
console.warn('Error loading user config')
|
|
||||||
}
|
|
||||||
const checkKeys = (storeObj, newObj) => {
|
|
||||||
for (const key in newObj) {
|
|
||||||
if (!Object.prototype.hasOwnProperty.call(storeObj, key)) return
|
|
||||||
|
|
||||||
if (typeof newObj[key] === 'object') {
|
let userConfig = {}
|
||||||
storeObj[key] = checkKeys(storeObj[key], newObj[key])
|
|
||||||
} else {
|
try {
|
||||||
storeObj[key] = newObj[key]
|
userConfig = require('./customConfig.js')
|
||||||
}
|
} catch (e) {
|
||||||
}
|
console.warn(e)
|
||||||
return storeObj
|
console.warn('Error loading user config')
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkKeys = (storeObj, newObj) => {
|
||||||
|
for (const key in newObj) {
|
||||||
|
if (!Object.prototype.hasOwnProperty.call(storeObj, key)) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if (typeof newObj[key] === 'object') {
|
||||||
|
storeObj[key] = checkKeys(storeObj[key], newObj[key])
|
||||||
|
} else {
|
||||||
|
storeObj[key] = newObj[key]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return storeObj
|
||||||
}
|
}
|
||||||
|
|
||||||
const getConfig = customConfig => {
|
const getConfig = customConfig => {
|
||||||
config = checkKeys(config, customConfig)
|
config = checkKeys(config, customConfig)
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = getConfig(userConfig)
|
module.exports = getConfig(userConfig)
|
@ -1,3 +1,3 @@
|
|||||||
const defaultConfig = require('./default.config.js')
|
const defaultConfig = require('./default.config.js')
|
||||||
|
|
||||||
module.exports = {}
|
module.exports = {}
|
@ -4,10 +4,4 @@ const styles = require('./styles.config.js')
|
|||||||
const build = require('./build.config.js')
|
const build = require('./build.config.js')
|
||||||
const user = require('./user.config.js')
|
const user = require('./user.config.js')
|
||||||
|
|
||||||
module.exports = {
|
module.exports = { coin, styles, build, user, crypto }
|
||||||
coin,
|
|
||||||
styles,
|
|
||||||
build,
|
|
||||||
user,
|
|
||||||
crypto
|
|
||||||
}
|
|
@ -1,5 +1,4 @@
|
|||||||
const uiCore = require('../core/ui-core.js')
|
const uiCore = require('../core/ui-core.js')
|
||||||
const defaultConfig = uiCore('default_config')
|
const defaultConfig = uiCore('default_config')
|
||||||
|
|
||||||
|
module.exports = defaultConfig
|
||||||
module.exports = defaultConfig
|
|
@ -1 +1 @@
|
|||||||
module.exports = {}
|
module.exports = {}
|
@ -1,10 +1,11 @@
|
|||||||
const user = require('./default.config.js').user
|
const user = require('./default.config.js').user
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
node: 0, // set to mainnet
|
node: 0, // set to mainnet
|
||||||
server: {
|
server: {
|
||||||
primary: {
|
primary: {
|
||||||
port: 12388, // set as default UI port
|
port: 12388, // set as default UI port
|
||||||
address: '0.0.0.0', // can specify an IP for a fixed bind
|
address: '0.0.0.0' // can specify an IP for a fixed bind
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
@ -4,4 +4,4 @@ const user = require('./default.user.config.js')
|
|||||||
const styles = require('./default.styles.config.js')
|
const styles = require('./default.styles.config.js')
|
||||||
const build = require('./default.build.options.js')
|
const build = require('./default.build.options.js')
|
||||||
|
|
||||||
module.exports = { coin, crypto, user, styles, build }
|
module.exports = { coin, crypto, user, styles, build }
|
@ -4,132 +4,132 @@ const { makeSourceAbsolute } = require('../tooling/utils.js')
|
|||||||
const srcDir = '../src'
|
const srcDir = '../src'
|
||||||
|
|
||||||
const options = {
|
const options = {
|
||||||
inputFile: path.join(__dirname, '../src/main.js'),
|
inputFile: path.join(__dirname, '../src/main.js'),
|
||||||
outputDir: path.join(__dirname, '../build'),
|
outputDir: path.join(__dirname, '../build'),
|
||||||
sassOutputDir: path.join(__dirname, '../build/styles.bundle.css'),
|
sassOutputDir: path.join(__dirname, '../build/styles.bundle.css'),
|
||||||
imgDir: path.join(__dirname, '../img')
|
imgDir: path.join(__dirname, '../img')
|
||||||
}
|
}
|
||||||
|
|
||||||
const aliases = {
|
const aliases = {
|
||||||
'qortal-ui-crypto': '../../crypto/api.js'
|
'qortal-ui-crypto': '../../crypto/api.js'
|
||||||
}
|
}
|
||||||
|
|
||||||
const apiComponents = {
|
const apiComponents = {
|
||||||
api: {
|
api: {
|
||||||
file: '../../crypto/api.js',
|
file: '../../crypto/api.js',
|
||||||
className: 'api'
|
className: 'api'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const functionalComponents = {
|
const functionalComponents = {
|
||||||
'loading-ripple': {
|
'loading-ripple': {
|
||||||
file: 'functional-components/loading-ripple.js',
|
file: 'functional-components/loading-ripple.js',
|
||||||
className: 'LoadingRipple'
|
className: 'LoadingRipple'
|
||||||
},
|
},
|
||||||
'confirm-transaction-dialog': {
|
'confirm-transaction-dialog': {
|
||||||
file: 'functional-components/confirm-transaction-dialog',
|
file: 'functional-components/confirm-transaction-dialog',
|
||||||
className: 'ConfirmTransactionDialog'
|
className: 'ConfirmTransactionDialog'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const inlineComponents = [
|
const inlineComponents = [
|
||||||
{
|
{
|
||||||
className: 'worker',
|
className: 'worker',
|
||||||
input: path.join(__dirname, srcDir, 'worker.js'),
|
input: path.join(__dirname, srcDir, 'worker.js'),
|
||||||
output: 'worker.js'
|
output: 'worker.js'
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
className: 'PluginMainJSLoader',
|
className: 'PluginMainJSLoader',
|
||||||
input: path.join(__dirname, srcDir, '/plugins/plugin-mainjs-loader.js'),
|
input: path.join(__dirname, srcDir, '/plugins/plugin-mainjs-loader.js'),
|
||||||
output: 'plugins/plugin-mainjs-loader.js'
|
output: 'plugins/plugin-mainjs-loader.js'
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
||||||
const elementComponents = {
|
const elementComponents = {
|
||||||
'main-app': {
|
'main-app': {
|
||||||
file: 'components/main-app.js',
|
file: 'components/main-app.js',
|
||||||
className: 'MainApp',
|
className: 'MainApp',
|
||||||
children: {
|
children: {
|
||||||
'app-styles': {
|
'app-styles': {
|
||||||
file: 'styles/app-styles.js',
|
file: 'styles/app-styles.js',
|
||||||
className: 'AppStyles',
|
className: 'AppStyles',
|
||||||
children: {
|
children: {
|
||||||
'app-theme': {
|
'app-theme': {
|
||||||
className: 'AppTheme',
|
className: 'AppTheme',
|
||||||
file: 'styles/app-theme.js'
|
file: 'styles/app-theme.js'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'app-view': {
|
'app-view': {
|
||||||
file: 'components/app-view.js',
|
file: 'components/app-view.js',
|
||||||
className: 'AppView',
|
className: 'AppView',
|
||||||
children: {
|
children: {
|
||||||
'show-plugin': {
|
'show-plugin': {
|
||||||
file: 'components/show-plugin.js',
|
file: 'components/show-plugin.js',
|
||||||
className: 'ShowPlugin'
|
className: 'ShowPlugin'
|
||||||
},
|
},
|
||||||
'wallet-profile': {
|
'wallet-profile': {
|
||||||
file: 'components/wallet-profile.js',
|
file: 'components/wallet-profile.js',
|
||||||
className: 'WalletProfile'
|
className: 'WalletProfile'
|
||||||
},
|
},
|
||||||
'app-info': {
|
'app-info': {
|
||||||
file: 'components/app-info.js',
|
file: 'components/app-info.js',
|
||||||
className: 'AppInfo'
|
className: 'AppInfo'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'login-view': {
|
'login-view': {
|
||||||
file: 'components/login-view/login-view.js',
|
file: 'components/login-view/login-view.js',
|
||||||
className: 'LoginView',
|
className: 'LoginView',
|
||||||
children: {
|
children: {
|
||||||
'create-account-section': {
|
'create-account-section': {
|
||||||
file: 'components/login-view/create-account-section.js',
|
file: 'components/login-view/create-account-section.js',
|
||||||
className: 'CreateAccountSection'
|
className: 'CreateAccountSection'
|
||||||
},
|
},
|
||||||
'login-section': {
|
'login-section': {
|
||||||
file: 'components/login-view/login-section.js',
|
file: 'components/login-view/login-section.js',
|
||||||
className: 'LoginSection'
|
className: 'LoginSection'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'settings-view': {
|
'settings-view': {
|
||||||
file: 'components/settings-view/user-settings.js',
|
file: 'components/settings-view/user-settings.js',
|
||||||
className: 'UserSettings',
|
className: 'UserSettings',
|
||||||
children: {
|
children: {
|
||||||
'account-view': {
|
'account-view': {
|
||||||
file: 'components/settings-view/account-view.js',
|
file: 'components/settings-view/account-view.js',
|
||||||
className: 'AccountView'
|
className: 'AccountView'
|
||||||
},
|
},
|
||||||
'security-view': {
|
'security-view': {
|
||||||
file: 'components/settings-view/security-view.js',
|
file: 'components/settings-view/security-view.js',
|
||||||
className: 'SecurityView'
|
className: 'SecurityView'
|
||||||
},
|
},
|
||||||
'qr-login-view': {
|
'qr-login-view': {
|
||||||
file: 'components/settings-view/qr-login-view.js',
|
file: 'components/settings-view/qr-login-view.js',
|
||||||
className: 'QRLoginView'
|
className: 'QRLoginView'
|
||||||
},
|
},
|
||||||
'notifications-view': {
|
'notifications-view': {
|
||||||
file: 'components/settings-view/notifications-view.js',
|
file: 'components/settings-view/notifications-view.js',
|
||||||
className: 'NotificationsView'
|
className: 'NotificationsView'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
'user-info-view': {
|
'user-info-view': {
|
||||||
file: 'components/user-info-view/user-info-view.js',
|
file: 'components/user-info-view/user-info-view.js',
|
||||||
className: 'UserInfoView'
|
className: 'UserInfoView'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
makeSourceAbsolute(path.join(__dirname, srcDir), elementComponents)
|
makeSourceAbsolute(path.join(__dirname, srcDir), elementComponents)
|
||||||
makeSourceAbsolute(path.join(__dirname, srcDir), functionalComponents)
|
makeSourceAbsolute(path.join(__dirname, srcDir), functionalComponents)
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
options,
|
options,
|
||||||
elementComponents,
|
elementComponents,
|
||||||
functionalComponents,
|
functionalComponents,
|
||||||
inlineComponents,
|
inlineComponents,
|
||||||
apiComponents,
|
apiComponents,
|
||||||
aliases
|
aliases
|
||||||
}
|
}
|
@ -1,11 +1,11 @@
|
|||||||
const coin = {
|
const coin = {
|
||||||
name: 'Qortal',
|
name: 'Qortal',
|
||||||
symbol: 'QORT',
|
symbol: 'QORT',
|
||||||
addressCount: 1,
|
addressCount: 1,
|
||||||
addressVersion: 58,
|
addressVersion: 58,
|
||||||
decimals: 100000000,
|
decimals: 100000000,
|
||||||
logo: '/img/QORT_LOGO.png',
|
logo: '/img/QORT_LOGO.png',
|
||||||
icon: '/img/QORT_LOGO.png'
|
icon: '/img/QORT_LOGO.png'
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = coin
|
module.exports = coin
|
@ -1,11 +1,11 @@
|
|||||||
const crypto = {
|
const crypto = {
|
||||||
kdfThreads: 16,
|
kdfThreads: 16,
|
||||||
staticSalt: '4ghkVQExoneGqZqHTMMhhFfxXsVg2A75QeS1HCM5KAih', // Base58 encoded
|
staticSalt: '4ghkVQExoneGqZqHTMMhhFfxXsVg2A75QeS1HCM5KAih', // Base58 encoded
|
||||||
bcryptRounds: 11, // Note it's kinda bcryptRounds * log.2.16, cause it runs on all 16 threads
|
bcryptRounds: 11, // Note it's kinda bcryptRounds * log.2.16, cause it runs on all 16 threads
|
||||||
bcryptVersion: '2a',
|
bcryptVersion: '2a',
|
||||||
get staticBcryptSalt () {
|
get staticBcryptSalt() {
|
||||||
return `$${this.bcryptVersion}$${this.bcryptRounds}$IxVE941tXVUD4cW0TNVm.O`
|
return `$${this.bcryptVersion}$${this.bcryptRounds}$IxVE941tXVUD4cW0TNVm.O`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = crypto
|
module.exports = crypto
|
@ -1,40 +1,41 @@
|
|||||||
const styles = {
|
const styles = {
|
||||||
breakpoints: {
|
breakpoints: {
|
||||||
desktop: '',
|
desktop: '',
|
||||||
laptop: '',
|
laptop: '',
|
||||||
tablet: '',
|
tablet: '',
|
||||||
mobile: ''
|
mobile: ''
|
||||||
},
|
},
|
||||||
theme: {
|
theme: {
|
||||||
colors: {
|
colors: {
|
||||||
primary: '#03a9f4', /* Sets the text color to the theme primary color. */
|
primary: '#03a9f4', /* Sets the text color to the theme primary color. */
|
||||||
primaryBg: '#e8eaf6', /* Sets the background color to the theme primary color. */
|
primaryBg: '#e8eaf6', /* Sets the background color to the theme primary color. */
|
||||||
onPrimary: '#fff', /* Sets the text color to the color configured for text on the primary color. */
|
onPrimary: '#fff', /* Sets the text color to the color configured for text on the primary color. */
|
||||||
|
|
||||||
secondary: '#03a9f4', /* Sets the text color to the theme secondary color. */
|
secondary: '#03a9f4', /* Sets the text color to the theme secondary color. */
|
||||||
secondaryBg: '#fce4ec', /* Sets the background color to the theme secondary color. */
|
secondaryBg: '#fce4ec', /* Sets the background color to the theme secondary color. */
|
||||||
onSecondary: '#fff', /* Sets the text color to the color configured for text on the secondary color. */
|
onSecondary: '#fff', /* Sets the text color to the color configured for text on the secondary color. */
|
||||||
|
|
||||||
surface: '#fff', /* Sets the background color to the surface background color. */
|
surface: '#fff', /* Sets the background color to the surface background color. */
|
||||||
onSurface: '#333', /* Sets the text color to the color configured for text on the surface color. */
|
onSurface: '#333', /* Sets the text color to the color configured for text on the surface color. */
|
||||||
background: '#eee', /* Sets the background color to the theme background color. */
|
background: '#eee', /* Sets the background color to the theme background color. */
|
||||||
|
|
||||||
warning: '#FFA000',
|
warning: '#FFA000',
|
||||||
error: '#F44336'
|
error: '#F44336'
|
||||||
},
|
},
|
||||||
|
|
||||||
addressColors: [
|
addressColors: [
|
||||||
'#256480',
|
'#256480',
|
||||||
'#002530',
|
'#002530',
|
||||||
'#02564e',
|
'#02564e',
|
||||||
'#d32f2f',
|
'#d32f2f',
|
||||||
'#795548',
|
'#795548',
|
||||||
'#004d40',
|
'#004d40',
|
||||||
'#006064',
|
'#006064',
|
||||||
'#9c27b0',
|
'#9c27b0',
|
||||||
'#2196f3',
|
'#2196f3',
|
||||||
'#d81b60'
|
'#d81b60'
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
module.exports = styles
|
|
||||||
|
module.exports = styles
|
@ -1,42 +1,43 @@
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
||||||
const user = {
|
const user = {
|
||||||
node: 0,
|
node: 0,
|
||||||
nodeSettings: {
|
nodeSettings: {
|
||||||
pingInterval: 30 * 1000,
|
pingInterval: 30 * 1000
|
||||||
},
|
},
|
||||||
server: {
|
server: {
|
||||||
writeHosts: {
|
writeHosts: {
|
||||||
enabled: true,
|
enabled: true
|
||||||
},
|
},
|
||||||
relativeTo: path.join(__dirname, '../'),
|
relativeTo: path.join(__dirname, '../'),
|
||||||
primary: {
|
primary: {
|
||||||
domain: '0.0.0.0',
|
domain: '0.0.0.0',
|
||||||
address: '0.0.0.0',
|
address: '0.0.0.0',
|
||||||
port: 12388,
|
port: 12388,
|
||||||
directory: './src/',
|
directory: './src/',
|
||||||
page404: './src/404.html',
|
page404: './src/404.html',
|
||||||
host: '0.0.0.0',
|
host: '0.0.0.0'
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
tls: {
|
tls: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
options: {
|
options: {
|
||||||
key: '',
|
key: '',
|
||||||
cert: '',
|
cert: ''
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
constants: {
|
constants: {
|
||||||
pollingInterval: 30 * 1000, // How long between checking for new unconfirmed transactions and new blocks (in milliseconds).
|
pollingInterval: 30 * 1000, // How long between checking for new unconfirmed transactions and new blocks (in milliseconds).
|
||||||
workerURL: '/build/worker.js',
|
workerURL: '/build/worker.js'
|
||||||
},
|
},
|
||||||
|
|
||||||
// Notification Settings (All defaults to true)
|
// Notification Settings (All defaults to true)
|
||||||
notifications: {
|
notifications: {
|
||||||
q_chat: {
|
q_chat: {
|
||||||
playSound: true,
|
playSound: true,
|
||||||
showNotification: true,
|
showNotification: true
|
||||||
},
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
module.exports = user
|
|
||||||
|
module.exports = user
|
@ -1,21 +1,22 @@
|
|||||||
let config = require('./config.js')
|
let config = require('./config.js')
|
||||||
|
|
||||||
const checkKeys = (storeObj, newObj) => {
|
const checkKeys = (storeObj, newObj) => {
|
||||||
for (const key in newObj) {
|
for (const key in newObj) {
|
||||||
if (!Object.prototype.hasOwnProperty.call(storeObj, key)) return
|
if (!Object.prototype.hasOwnProperty.call(storeObj, key)) return
|
||||||
|
|
||||||
if (typeof newObj[key] === 'object') {
|
if (typeof newObj[key] === 'object') {
|
||||||
storeObj[key] = checkKeys(storeObj[key], newObj[key])
|
storeObj[key] = checkKeys(storeObj[key], newObj[key])
|
||||||
} else {
|
} else {
|
||||||
storeObj[key] = newObj[key]
|
storeObj[key] = newObj[key]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return storeObj
|
|
||||||
|
return storeObj
|
||||||
}
|
}
|
||||||
|
|
||||||
const getConfig = customConfig => {
|
const getConfig = customConfig => {
|
||||||
config = checkKeys(config, customConfig)
|
config = checkKeys(config, customConfig)
|
||||||
return config
|
return config
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = getConfig
|
module.exports = getConfig
|
@ -6,6 +6,7 @@ html {
|
|||||||
--plugback: #ffffff;
|
--plugback: #ffffff;
|
||||||
--border: #d0d6de;
|
--border: #d0d6de;
|
||||||
--border2: #dde2e8;
|
--border2: #dde2e8;
|
||||||
|
--border3: #080808;
|
||||||
--copybutton: #707584;
|
--copybutton: #707584;
|
||||||
--chat-group: #080808;
|
--chat-group: #080808;
|
||||||
--chat-bubble: #9f9f9f0a;
|
--chat-bubble: #9f9f9f0a;
|
||||||
@ -83,6 +84,7 @@ html[theme="dark"] {
|
|||||||
--plugback: #0f1a2e;
|
--plugback: #0f1a2e;
|
||||||
--border: #0b305e;
|
--border: #0b305e;
|
||||||
--border2: #0b305e;
|
--border2: #0b305e;
|
||||||
|
--border3: #767676;
|
||||||
--copybutton: #d0d6de;
|
--copybutton: #d0d6de;
|
||||||
--chat-group: #ffffff;
|
--chat-group: #ffffff;
|
||||||
--chat-bubble: #9694941a;
|
--chat-bubble: #9694941a;
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
"tm32": "Diesem Konto folgt keinem Benutzer",
|
"tm32": "Diesem Konto folgt keinem Benutzer",
|
||||||
"tm33": "Registerkartenmenü importieren",
|
"tm33": "Registerkartenmenü importieren",
|
||||||
"tm34": "Registerkartenmenü Exportieren",
|
"tm34": "Registerkartenmenü Exportieren",
|
||||||
"tm35": "Ihr vorhandenes Tab-Menü wird gelöscht und auf das hochgeladene Tab-Menü gesetzt.",
|
"tm35": "Ihr vorhandenes Tab-Menü wird gelöscht und auf das importiert Tab-Menü gesetzt.",
|
||||||
"tm36": "Tab-Menü erfolgreich wiederhergestellt",
|
"tm36": "Tab-Menü erfolgreich wiederhergestellt",
|
||||||
"tm37": "Tab-Menü erfolgreich gespeichert als",
|
"tm37": "Tab-Menü erfolgreich gespeichert als",
|
||||||
"tm38": "DEV-MODUS",
|
"tm38": "DEV-MODUS",
|
||||||
@ -98,43 +98,43 @@
|
|||||||
"youraccounts": "Ihre Konten",
|
"youraccounts": "Ihre Konten",
|
||||||
"clickto": "Klicken Sie auf Ihr Konto, um sich damit anzumelden",
|
"clickto": "Klicken Sie auf Ihr Konto, um sich damit anzumelden",
|
||||||
"needcreate": "Sie müssen ein Konto erstellen oder speichern, bevor Sie sich anmelden können!",
|
"needcreate": "Sie müssen ein Konto erstellen oder speichern, bevor Sie sich anmelden können!",
|
||||||
"upload": "Laden Sie Ihr Qortal-Backup hoch",
|
"upload": "Importieren Sie Ihre Qortal Backup-Datei",
|
||||||
"howlogin": "Wie möchten Sie sich anmelden?",
|
"howlogin": "Wie möchten Sie sich anmelden?",
|
||||||
"seed": "Seedphrase",
|
"seed": "Seedphrase",
|
||||||
"seedphrase": "seedphrase",
|
"seedphrase": "seedphrase",
|
||||||
"saved": "Gespeichertes Konto",
|
"saved": "Gespeichertes Konto",
|
||||||
"qora": "Qora Adresssamen",
|
"qora": "QORA Adresssamen",
|
||||||
"backup": "Qortal wallet backup",
|
"backup": "Qortal-Sicherungsdatei",
|
||||||
"decrypt": "Entschlüssel Sicherung",
|
"decrypt": "Sicherungsdatei entschlüsseln",
|
||||||
"save": "In diesem Browser speichern.",
|
"save": "In diesem Browser speichern.",
|
||||||
"prepare": "Vorbereiten Ihres Kontos",
|
"prepare": "Vorbereiten Ihres Kontos...",
|
||||||
"areyousure": "Möchten Sie dieses Wallet wirklich aus den gespeicherten Wallets entfernen?",
|
"areyousure": "Möchten Sie dieses Wallet wirklich aus den gespeicherten Wallets entfernen? (Wenn es entfernt wird und keine Sicherungsdatei vorhanden ist, könnte das Konto für immer verloren gehen! Stellen Sie sicher, dass Sie über eine Sicherungsdatei verfügen, bevor Sie dies tun!)",
|
||||||
"error1": "Sicherung muss gültiges JSON format sein",
|
"error1": "Die Sicherungsdatei muss gültiges JSON sein",
|
||||||
"error2": "Anmeldeoption nicht ausgewählt",
|
"error2": "Anmeldeoption nicht ausgewählt",
|
||||||
"createwelcome": "Willkommen bei Qortal, Sie werden feststellen, dass es dem eines RPG-Spiels ähnelt. Sie als Minter im Qortal-Netzwerk (wenn Sie sich dafür entscheiden, einer zu werden) haben die Möglichkeit, Ihr Konto zu verbessern, wodurch Sie mehr von der QORT-Block-Belohnung haben und auch einen größeren Einfluss auf das Netzwerk in Bezug auf die Abstimmung über Entscheidungen für die Plattform zu haben.",
|
"createwelcome": "Willkommen bei Qortal! Ihre dezentrale digitale Zukunft erwartet Sie! Nur bei Qortal haben Sie die absolute Kontrolle über Ihre Daten. Qortal bietet die Basisebene einer neuen, vollständig benutzergesteuerten digitalen Welt.",
|
||||||
"createa": "Eine",
|
"createa": "Eine",
|
||||||
"click": "Klicken Sie hier, um die Seedphrase anzuzeigen",
|
"click": "Klicken Sie hier, um die Seedphrase anzuzeigen",
|
||||||
"confirmpass": "Passwort bestätigen",
|
"confirmpass": "Passwort bestätigen",
|
||||||
"willbe": "wird zufällig im Hintergrund generiert. Diese wird als Ihr privater Schlüsselgenerator für Ihr Blockchain-Konto in Qortal verwendet.",
|
"willbe": "wird zufällig im Hintergrund generiert. Wenn Sie die Seedphrase ANZEIGEN möchten, klicken Sie in diesem Text auf die hervorgehobene „Seedphrase“. Dies wird als Ihr privater Schlüsselgenerator für Ihr Blockchain-Konto in Qortal verwendet. Aus Sicherheitsgründen werden Seedphrases standardmäßig nicht angezeigt, es sei denn, dies wurde ausdrücklich ausgewählt.",
|
||||||
"clicknext": "Erstellen Sie Ihr Qortal-Konto, indem Sie unten auf WEITER klicken.",
|
"clicknext": "Erstellen Sie Ihr Qortal-Konto, indem Sie unten auf WEITER klicken.",
|
||||||
"ready": "Ihr Konto kann jetzt erstellt werden. Es wird in diesem Browser gespeichert. Wenn Sie nicht möchten, dass Ihr neues Konto in Ihrem Browser gespeichert wird, können Sie das Kontrollkästchen unten deaktivieren. Sie können sich weiterhin mit Ihrem neuen Konto anmelden (nachdem Sie sich abgemeldet haben), indem Sie Ihre Brieftaschen-Sicherungsdatei verwenden, die Sie herunterladen MÜSSEN, sobald Sie Ihr Konto erstellt haben.",
|
"ready": "Ihr Konto kann jetzt erstellt werden. Es wird standardmäßig in verschlüsselter Form in dieser Kopie der Qortal-Benutzeroberfläche gespeichert. Wenn Sie nicht möchten, dass Ihr neues Konto hier gespeichert wird, können Sie das Kontrollkästchen unten deaktivieren. Sie können sich weiterhin mit Ihrem neuen Konto anmelden (nachdem Sie sich abgemeldet haben) und dabei Ihre Wallet-Sicherungsdatei verwenden, die Sie nach der Erstellung Ihres Kontos unbedingt herunterladen müssen.",
|
||||||
"welmessage": "Willkommen bei Qortal",
|
"welmessage": "Willkommen bei Qortal",
|
||||||
"pleaseenter": "Bitte Passwort eingeben!",
|
"pleaseenter": "Bitte Passwort eingeben!",
|
||||||
"notmatch": "Passwörter stimmen nicht überein!",
|
"notmatch": "Hoppla! Passwörter stimmen nicht überein! Versuchen Sie es erneut!",
|
||||||
"lessthen8": "Ihr Passwort hat weniger als 5 Zeichen! Dies wird nicht empfohlen. Sie können diese Warnung weiterhin ignorieren.",
|
"lessthen8": "Ihr Passwort hat weniger als 5 Zeichen! Dies wird nicht empfohlen. Sie können diese Warnung weiterhin ignorieren.",
|
||||||
"lessthen8-2": "Ihr Passwort hat weniger als 5 Zeichen!",
|
"lessthen8-2": "Ihr Passwort hat weniger als 5 Zeichen!",
|
||||||
"entername": "Bitte geben Sie einen Namen ein!",
|
"entername": "Bitte geben Sie einen Anzeigenamen ein!",
|
||||||
"downloaded": "Ihre Wallet BackUp-Datei wird heruntergeladen!",
|
"downloaded": "Ihre Wallet-Backup-Datei wurde gespeichert!",
|
||||||
"loading": "Wird geladen, bitte warten...",
|
"loading": "Wird geladen, bitte warten...",
|
||||||
"createdseed": "Ihre erstellte Seedphrase",
|
"createdseed": "Ihre erstellte Seedphrase:",
|
||||||
"saveseed": "Seedphrase speichern",
|
"saveseed": "Seedphrase speichern",
|
||||||
"savein": "Im Browser speichern",
|
"savein": "Speichern Sie in dieser Benutzeroberfläche",
|
||||||
"backup2": "Diese Datei ist die EINZIGE Möglichkeit, auf Ihr Konto auf einem System zuzugreifen, auf dem das Konto nicht in der App oder im Browser gespeichert ist. SICHERN SIE DIESE DATEI AN MEHREREN ORTEN. Die Datei wird sehr sicher verschlüsselt und mit Ihrem lokalen Passwort, das Sie im vorherigen Schritt erstellt haben, entschlüsselt. Sie können es überall sicher speichern, aber stellen Sie sicher, dass Sie dies an mehreren Orten tun.",
|
"backup2": "Diese Datei ist (standardmäßig) die EINZIGE Möglichkeit, auf Ihr Konto zuzugreifen, sofern sie nicht in der Benutzeroberfläche gespeichert wird. Stellen Sie sicher, dass Sie diese Datei an mehreren Orten sichern. Die Datei wird sehr sicher verschlüsselt und mit Ihrem lokalen Passwort, das Sie im vorherigen Schritt erstellt haben, entschlüsselt. Sie können es überall sicher speichern, aber achten Sie darauf, dass Sie dies an mehreren Orten tun.",
|
||||||
"savewallet": "Speichern Sie die Wallet-Sicherungsdatei",
|
"savewallet": "Speichern Sie die Wallet-Sicherungsdatei",
|
||||||
"created1": "Ihr Konto ist jetzt erstellt",
|
"created1": "Ihr Konto ist jetzt erstellt",
|
||||||
"created2": " und wird in diesem Browser gespeichert.",
|
"created2": " und in verschlüsselter Form in dieser Benutzeroberfläche gespeichert.",
|
||||||
"downloadbackup": "Laden Sie die Wallet-Sicherungsdatei herunter",
|
"downloadbackup": "Speichern Sie die Wallet-BackUp-Datei",
|
||||||
"passwordhint": "Ein Passwort muss mindestens 5 Zeichen lang sein.",
|
"passwordhint": "Das Passwort muss mindestens 5 Zeichen lang sein.",
|
||||||
"lp1": "Bildschirm sperren",
|
"lp1": "Bildschirm sperren",
|
||||||
"lp2": "Es ist kein Passwort für den Sperrbildschirm festgelegt!",
|
"lp2": "Es ist kein Passwort für den Sperrbildschirm festgelegt!",
|
||||||
"lp3": "Bitte legen Sie eins fest",
|
"lp3": "Bitte legen Sie eins fest",
|
||||||
@ -163,8 +163,8 @@
|
|||||||
"confirmlogout": "Möchten Sie sich wirklich abmelden?"
|
"confirmlogout": "Möchten Sie sich wirklich abmelden?"
|
||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "Datei auswählen",
|
"selectfile": "Wählen Sie die Sicherungsdatei aus",
|
||||||
"dragfile": "Backup per Drag-and-Drop hierher ziehen"
|
"dragfile": "Ziehen Sie die Datei per Drag-and-Drop oder klicken Sie hier, um die Sicherungsdatei auszuwählen"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "Allgemeine Kontoinformationen",
|
"generalinfo": "Allgemeine Kontoinformationen",
|
||||||
@ -181,19 +181,19 @@
|
|||||||
"notifications": "Benachrichtigungen",
|
"notifications": "Benachrichtigungen",
|
||||||
"accountsecurity": "Konto Sicherheit",
|
"accountsecurity": "Konto Sicherheit",
|
||||||
"password": "Passwort",
|
"password": "Passwort",
|
||||||
"download": "Sicherungsdatei herunterladen",
|
"download": "Sicherungsdatei exportieren/speichern",
|
||||||
"choose": "Bitte wählen Sie ein Passwort, um Ihr Backup zu verschlüsseln. (Dies kann dasselbe sein wie das, mit dem Sie sich angemeldet haben, oder ein anderes)",
|
"choose": "Bitte geben Sie ein Passwort ein, um Ihre Sicherungsdatei zu verschlüsseln. (Dies kann dasselbe sein wie das, mit dem Sie sich angemeldet haben, oder ein neues.)",
|
||||||
"playsound": "Ton abspielen",
|
"playsound": "Ton abspielen",
|
||||||
"shownotifications": "Zeige Benachrichtigungen",
|
"shownotifications": "Zeige Benachrichtigungen",
|
||||||
"nodeurl": "Knotenverbindung",
|
"nodeurl": "Knotenverbindung",
|
||||||
"nodehint": "Wählen Sie einen Knoten aus der Standardliste der Knoten oben aus oder fügen Sie der obigen Liste einen benutzerdefinierten Knoten hinzu, indem Sie auf die Schaltfläche unten klicken",
|
"nodehint": "Wählen Sie einen Knoten aus der Standardliste aus oder fügen Sie der Liste einen benutzerdefinierten Knoten hinzu, indem Sie auf die Schaltfläche unten klicken",
|
||||||
"addcustomnode": "Benutzerdefinierten Knoten hinzufügen",
|
"addcustomnode": "Benutzerdefinierten Knoten hinzufügen",
|
||||||
"addandsave": "Hinzufügen und speichern",
|
"addandsave": "Hinzufügen und speichern",
|
||||||
"protocol": "Protokoll",
|
"protocol": "Protokoll",
|
||||||
"domain": "Domain",
|
"domain": "Domain",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
"import": "Knoten Importieren",
|
"import": "Gespeicherte Knoten importieren",
|
||||||
"export": "Knoten Exportieren",
|
"export": "Gespeicherte Knoten exportieren",
|
||||||
"deletecustomnode": "Alle benutzerdefinierten Knoten entfernen",
|
"deletecustomnode": "Alle benutzerdefinierten Knoten entfernen",
|
||||||
"warning": "Ihre bestehenden Knoten werden gelöscht und aus dem Backup neu erstellt.",
|
"warning": "Ihre bestehenden Knoten werden gelöscht und aus dem Backup neu erstellt.",
|
||||||
"snack1": "Benutzerdefinierten Knoten erfolgreich gelöscht und Standardknoten hinzugefügt",
|
"snack1": "Benutzerdefinierten Knoten erfolgreich gelöscht und Standardknoten hinzugefügt",
|
||||||
@ -203,17 +203,17 @@
|
|||||||
"snack5": "Knoten erfolgreich importiert",
|
"snack5": "Knoten erfolgreich importiert",
|
||||||
"snack6": "Benutzerdefinierter Knoten erfolgreich entfernt",
|
"snack6": "Benutzerdefinierter Knoten erfolgreich entfernt",
|
||||||
"snack7": "Benutzerdefinierter Knoten erfolgreich bearbeitet",
|
"snack7": "Benutzerdefinierter Knoten erfolgreich bearbeitet",
|
||||||
"exp1": "Privaten Hauptschlüssel exportieren",
|
"exp1": "Master-Privatschlüssel exportieren (xpriv)",
|
||||||
"exp2": "Hauptschlüssel exportieren",
|
"exp2": "Hauptschlüssel exportieren",
|
||||||
"exp3": "Exportieren",
|
"exp3": "Exportieren",
|
||||||
"exp4": "Bitte wählen Sie eine Brieftasche aus, um den privaten Hauptschlüssel zu sichern.",
|
"exp4": "Bitte wählen Sie eine Wallet aus, um den privaten Master-Schlüssel zu sichern/exportieren.",
|
||||||
"core": "Core-Einstellungen starten",
|
"core": "Grundlegende Autostart-Einstellungen",
|
||||||
"qappNotification1": "Q-App Benachrichtigungen",
|
"qappNotification1": "Q-App Benachrichtigungen",
|
||||||
"selectnode": "Bitte wählen Sie eine Option",
|
"selectnode": "Bitte wählen Sie eine Option",
|
||||||
"arrr1": "ARRR-Wallet nicht initialisiert!",
|
"arrr1": "ARRR-Wallet nicht initialisiert!",
|
||||||
"arrr2": "Bitte gehen Sie zur Registerkarte „Wallet“ und initialisieren Sie zuerst Ihre arrr-Wallet.",
|
"arrr2": "Bitte gehen Sie zur Registerkarte „Wallet“ und greifen Sie auf das ARRR-Wallet zu, um zuerst das Wallet zu initialisieren.",
|
||||||
"arrr3": "Core-Update erforderlich!",
|
"arrr3": "Core-Update erforderlich!",
|
||||||
"arrr4": "Um den privaten Schlüssel Ihrer arrr-Wallet zu speichern, benötigen Sie zuerst ein Core-Update!",
|
"arrr4": "Um den privaten Schlüssel Ihres ARRR-Wallets zu speichern, müssen Sie zunächst den Qortal Core aktualisieren!",
|
||||||
"sync_indicator": "Synchronisierungsanzeige-Popup deaktivieren"
|
"sync_indicator": "Synchronisierungsanzeige-Popup deaktivieren"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "Guthaben",
|
"balance": "Guthaben",
|
||||||
"balances": "IHR WALLET-GUTHABEN",
|
"balances": "IHR WALLET-GUTHABEN",
|
||||||
"update": "AKTUALISIERE WALLET-GUTHABEN",
|
"update": "AKTUALISIERE WALLET-GUTHABEN",
|
||||||
"view": "Ansehen"
|
"view": "Ansehen",
|
||||||
|
"all": "Alle",
|
||||||
|
"page": "Seite"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "GIF-Explorer",
|
"gchange1": "GIF-Explorer",
|
||||||
@ -283,15 +285,15 @@
|
|||||||
},
|
},
|
||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "Prägekonten können nicht abgerufen werden",
|
"smchange1": "Prägekonten können nicht abgerufen werden",
|
||||||
"smchange2": "Schlüssel konnte nicht entfernt werden",
|
"smchange2": "Minting-Schlüssel konnte nicht entfernt werden",
|
||||||
"smchange3": "Prägeschlüssel konnte nicht hinzugefügt werden",
|
"smchange3": "Das Hinzufügen des Minting-Schlüssels ist fehlgeschlagen. Wenn der Schlüssel gerade erstellt wurde, warten Sie ein paar Blöcke und fügen Sie ihn erneut hinzu",
|
||||||
"smchange4": "Sponsorship-Schlüssel kann nicht erstellt werden",
|
"smchange4": "Sponsorship-Schlüssel kann nicht erstellt werden",
|
||||||
"smchange5": "Beziehung schaffen",
|
"smchange5": "Beziehung schaffen",
|
||||||
"smchange6": "Warten auf Bestätigung in der Blockchain",
|
"smchange6": "Warten auf Bestätigung in der Blockchain",
|
||||||
"smchange7": "Beziehung beenden",
|
"smchange7": "Beziehung beenden",
|
||||||
"smchange8": "Prägeschlüssel zum Knoten hinzufügen",
|
"smchange8": "Prägeschlüssel zum Knoten hinzufügen",
|
||||||
"smchange9": "Vollständig",
|
"smchange9": "Vollständig",
|
||||||
"smchange10": "Pro Node sind nur 2 Minting Keys erlaubt, Sie versuchen 3 Keys zuzuweisen, gehen Sie bitte zu Management - Node Management und entfernen Sie den Key, den Sie diesem Node nicht zuweisen möchten, danke!"
|
"smchange10": "Pro Knoten sind nur 2 Minting-Schlüssel zulässig. Sie versuchen, 3 Schlüssel zuzuweisen. Gehen Sie bitte zur Knotenverwaltung und entfernen Sie alle unnötigen Schlüssel. Vielen Dank!"
|
||||||
},
|
},
|
||||||
"mintingpage": {
|
"mintingpage": {
|
||||||
"mchange1": "Allgemeine Prägedetails",
|
"mchange1": "Allgemeine Prägedetails",
|
||||||
@ -466,10 +468,10 @@
|
|||||||
"rchange6": "Empfänger",
|
"rchange6": "Empfänger",
|
||||||
"rchange7": "Aktion",
|
"rchange7": "Aktion",
|
||||||
"rchange8": "Typ",
|
"rchange8": "Typ",
|
||||||
"rchange9": "Level 1 - 4 können einen Self Share erstellen und Level 5 oder höher können einen Reward Share erstellen!",
|
"rchange9": "Die Stufen 1–4 können nur Self-Share-(Minting-)Schlüssel erstellen. Nur Level 5 oder höher kann einen Prämienanteil erstellen!",
|
||||||
"rchange10": "Öffentlicher Schlüssel des Empfängers",
|
"rchange10": "Öffentlicher Schlüssel des Empfängers",
|
||||||
"rchange11": "Belohnungsanteil in Prozent",
|
"rchange11": "Belohnungsanteil in Prozent",
|
||||||
"rchange12": "Mache Etwas Leckeres",
|
"rchange12": "Angeforderter Befehl wird ausgeführt...",
|
||||||
"rchange13": "Füge Minting Konto hinzu",
|
"rchange13": "Füge Minting Konto hinzu",
|
||||||
"rchange14": "Hinzufügen",
|
"rchange14": "Hinzufügen",
|
||||||
"rchange15": "Dieses Konto ist nicht an Belohnungsanteile beteiligt",
|
"rchange15": "Dieses Konto ist nicht an Belohnungsanteile beteiligt",
|
||||||
@ -507,12 +509,12 @@
|
|||||||
"nchange23": "Verkaufspreis",
|
"nchange23": "Verkaufspreis",
|
||||||
"nchange24": "Keine Namen zu verkaufen",
|
"nchange24": "Keine Namen zu verkaufen",
|
||||||
"nchange25": "Name zu verkaufen",
|
"nchange25": "Name zu verkaufen",
|
||||||
"nchange26": "Sind Sie sicher, dass Sie diesen Namen verkaufen möchten?",
|
"nchange26": "Sind Sie sicher, dass Sie diesen Namen verkaufen möchten? Wenn der Name von einem anderen Konto gekauft wird, liegt dies außerhalb Ihrer Kontrolle!",
|
||||||
"nchange27": "Für diesen Preis in QORT",
|
"nchange27": "Für diesen Preis in QORT",
|
||||||
"nchange28": "Beim Drücken auf Bestätigen wird die Anfrage zum Verkauf gesendet!",
|
"nchange28": "Wenn Sie auf „Bestätigen“ klicken, wird Ihr Name zum Verkauf angeboten!",
|
||||||
"nchange29": "Name zu stornieren",
|
"nchange29": "Name zu stornieren",
|
||||||
"nchange30": "Sind Sie sicher, den Verkauf für diesen Namen abzubrechen?",
|
"nchange30": "Sind Sie sicher, den Verkauf für diesen Namen abzubrechen?",
|
||||||
"nchange31": "Beim Drücken auf Bestätigen wird die Anfrage zum Stornieren des Verkaufs gesendet!",
|
"nchange31": "Wenn Sie auf „Bestätigen“ klicken, wird der Namensverkauf abgebrochen!",
|
||||||
"nchange32": "Namensverkaufsanfrage erfolgreich!",
|
"nchange32": "Namensverkaufsanfrage erfolgreich!",
|
||||||
"nchange33": "Verkaufsnamensanfrage erfolgreich stornieren!",
|
"nchange33": "Verkaufsnamensanfrage erfolgreich stornieren!",
|
||||||
"nchange34": "Kaufname-Anfrage erfolgreich!",
|
"nchange34": "Kaufname-Anfrage erfolgreich!",
|
||||||
@ -549,7 +551,7 @@
|
|||||||
"schange15": "Blockierte Webseiten",
|
"schange15": "Blockierte Webseiten",
|
||||||
"schange16": "Sie haben keine Webseiten blockiert",
|
"schange16": "Sie haben keine Webseiten blockiert",
|
||||||
"schange17": "Name nicht gefunden!",
|
"schange17": "Name nicht gefunden!",
|
||||||
"schange18": "Der Relay-Modus ist aktiviert. Dies bedeutet, dass Ihr Knoten dabei hilft, verschlüsselte Daten im Netzwerk zu transportieren, wenn ein Peer sie anfordert. Sie können sich per Einstellung abmelden, ändern Sie",
|
"schange18": "Der Relaismodus ist aktiviert. Das bedeutet, dass Ihr Knoten dabei hilft, VERSCHLÜSSELTE/CHUNKIERTE Daten im Netzwerk zu transportieren, wenn ein Peer dies anfordert. Sie können sich per Einstellung abmelden",
|
||||||
"schange19": "in",
|
"schange19": "in",
|
||||||
"schange20": "Der Relay-Modus ist deaktiviert. Sie können es durch Einstellung aktivieren, ändern Sie",
|
"schange20": "Der Relay-Modus ist deaktiviert. Sie können es durch Einstellung aktivieren, ändern Sie",
|
||||||
"schange21": "Webseite veröffentlichen",
|
"schange21": "Webseite veröffentlichen",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "Zu suchender Gruppenname",
|
"gchange56": "Zu suchender Gruppenname",
|
||||||
"gchange57": "Privater Gruppenname nicht gefunden",
|
"gchange57": "Privater Gruppenname nicht gefunden",
|
||||||
"gchange58": "Beachten Sie, dass der Gruppenname genau übereinstimmen muss.",
|
"gchange58": "Beachten Sie, dass der Gruppenname genau übereinstimmen muss.",
|
||||||
"gchange59": "Ticker ein-/ausblenden"
|
"gchange59": "Ticker ein-/ausblenden",
|
||||||
|
"gchange60": "Bitte geben Sie den Gruppennamen ein",
|
||||||
|
"gchange61": "Bitte Beschreibung eingeben",
|
||||||
|
"gchange62": "Sind Sie sicher, dass Sie diese Gruppe AKTUALISIEREN möchten?",
|
||||||
|
"gchange63": "Wenn Sie auf CONFIRM klicken, wird die UPDATE_GROUP Anfrage gesendet!",
|
||||||
|
"gchange64": "Derzeitiger Besitzer / Neuer Besitzer",
|
||||||
|
"gchange65": "Ersetzen Sie diese Adresse durch EIGENTUM der Gruppe übertragen!",
|
||||||
|
"gchange66": "Ungültige Besitzer-/neue Besitzeradresse",
|
||||||
|
"gchange67": "Gruppen-UPDATE erfolgreich!",
|
||||||
|
"gchange68": "Gruppen-Avatar festlegen"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Rätsel",
|
"pchange1": "Rätsel",
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
"tm32": "Esta cuenta no sigue a ningún usuario",
|
"tm32": "Esta cuenta no sigue a ningún usuario",
|
||||||
"tm33": "Menú de pestaña Importar",
|
"tm33": "Menú de pestaña Importar",
|
||||||
"tm34": "Menú de pestaña Exportar",
|
"tm34": "Menú de pestaña Exportar",
|
||||||
"tm35": "Tu menú de pestañas existente se eliminará y se establecerá en el menú de pestañas cargado.",
|
"tm35": "Su menú de pestañas existente se eliminará y se configurará como menú de pestañas importado.",
|
||||||
"tm36": "Menú de pestañas restaurado con éxito",
|
"tm36": "Menú de pestañas restaurado con éxito",
|
||||||
"tm37": "Menú de pestañas guardado correctamente como",
|
"tm37": "Menú de pestañas guardado correctamente como",
|
||||||
"tm38": "MODO DEV",
|
"tm38": "MODO DEV",
|
||||||
@ -103,37 +103,37 @@
|
|||||||
"seed": "Frasesemilla",
|
"seed": "Frasesemilla",
|
||||||
"seedphrase": "frasesemilla",
|
"seedphrase": "frasesemilla",
|
||||||
"saved": "Cuenta guardada",
|
"saved": "Cuenta guardada",
|
||||||
"qora": "Frase semilla de la dirección Qora",
|
"qora": "Frase semilla de la dirección QORA",
|
||||||
"backup": "Copia de seguridad del monedero Qortal",
|
"backup": "Archivo de copia de seguridad Qortal",
|
||||||
"decrypt": "Descifrar copia de seguridad",
|
"decrypt": "Descifrar archivo de copia de seguridad",
|
||||||
"save": "Guardar en este navegador.",
|
"save": "Guardar en este navegador.",
|
||||||
"prepare": "Preparando tu cuenta",
|
"prepare": "Preparando tu cuenta...",
|
||||||
"areyousure": "¿Está seguro que desea eliminar este monedero de los monederos guardados?",
|
"areyousure": "¿Está seguro de que desea eliminar esta billetera de las billeteras guardadas? (Si se elimina y no existe un archivo de respaldo, la cuenta podría perderse para siempre. ¡Asegúrese de tener un archivo de respaldo antes de hacer esto!)",
|
||||||
"error1": "La copia de seguridad tiene que ser un JSON válido",
|
"error1": "La copia de seguridad tiene que ser un JSON válido",
|
||||||
"error2": "Opción de inicio de sesión no seleccionada",
|
"error2": "Opción de inicio de sesión no seleccionada",
|
||||||
"createwelcome": "Bienvenido a Qortal, encontrarás que es similar a un juego de rol, usted, como minero en la red Qortal (si decide convertirse en uno) tendrá la oportunidad de subir de nivel su cuenta, dándole más de la recompensa del bloque QORT y también una mayor influencia sobre la red en términos de votación sobre las decisiones en la plataforma.",
|
"createwelcome": "¡Bienvenidos a Qortal! ¡Tu futuro digital descentralizado te espera! En Qortal sólo tú tienes control absoluto sobre tus datos. Qortal proporciona el nivel básico de un mundo digital nuevo y totalmente controlado por el usuario.",
|
||||||
"createa": "A",
|
"createa": "A",
|
||||||
"click": "Haz clic para ver la frasesemilla",
|
"click": "Haz clic para ver la frasesemilla",
|
||||||
"confirmpass": "Confirmar Contraseña",
|
"confirmpass": "Confirmar Contraseña",
|
||||||
"willbe": "Se generará aleatoriamente en segundo plano. Esto se utiliza como su generador de clave privada para su cuenta de blockchain en Qortal.",
|
"willbe": "se generará aleatoriamente en segundo plano. Si desea VER la frase inicial, haga clic en la 'frase inicial' resaltada en este texto. Esto se utiliza como su generador de clave privada para su cuenta blockchain en Qortal. Por seguridad, de forma predeterminada, las frases iniciales no se muestran a menos que se elijan específicamente para ello.",
|
||||||
"clicknext": "Crea tu cuenta Qortal haciendo clic en SIGUIENTE a continuación",
|
"clicknext": "Crea tu cuenta Qortal haciendo clic en SIGUIENTE a continuación",
|
||||||
"ready": "Su cuenta está lista para ser creada. Será guardada en este navegador. Si no quiere que su nueva cuenta sea guardada en el navegador, puede desmarcar la casilla de abajo. Podrá seguir accediendo con su nueva cuenta (después de cerrar la sesión), utilizando el archivo de copia de seguridad de su monedero que DEBE descargar una vez que haya creado su cuenta.",
|
"ready": "Su cuenta ahora está lista para ser creada. Se guardará dentro de esta copia de la interfaz de usuario de Qortal de forma predeterminada, en forma cifrada. Si no desea que su nueva cuenta se guarde aquí, puede desmarcar la casilla a continuación. Aún podrá iniciar sesión con su nueva cuenta (después de cerrar sesión), utilizando el archivo de respaldo de su billetera que DEBE descargar una vez que cree su cuenta.",
|
||||||
"welmessage": "Bienvenido a Qortal",
|
"welmessage": "Bienvenido a Qortal",
|
||||||
"pleaseenter": "Por favor, introduzca una Contraseña!",
|
"pleaseenter": "Por favor, introduzca una Contraseña!",
|
||||||
"notmatch": "Las contraseñas no coinciden!",
|
"notmatch": "¡Ups! ¡Las contraseñas no coinciden! ¡Intentar otra vez!",
|
||||||
"lessthen8": "Su contraseña tiene menos de 5 caracteres! Esto no es recomendable. Puede continuar para ignorar esta advertencia.",
|
"lessthen8": "Su contraseña tiene menos de 5 caracteres! Esto no es recomendable. Puede continuar para ignorar esta advertencia.",
|
||||||
"lessthen8-2": "Su contraseña tiene menos de 5 caracteres!",
|
"lessthen8-2": "Su contraseña tiene menos de 5 caracteres!",
|
||||||
"entername": "Por favor, introduzca un Nombre!",
|
"entername": "¡Ingrese un nombre para mostrar!",
|
||||||
"downloaded": "La copia de seguridad de su monedero ha sido descargada!",
|
"downloaded": "¡Se guardó su archivo de copia de seguridad de Wallet!",
|
||||||
"loading": "Cargando, Por favor espere...",
|
"loading": "Cargando, Por favor espere...",
|
||||||
"createdseed": "Su Frasesemilla creada",
|
"createdseed": "Su Frasesemilla creada:",
|
||||||
"saveseed": "Guardar Frasesemilla",
|
"saveseed": "Guardar Frasesemilla",
|
||||||
"savein": "Guardar en el navegador",
|
"savein": "Guardar en esta UI",
|
||||||
"backup2": "Este archivo es la ÚNICA manera de acceder a su cuenta en un sistema que no lo tenga guardado en la aplicación/navegador. ASEGÚRATE DE HACER UNA COPIA DE SEGURIDAD DE ESTE ARCHIVO EN VARIOS LUGARES. El archivo está encriptado de forma muy segura y descifrado con su contraseña local que creó en el paso anterior. Puedes guardarlo en cualquier lugar de forma segura, pero asegúrate de hacerlo en múltiples lugares.",
|
"backup2": "Este archivo es la ÚNICA manera de acceder a su cuenta en un sistema que no lo tenga guardado en la aplicación/navegador. ASEGÚRATE DE HACER UNA COPIA DE SEGURIDAD DE ESTE ARCHIVO EN VARIOS LUGARES. El archivo está encriptado de forma muy segura y descifrado con su contraseña local que creó en el paso anterior. Puedes guardarlo en cualquier lugar de forma segura, pero asegúrate de hacerlo en múltiples lugares.",
|
||||||
"savewallet": "Guardar archivo de copia de seguridad del monedero",
|
"savewallet": "Guardar archivo de copia de seguridad del monedero",
|
||||||
"created1": "Su cuenta ha sido creada",
|
"created1": "Su cuenta ha sido creada",
|
||||||
"created2": " y será guardada en el navegador.",
|
"created2": " y guardado en esta interfaz de usuario en forma cifrada.",
|
||||||
"downloadbackup": "Descargar archivo de copia de seguridad del monedero",
|
"downloadbackup": "Guardar archivo de respaldo de Wallet",
|
||||||
"passwordhint": "Una contraseña debe tener al menos 5 caracteres.",
|
"passwordhint": "Una contraseña debe tener al menos 5 caracteres.",
|
||||||
"lp1": "Pantalla de bloqueo",
|
"lp1": "Pantalla de bloqueo",
|
||||||
"lp2": "¡No se estableció una contraseña de pantalla de bloqueo!",
|
"lp2": "¡No se estableció una contraseña de pantalla de bloqueo!",
|
||||||
@ -163,8 +163,8 @@
|
|||||||
"confirmlogout": "¿Está seguro que desea cerrar sesión?"
|
"confirmlogout": "¿Está seguro que desea cerrar sesión?"
|
||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "Seleccione un archivo",
|
"selectfile": "Seleccionar archivo de respaldo",
|
||||||
"dragfile": "Arrastra y suelta la copia de seguridad aquí"
|
"dragfile": "Arrastre y suelte o haga clic aquí para seleccionar el archivo de respaldo"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "Información General de la Cuenta",
|
"generalinfo": "Información General de la Cuenta",
|
||||||
@ -181,19 +181,19 @@
|
|||||||
"notifications": "Notificaciones",
|
"notifications": "Notificaciones",
|
||||||
"accountsecurity": "Seguridad de la Cuenta",
|
"accountsecurity": "Seguridad de la Cuenta",
|
||||||
"password": "Contraseña",
|
"password": "Contraseña",
|
||||||
"download": "Descargar copia de seguridad",
|
"download": "Exportar/guardar archivo de copia de seguridad",
|
||||||
"choose": "Por favor, elija una contraseña para cifrar su copia de seguridad. (Puede ser la misma con la que ha iniciado la sesión, o diferente)",
|
"choose": "Elija una contraseña para cifrar su archivo de copia de seguridad. (Este puede ser el mismo con el que inició sesión o uno nuevo).",
|
||||||
"playsound": "Reproducir Sonido",
|
"playsound": "Reproducir Sonido",
|
||||||
"shownotifications": "Mostrar Notificaciones",
|
"shownotifications": "Mostrar Notificaciones",
|
||||||
"nodeurl": "URL del Nodo",
|
"nodeurl": "URL del Nodo",
|
||||||
"nodehint": "Seleccione un nodo de la lista predeterminada de nodos de arriba o añada un nodo personalizado a la lista de arriba haciendo clic en el botón de abajo",
|
"nodehint": "Seleccione un nodo de la lista predeterminada o agregue un nodo personalizado a la lista haciendo clic en el botón a continuación",
|
||||||
"addcustomnode": "Añadir un Nodo Personalizado",
|
"addcustomnode": "Añadir un Nodo Personalizado",
|
||||||
"addandsave": "Añadir Y Guardar",
|
"addandsave": "Añadir Y Guardar",
|
||||||
"protocol": "Protocolo",
|
"protocol": "Protocolo",
|
||||||
"domain": "Dominio",
|
"domain": "Dominio",
|
||||||
"port": "Puerto",
|
"port": "Puerto",
|
||||||
"import": "Importar Nodos",
|
"import": "Importar nodos guardados",
|
||||||
"export": "Exportar Nodos",
|
"export": "Exportar Nodos guardados",
|
||||||
"deletecustomnode": "Eliminar todos los nodos personalizados",
|
"deletecustomnode": "Eliminar todos los nodos personalizados",
|
||||||
"warning": "Sus nodos existentes se eliminarán y se crearán nuevos a partir de la copia de seguridad.",
|
"warning": "Sus nodos existentes se eliminarán y se crearán nuevos a partir de la copia de seguridad.",
|
||||||
"snack1": "Nodos estándar eliminados y agregados con éxito",
|
"snack1": "Nodos estándar eliminados y agregados con éxito",
|
||||||
@ -203,17 +203,17 @@
|
|||||||
"snack5": "Nodos importados con éxito",
|
"snack5": "Nodos importados con éxito",
|
||||||
"snack6": "Nodo personalizado eliminado exitosamente",
|
"snack6": "Nodo personalizado eliminado exitosamente",
|
||||||
"snack7": "Nodo personalizado editado con éxito",
|
"snack7": "Nodo personalizado editado con éxito",
|
||||||
"exp1": "Exportar clave maestra privada",
|
"exp1": "Exportar clave privada maestra (xpriv)",
|
||||||
"exp2": "Exportar clave maestra",
|
"exp2": "Exportar clave maestra",
|
||||||
"exp3": "Exportar",
|
"exp3": "Exportar",
|
||||||
"exp4": "Elija una billetera para hacer una copia de seguridad de la clave maestra privada.",
|
"exp4": "Elija una billetera para hacer una copia de seguridad de la clave privada maestra.",
|
||||||
"core": "Iniciar configuración básica",
|
"core": "Configuración principal de inicio automático",
|
||||||
"qappNotification1": "Notificaciones de Q-App",
|
"qappNotification1": "Notificaciones de Q-App",
|
||||||
"selectnode": "Por favor seleccione una opción",
|
"selectnode": "Por favor seleccione una opción",
|
||||||
"arrr1": "¡Cartera ARRR no inicializada!",
|
"arrr1": "¡Cartera ARRR no inicializada!",
|
||||||
"arrr2": "Por favor, vaya a la pestaña de billetera e inicialice su billetera arrr primero.",
|
"arrr2": "Vaya a la pestaña de billetera y acceda a la billetera ARRR para inicializar la billetera primero.",
|
||||||
"arrr3": "¡Necesita actualización principal!",
|
"arrr3": "¡Necesita actualización principal!",
|
||||||
"arrr4": "¡Para guardar la clave privada de tu billetera arrr, primero necesitas una actualización básica!",
|
"arrr4": "¡Para guardar la clave privada de su billetera ARRR, primero debe actualizar Qortal Core!",
|
||||||
"sync_indicator": "Desactivar la ventana emergente del indicador de sincronización"
|
"sync_indicator": "Desactivar la ventana emergente del indicador de sincronización"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "Saldo",
|
"balance": "Saldo",
|
||||||
"balances": "LOS SALDOS DE TU BILLETERA",
|
"balances": "LOS SALDOS DE TU BILLETERA",
|
||||||
"update": "ACTUALIZAR SALDOS DE CARTERA",
|
"update": "ACTUALIZAR SALDOS DE CARTERA",
|
||||||
"view": "Vista"
|
"view": "Vista",
|
||||||
|
"all": "Todo",
|
||||||
|
"page": "Página"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Explorador de gifs",
|
"gchange1": "Explorador de gifs",
|
||||||
@ -283,15 +285,15 @@
|
|||||||
},
|
},
|
||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "No se pueden obtener cuentas de acuñación",
|
"smchange1": "No se pueden obtener cuentas de acuñación",
|
||||||
"smchange2": "No se pudo quitar la clave",
|
"smchange2": "No se pudo eliminar la clave de acuñación",
|
||||||
"smchange3": "No se pudo agregar la clave de acuñación",
|
"smchange3": "No se pudo agregar la clave de acuñación. Si la clave se acaba de crear, intente esperar unos bloques y agregarla nuevamente.",
|
||||||
"smchange4": "No se puede crear la clave de patrocinio",
|
"smchange4": "No se puede crear la clave de patrocinio",
|
||||||
"smchange5": "Creando relación",
|
"smchange5": "Creando relación",
|
||||||
"smchange6": "En espera de confirmación en blockchain",
|
"smchange6": "En espera de confirmación en blockchain",
|
||||||
"smchange7": "Terminando la relación",
|
"smchange7": "Terminando la relación",
|
||||||
"smchange8": "Agregar clave de acuñación al nodo",
|
"smchange8": "Agregar clave de acuñación al nodo",
|
||||||
"smchange9": "Completo",
|
"smchange9": "Completo",
|
||||||
"smchange10": "Solo se permiten 2 claves de acuñación por nodo, está intentando asignar 3 claves, vaya a administración - administración de nodos y elimine la clave que no desea asignar a este nodo, gracias!"
|
"smchange10": "Solo se permiten 2 claves de acuñación por nodo. Está intentando asignar 3 claves. Vaya a Administración de nodos y elimine las claves innecesarias. ¡Gracias!"
|
||||||
},
|
},
|
||||||
"mintingpage": {
|
"mintingpage": {
|
||||||
"mchange1": "Detalles Generales de Acuñación",
|
"mchange1": "Detalles Generales de Acuñación",
|
||||||
@ -466,10 +468,10 @@
|
|||||||
"rchange6": "Receptor",
|
"rchange6": "Receptor",
|
||||||
"rchange7": "Acción",
|
"rchange7": "Acción",
|
||||||
"rchange8": "Tipo",
|
"rchange8": "Tipo",
|
||||||
"rchange9": "Los niveles de 1 a 4 pueden crear una Self Share y los niveles 5 o superior pueden crear una Reward Share!",
|
"rchange9": "Los niveles 1 a 4 solo pueden crear claves Self-Share (acuñación). ¡Solo el nivel 5 o superior puede crear una recompensa compartida!",
|
||||||
"rchange10": "Clave pública del receptor",
|
"rchange10": "Clave pública del receptor",
|
||||||
"rchange11": "Porcentaje de Reward share",
|
"rchange11": "Porcentaje de Reward share",
|
||||||
"rchange12": "Haciendo algo delicioso",
|
"rchange12": "Ejecutando el comando solicitado",
|
||||||
"rchange13": "Añadir cuenta de acuñación",
|
"rchange13": "Añadir cuenta de acuñación",
|
||||||
"rchange14": "Añadir",
|
"rchange14": "Añadir",
|
||||||
"rchange15": "La cuenta no participa en ninguna reward share",
|
"rchange15": "La cuenta no participa en ninguna reward share",
|
||||||
@ -507,12 +509,12 @@
|
|||||||
"nchange23": "Precio de venta",
|
"nchange23": "Precio de venta",
|
||||||
"nchange24": "No hay nombres para vender",
|
"nchange24": "No hay nombres para vender",
|
||||||
"nchange25": "Nombre para vender",
|
"nchange25": "Nombre para vender",
|
||||||
"nchange26": "¿Estás seguro de vender este nombre?",
|
"nchange26": "¿Estás seguro de que quieres vender este nombre? Si otra cuenta compra el nombre, ¡estará fuera de su control!",
|
||||||
"nchange27": "Por este precio en QORT",
|
"nchange27": "Por este precio en QORT",
|
||||||
"nchange28": "¡Al presionar confirmar, se enviará la solicitud de nombre de venta!",
|
"nchange28": "¡Al presionar confirmar, su nombre aparecerá a la venta!",
|
||||||
"nchange29": "Nombre para cancelar",
|
"nchange29": "Nombre para cancelar",
|
||||||
"nchange30": "¿Está seguro de cancelar la venta de este nombre?",
|
"nchange30": "¿Está seguro de cancelar la venta de este nombre?",
|
||||||
"nchange31": "¡Al presionar confirmar, se enviará la solicitud de cancelación de nombre de venta!",
|
"nchange31": "¡Al presionar confirmar, la venta del nombre será cancelada!",
|
||||||
"nchange32": "¡Solicitud de nombre de venta exitosa!",
|
"nchange32": "¡Solicitud de nombre de venta exitosa!",
|
||||||
"nchange33": "¡Cancelar solicitud de venta de nombre exitosa!",
|
"nchange33": "¡Cancelar solicitud de venta de nombre exitosa!",
|
||||||
"nchange34": "¡Solicitud de nombre de compra exitosa!",
|
"nchange34": "¡Solicitud de nombre de compra exitosa!",
|
||||||
@ -549,7 +551,7 @@
|
|||||||
"schange15": "Sitios web bloqueados",
|
"schange15": "Sitios web bloqueados",
|
||||||
"schange16": "No ha bloqueado ningún sitio web",
|
"schange16": "No ha bloqueado ningún sitio web",
|
||||||
"schange17": "Nombre no encontrado!",
|
"schange17": "Nombre no encontrado!",
|
||||||
"schange18": "El modo de retransmisión está activado. Esto significa que tu nodo ayudará a transportar datos encriptados por la red cuando un par lo solicite. Puedes optar por no hacerlo configurando",
|
"schange18": "El modo de retransmisión está habilitado (relayModeEnabled: true). Esto significa que su nodo ayudará a transportar datos CIFRADOS/CHUNKED por la red cuando un par lo solicite. Puede optar por no participar configurando",
|
||||||
"schange19": "en",
|
"schange19": "en",
|
||||||
"schange20": "El modo de retransmisión está desactivado. Puede activarlo configurando",
|
"schange20": "El modo de retransmisión está desactivado. Puede activarlo configurando",
|
||||||
"schange21": "Publicar Sitio Web",
|
"schange21": "Publicar Sitio Web",
|
||||||
@ -586,7 +588,7 @@
|
|||||||
"schange15": "Q-Apps bloqueadas",
|
"schange15": "Q-Apps bloqueadas",
|
||||||
"schange16": "No has bloqueado ninguna Q-Apps",
|
"schange16": "No has bloqueado ninguna Q-Apps",
|
||||||
"schange17": "¡No se encontró el nombre!",
|
"schange17": "¡No se encontró el nombre!",
|
||||||
"schange18": "El modo de retransmisión está habilitado. Esto significa que su nodo ayudará a transportar datos cifrados por la red cuando un par lo solicite. Puede optar por no hacerlo configurando",
|
"schange18": "El modo de retransmisión está habilitado. Esto significa que su nodo ayudará a transportar datos CIFRADOS/CHUNKED por la red cuando un par lo solicite. Puede optar por no participar configurando",
|
||||||
"schange19": "en",
|
"schange19": "en",
|
||||||
"schange20": "El modo de relé está deshabilitado. Puedes habilitarlo configurando",
|
"schange20": "El modo de relé está deshabilitado. Puedes habilitarlo configurando",
|
||||||
"schange21": "Publicar Q-App",
|
"schange21": "Publicar Q-App",
|
||||||
@ -945,7 +947,17 @@
|
|||||||
"gchange56": "Nombre del grupo a buscar",
|
"gchange56": "Nombre del grupo a buscar",
|
||||||
"gchange57": "Nombre de grupo privado no encontrado",
|
"gchange57": "Nombre de grupo privado no encontrado",
|
||||||
"gchange58": "Tenga en cuenta que el nombre del grupo debe coincidir exactamente.",
|
"gchange58": "Tenga en cuenta que el nombre del grupo debe coincidir exactamente.",
|
||||||
"gchange59": "Mostrar/ocultar teletipo"
|
"gchange59": "Mostrar/ocultar teletipo",
|
||||||
|
"gchange60": "Por favor, introduzca el nombre del grupo",
|
||||||
|
"gchange61": "Por favor, introduzca la descripción",
|
||||||
|
"gchange62": "¿Estás seguro de ACTUALIZAR este grupo?",
|
||||||
|
"gchange63": "Al presionar CONFIRMAR, se enviará la solicitud UPDATE_GROUP.",
|
||||||
|
"gchange64": "Propietario actual / Nuevo propietario",
|
||||||
|
"gchange65": "¡Reemplace esta dirección para TRANSFERIR LA PROPIEDAD del grupo!",
|
||||||
|
"gchange66": "Propietario no válido / Dirección de nuevo propietario",
|
||||||
|
"gchange67": "¡Éxito de la ACTUALIZACIÓN del grupo!",
|
||||||
|
"gchange68": "Establecer avatar de grupo"
|
||||||
|
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Rompecabezas",
|
"pchange1": "Rompecabezas",
|
||||||
@ -1176,7 +1188,7 @@
|
|||||||
"inf7": "Información de compra automática",
|
"inf7": "Información de compra automática",
|
||||||
"inf8": "Cerrar información de compra automática",
|
"inf8": "Cerrar información de compra automática",
|
||||||
"inf9": "'Auto Buy' es una función que permite realizar 'órdenes de compra' en el Portal de comercio. Estas 'órdenes de compra' solo son visibles para la persona que las realiza. No son órdenes de compra 'públicas' como las Las 'ventas de mercado abierto' NO se almacenan en la cadena de bloques de Qortal. La compra automática es una característica de la interfaz de usuario y, como tal, requiere que la interfaz de usuario esté FUNCIONANDO.",
|
"inf9": "'Auto Buy' es una función que permite realizar 'órdenes de compra' en el Portal de comercio. Estas 'órdenes de compra' solo son visibles para la persona que las realiza. No son órdenes de compra 'públicas' como las Las 'ventas de mercado abierto' NO se almacenan en la cadena de bloques de Qortal. La compra automática es una característica de la interfaz de usuario y, como tal, requiere que la interfaz de usuario esté FUNCIONANDO.",
|
||||||
"inf10": "Para realizar un pedido de compra automática, haga clic en el botón 'Agregar pedido de compra automática' y complete el cuadro que aparece. Ingrese la CANTIDAD DE QORT que desea COMPRAR y el PRECIO al que desea COMPRAR. Una vez la orden está activa, Auto Buy comprará HASTA esa cantidad de QORT para usted, HASTA el precio que establezca (comenzando en la orden más baja y subiendo en los libros)",
|
"inf10": "Para realizar un pedido de Compra automática, haga clic en el botón 'Agregar pedido de Compra automática' y complete el cuadro que aparece. Ingrese la CANTIDAD DE QORT que desea COMPRAR o la cantidad de LTC que desea utilizar, y el PRECIO que desea COMPRAR HASTA. Una vez que la orden esté activa, Auto Buy comprará HASTA esa cantidad de QORT para usted, HASTA el precio que usted establezca (comenzando en la orden más baja y subiendo en los libros).",
|
||||||
"inf11": "¡Simplemente DEJE SU IU FUNCIONANDO y Auto Buy hace el resto, automáticamente!",
|
"inf11": "¡Simplemente DEJE SU IU FUNCIONANDO y Auto Buy hace el resto, automáticamente!",
|
||||||
"inf12": "PUEDE explorar otros complementos en la IU (Q-Chat, carteras, etc.) pero NO PUEDE CERRAR LA IU si desea que se complete su compra automática. Deje la IU 'minimizada' en la 'barra de tareas' o 'panel' está bien, mientras la interfaz de usuario permanezca ABIERTA, Auto Buy funcionará.",
|
"inf12": "PUEDE explorar otros complementos en la IU (Q-Chat, carteras, etc.) pero NO PUEDE CERRAR LA IU si desea que se complete su compra automática. Deje la IU 'minimizada' en la 'barra de tareas' o 'panel' está bien, mientras la interfaz de usuario permanezca ABIERTA, Auto Buy funcionará.",
|
||||||
"inf13": "Comprar automáticamente",
|
"inf13": "Comprar automáticamente",
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
"tm32": "See konto ei jälgi ühtegi kasutajat",
|
"tm32": "See konto ei jälgi ühtegi kasutajat",
|
||||||
"tm33": "Impordi vahekaardi menüü",
|
"tm33": "Impordi vahekaardi menüü",
|
||||||
"tm34": "Ekspordi vahekaardi menüü",
|
"tm34": "Ekspordi vahekaardi menüü",
|
||||||
"tm35": "Olemasolev vahekaardimenüü kustutatakse ja seatakse üleslaaditud vahekaardi menüüks.",
|
"tm35": "Teie olemasolev vahekaardimenüü kustutatakse ja seatakse imporditud vahekaardimenüüks.",
|
||||||
"tm36": "Vahekaardimenüü edukalt taastatud",
|
"tm36": "Vahekaardimenüü edukalt taastatud",
|
||||||
"tm37": "Vahekaardimenüü edukalt salvestatud nimega",
|
"tm37": "Vahekaardimenüü edukalt salvestatud nimega",
|
||||||
"tm38": "ARENDAJA REZHIIM",
|
"tm38": "ARENDAJA REZHIIM",
|
||||||
@ -96,44 +96,44 @@
|
|||||||
"address": "Aadress",
|
"address": "Aadress",
|
||||||
"password": "Salasõna",
|
"password": "Salasõna",
|
||||||
"youraccounts": "Sinu kontod",
|
"youraccounts": "Sinu kontod",
|
||||||
"clickto": "Klõpsa kontole sellega sisse logimiseks",
|
"clickto": "Sisselogimiseks klõpsake kontol",
|
||||||
"needcreate": "Pead looma või salvestama konto enne sisse logimist!",
|
"needcreate": "Pead looma või salvestama konto enne sisse logimist!",
|
||||||
"upload": "Laadi üles oma Qortal varukoopia",
|
"upload": "Importige oma Qortali varukoopiafail",
|
||||||
"howlogin": "Kuidas soovid sisse logida?",
|
"howlogin": "Kuidas soovid sisse logida?",
|
||||||
"seed": "Seemnefraas",
|
"seed": "Seemnefraas",
|
||||||
"seedphrase": "seemnefraas",
|
"seedphrase": "seemnefraas",
|
||||||
"saved": "Konto salvestatud",
|
"saved": "Konto salvestatud",
|
||||||
"qora": "Qora aadressi seeme",
|
"qora": "QORA aadressi seeme",
|
||||||
"backup": "Qortal rahakoti varukoopia",
|
"backup": "Qortal rahakoti varukoopiafail",
|
||||||
"decrypt": "Krüpti varukoopia lahti",
|
"decrypt": "Krüpti varukoopiafail ",
|
||||||
"save": "Salvesta selles sirvikus.",
|
"save": "Salvesta selles sirvikus.",
|
||||||
"prepare": "Konto ettevalmistus...",
|
"prepare": "Konto ettevalmistus...",
|
||||||
"areyousure": "Oled kindel, et soovid eemaldada seda rahakotti salvestatud rahakottide hulgast?",
|
"areyousure": "Kas olete kindel, et soovite selle rahakoti salvestatud rahakottide hulgast eemaldada? (Kui eemaldate ja varukoopiafaili pole, võib konto jäädavalt kaduda! Enne seda veenduge, et teil oleks varukoopiafail!)",
|
||||||
"error1": "Varukoopia peab olema korrektses JSON-formaadis",
|
"error1": "Varukoopiafail peab olema korrektses JSON-formaadis",
|
||||||
"error2": "Sisse logimise viis valimata",
|
"error2": "Sisse logimise viis valimata",
|
||||||
"createwelcome": "Tere tulemast Qortalisse! Sulle genereeritakse nüüd uus juhuslik seemnefraas, mida kasutatakse Sinu privaatvõtme ja aadressi loomiseks Qortali plokiahelasse. Lisaks, kui otsustad hakata ka Qortali platvormil nö. müntijaks, on Sul võimalus oma Qortali kontole saavutada kõrgem tase, mis toob Sulle suurema plokkide tasu QORT digimüntidena ning ka suurema hääletusmõjuvõimu Qortaliga seonduvate tulevikuotsuste osas.",
|
"createwelcome": "Tere tulemast Qortal! Teie detsentraliseeritud digitaalne tulevik ootab teid! Ainult teil on Qortalis täielik kontroll oma andmete üle. Qortal pakub uue ja täielikult kasutaja juhitava digitaalse maailma baastaseme.",
|
||||||
"createa": "",
|
"createa": "",
|
||||||
"click": "Klõpsa, et vaadata seemnefraasi",
|
"click": "Klõpsa, et vaadata seemnefraasi",
|
||||||
"confirmpass": "Kinnita salasõna",
|
"confirmpass": "Kinnita salasõna",
|
||||||
"willbe": "<- siit näed oma seemnefraasi.",
|
"willbe": "genereeritakse taustal juhuslikult. Kui soovite lähtelauset VAADATA, klõpsake selles tekstis esiletõstetud 'idufraasi'. Seda kasutatakse teie Qortali plokiahela konto privaatvõtme generaatorina. Turvalisuse huvides vaikimisi seemnefraase ei kuvata, välja arvatud juhul, kui see on spetsiaalselt valitud.",
|
||||||
"clicknext": "Qortal konto loomiseks klõpsa allpool olevat nuppu EDASI.",
|
"clicknext": "Qortal konto loomiseks klõpsa allpool olevat nuppu EDASI.",
|
||||||
"ready": "Konto on peaaegu valmis ja see salvestatakse siia keskkonda (Qortal UI sirvikusse). Kui Sa mingil põhjusel seda salvestada ei soovi, võid eemaldada allpool oleva märkeruudu. Oma uue kontoga saad ikkagi sisse logida (pärast välja logimist), kasutades oma konto rahakoti varukoopia faili, mis tuleb KINDLASTI arvutis kuhugi kausta salvestada peale konto loomist.",
|
"ready": "Teie konto on nüüd loomiseks valmis. See salvestatakse vaikimisi sellesse Qortali kasutajaliidese koopiasse krüpteeritud kujul. Kui te ei soovi, et teie uut kontot siia salvestataks, võite tühjendada alloleva kasti. Saate endiselt oma uue kontoga sisse logida (pärast väljalogimist), kasutades oma rahakoti varukoopiafaili, mille PEATE pärast konto loomist alla laadima.",
|
||||||
"welmessage": "Tere tulemast Qortalisse",
|
"welmessage": "Tere tulemast Qortalisse",
|
||||||
"pleaseenter": "Palun sisesta salasõna!",
|
"pleaseenter": "Palun sisesta salasõna!",
|
||||||
"notmatch": "Salasõnad ei kattu!",
|
"notmatch": "Oih! Paroolid ei kattu! Proovi uuesti!",
|
||||||
"lessthen8": "Salasõna on vähem kui 5 tähemärki! See ei ole turvakaalutlustel soovitatav, kuigi saab ka nii.",
|
"lessthen8": "Salasõna on vähem kui 5 tähemärki! See ei ole turvakaalutlustel soovitatav, kuigi saab ka nii.",
|
||||||
"lessthen8-2": "Salasõna on vähem kui 5 tähemärki!",
|
"lessthen8-2": "Salasõna on vähem kui 5 tähemärki!",
|
||||||
"entername": "Palun sisesta Nimi!",
|
"entername": "Palun sisestage kuvatav nimi!",
|
||||||
"Lae allaed": "Sinu rahakoti varukoopia laeti alla.",
|
"Lae allaed": "Teie Walleti varundusfail salvestati!",
|
||||||
"loading": "Laadib, palun oota...",
|
"loading": "Laadib, palun oota...",
|
||||||
"createdseed": "Sa lõid seemnefraasi",
|
"createdseed": "Sa lõid seemnefraasi",
|
||||||
"saveseed": "Salvesta seemnefraas",
|
"saveseed": "Salvesta seemnefraas",
|
||||||
"savein": "Salvesta sirvikusse",
|
"savein": "Salvesta sirvikusse",
|
||||||
"backup2": "Konto varukoopia fail on turvaliselt krüpteeritud, ja dekrüpteeritav Sinu poolt sisestatud salasõnaga, ning see fail on AINUS VIIS pääseda Sinu kontole ligi, kui kontot ei ole Qortal UI sirvikusse salvestatud. TEE SELLEST FAILIST VARUKOOPIA(D), et sa ei kaotaks oma kontole ligipääsu!",
|
"backup2": "See fail on AINUS viis (vaikimisi) oma kontole juurde pääseda, kui seda pole kasutajaliidesesse salvestatud. VARUNDAGE SEE FAIL KINDLASTI MITMES KOHTA. Fail krüpteeritakse väga turvaliselt ja dekrüpteeritakse teie eelmises etapis loodud kohaliku parooliga. Saate selle turvaliselt kõikjale salvestada, kuid tehke seda kindlasti mitmes kohas.",
|
||||||
"savewallet": "Salvesta rahakoti varukoopia fail",
|
"savewallet": "Salvesta rahakoti varukoopia fail",
|
||||||
"created1": "Sinu konto on nüüd loodud",
|
"created1": "Sinu konto on nüüd loodud",
|
||||||
"created2": " ja salvestatakse siinse arvuti sirvikus.",
|
"created2": " ja salvestatakse sellesse kasutajaliidesesse krüptitud kujul.",
|
||||||
"Lae allabackup": "Laadi rahakoti varukoopia fail alla",
|
"Lae allabackup": "Salvesta Walleti varufail",
|
||||||
"passwordhint": "Salasõna peab olema vähemalt 5 tähemärki.",
|
"passwordhint": "Salasõna peab olema vähemalt 5 tähemärki.",
|
||||||
"lp1": "Lukusta ekraan",
|
"lp1": "Lukusta ekraan",
|
||||||
"lp2": "Ekraaniluku salasõna pole seatud.",
|
"lp2": "Ekraaniluku salasõna pole seatud.",
|
||||||
@ -163,8 +163,8 @@
|
|||||||
"confirmlogout": "Kas soovid kindlasti välja logida?"
|
"confirmlogout": "Kas soovid kindlasti välja logida?"
|
||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "Vali fail",
|
"selectfile": "Valige varufail",
|
||||||
"dragfile": "või lohista varukoopia fail siia"
|
"dragfile": "Varundusfaili valimiseks lohistage või klõpsake siin"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "Üldine konto teave",
|
"generalinfo": "Üldine konto teave",
|
||||||
@ -181,7 +181,7 @@
|
|||||||
"notifications": "Teavitused",
|
"notifications": "Teavitused",
|
||||||
"accountsecurity": "Konto turvalisus",
|
"accountsecurity": "Konto turvalisus",
|
||||||
"password": "Salasõna",
|
"password": "Salasõna",
|
||||||
"Lae alla": "Laadi varukoopia fail alla",
|
"Lae alla": "Ekspordi/salvesta varukoopiafail",
|
||||||
"choose": "Palun vali salasõna, millega varukoopia krüpteerida. (See võib olla sama, millega sisse logisid, või erinev).",
|
"choose": "Palun vali salasõna, millega varukoopia krüpteerida. (See võib olla sama, millega sisse logisid, või erinev).",
|
||||||
"playsound": "Mängi heli",
|
"playsound": "Mängi heli",
|
||||||
"shownotifications": "Näita teavitusi",
|
"shownotifications": "Näita teavitusi",
|
||||||
@ -203,17 +203,17 @@
|
|||||||
"snack5": "Sõlmed edukalt imporditud",
|
"snack5": "Sõlmed edukalt imporditud",
|
||||||
"snack6": "Kohandatud sõlm on edukalt eemaldatud",
|
"snack6": "Kohandatud sõlm on edukalt eemaldatud",
|
||||||
"snack7": "Kohandatud sõlme edukalt redigeeritud",
|
"snack7": "Kohandatud sõlme edukalt redigeeritud",
|
||||||
"exp1": "Ekspordi privaatne üldvõti",
|
"exp1": "Ekspordi privaatne üldvõti (xpriv)",
|
||||||
"exp2": "Ekspordi üldvõti",
|
"exp2": "Ekspordi üldvõti",
|
||||||
"exp3": "Ekspordi",
|
"exp3": "Ekspordi",
|
||||||
"exp4": "Palun vali rahakott privaatse üldvõtme varundamiseks.",
|
"exp4": "Palun vali rahakott privaatse üldvõtme varundamiseks.",
|
||||||
"core": "Tuuma käivitamise seaded",
|
"core": "Qortal automaatse käivitamise seaded",
|
||||||
"qappNotification1": "Q-App märguanded",
|
"qappNotification1": "Q-App märguanded",
|
||||||
"selectnode": "Palun tehke valik",
|
"selectnode": "Palun tehke valik",
|
||||||
"arrr1": "ARRR rahakott pole initsialiseeritud!",
|
"arrr1": "ARRR rahakott pole initsialiseeritud!",
|
||||||
"arrr2": "Minge rahakoti vahekaardile ja lähtestage esmalt oma arrr rahakott.",
|
"arrr2": "Minge vahekaardile Rahakott ja avage esmalt ARRR-i rahakott, et rahakott lähtestada.",
|
||||||
"arrr3": "Vaja põhivärskendust!",
|
"arrr3": "Vaja põhivärskendust!",
|
||||||
"arrr4": "Oma arrr rahakoti privaatvõtme salvestamiseks vajate esmalt põhivärskendust!",
|
"arrr4": "ARRR-i rahakoti privaatvõtme salvestamiseks peate esmalt Qortal Core'i värskendama!",
|
||||||
"sync_indicator": "Keela sünkroonimisindikaatori hüpikaken"
|
"sync_indicator": "Keela sünkroonimisindikaatori hüpikaken"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
@ -230,8 +230,8 @@
|
|||||||
"wp1": "Mündimine",
|
"wp1": "Mündimine",
|
||||||
"wp2": "Ei vermita",
|
"wp2": "Ei vermita",
|
||||||
"wp3": "Põhiteave",
|
"wp3": "Põhiteave",
|
||||||
"wp4": "Sünkroonitud",
|
"wp4": "sünkroniseeritud",
|
||||||
"wp5": "Sünkroonimise olek"
|
"wp5": "Sünkroniseerimise olek"
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"yes": "Jah",
|
"yes": "Jah",
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "Saldo",
|
"balance": "Saldo",
|
||||||
"balances": "Sinu saldoseisud",
|
"balances": "Sinu saldoseisud",
|
||||||
"update": "Saldoseisude uuendamine",
|
"update": "Saldoseisude uuendamine",
|
||||||
"view": "Vaata"
|
"view": "Vaata",
|
||||||
|
"all": "Kõik",
|
||||||
|
"page": "Lehekülg"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Gif avastaja",
|
"gchange1": "Gif avastaja",
|
||||||
@ -284,14 +286,14 @@
|
|||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "Ei saa müntimise konto(de)le ligi",
|
"smchange1": "Ei saa müntimise konto(de)le ligi",
|
||||||
"smchange2": "Võtme eemaldamine ebaõnnestus",
|
"smchange2": "Võtme eemaldamine ebaõnnestus",
|
||||||
"smchange3": "Ebaõnnestus müntimise võtme lisamine",
|
"smchange3": "Võtme lisamine nurjus. Kui võti just loodi, oodake mõni plokk ja lisage uuesti",
|
||||||
"smchange4": "Ei saa luua sponsorluse võtit",
|
"smchange4": "Ei saa luua sponsorluse võtit",
|
||||||
"smchange5": "Suhte loomine",
|
"smchange5": "Suhte loomine",
|
||||||
"smchange6": "Ootab kinnitust plokiahelalt",
|
"smchange6": "Ootab kinnitust plokiahelalt",
|
||||||
"smchange7": "Suhte lõpetamine",
|
"smchange7": "Suhte lõpetamine",
|
||||||
"smchange8": "Müntimise võtme lisamine sõlme",
|
"smchange8": "Müntimise võtme lisamine sõlme",
|
||||||
"smchange9": "Valmis",
|
"smchange9": "Valmis",
|
||||||
"smchange10": "Ühe sõlme kohta on lubatud ainult 2 müntimisvõtit, aga Sina üritad määrata 3. Palun ava Haldus - Sõlme Haldamine ja eemaldage võti, mida Sa ei soovi sellele sõlmele määrata, tänud!"
|
"smchange10": "Ühe sõlme kohta on lubatud ainult 2 vermimisvõtit, proovite määrata 3 võtit. Minge sõlmede haldusse ja eemaldage kõik mittevajalikud võtmed, aitäh!"
|
||||||
},
|
},
|
||||||
"mintingpage": {
|
"mintingpage": {
|
||||||
"mchange1": "Üldised müntimise detailid",
|
"mchange1": "Üldised müntimise detailid",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "Müügihind",
|
"nchange23": "Müügihind",
|
||||||
"nchange24": "Müüdavaid Nimesid pole",
|
"nchange24": "Müüdavaid Nimesid pole",
|
||||||
"nchange25": "Müüa Nimi",
|
"nchange25": "Müüa Nimi",
|
||||||
"nchange26": "Kas oled kindel, et müüd selle Nime ära?",
|
"nchange26": "Kas olete kindel, et soovite selle nime müüa? Kui nime ostab keegi teine, ei ole varasema nimega avaldatud andmed teie kontrolli all!",
|
||||||
"nchange27": "Selle hinna eest (QORTis)",
|
"nchange27": "Selle hinna eest (QORTis)",
|
||||||
"nchange28": "Kui vajutad kinnita, saadetakse Nime müügitaotlus!",
|
"nchange28": "Kui vajutad kinnita, saadetakse Nime müügitaotlus!",
|
||||||
"nchange29": "Nimi tühistamiseks",
|
"nchange29": "Nimi tühistamiseks",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "Otsi grupi nime",
|
"gchange56": "Otsi grupi nime",
|
||||||
"gchange57": "Privaatgrupi nime ei leitud",
|
"gchange57": "Privaatgrupi nime ei leitud",
|
||||||
"gchange58": "Rühma nimi peab olema täpne vaste.",
|
"gchange58": "Rühma nimi peab olema täpne vaste.",
|
||||||
"gchange59": "Näita / Peida saldod"
|
"gchange59": "Näita / Peida saldod",
|
||||||
|
"gchange60": "Palun sisestage grupi nimi",
|
||||||
|
"gchange61": "Palun sisestage kirjeldus",
|
||||||
|
"gchange62": "Kas olete kindel, et värskendate seda rühma?",
|
||||||
|
"gchange63": "Vajutades KINNITA, saadetakse UPDATE_GROUP päring!",
|
||||||
|
"gchange64": "Praegune omanik / uus omanik",
|
||||||
|
"gchange65": "Asendage see aadress grupi omandiõiguse üleandmiseks!",
|
||||||
|
"gchange66": "Kehtetu omanik / uue omaniku aadress",
|
||||||
|
"gchange67": "Grupi UUENDAMINE edukas!",
|
||||||
|
"gchange68": "Rühma avatari määramine"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Puzzled",
|
"pchange1": "Puzzled",
|
||||||
@ -989,7 +1000,7 @@
|
|||||||
"nchange20": "Väljalaske versioon",
|
"nchange20": "Väljalaske versioon",
|
||||||
"nchange21": "Ühendatud",
|
"nchange21": "Ühendatud",
|
||||||
"nchange22": "Tegevus",
|
"nchange22": "Tegevus",
|
||||||
"nchange23": "Sünkroonimise sundimine",
|
"nchange23": "Sünkroniseerimise sundimine",
|
||||||
"nchange24": "Ühendatud partnereid pole",
|
"nchange24": "Ühendatud partnereid pole",
|
||||||
"nchange25": "Alustan sünki partneriga: ",
|
"nchange25": "Alustan sünki partneriga: ",
|
||||||
"nchange26": "Partner edukalt eemaldatud: ",
|
"nchange26": "Partner edukalt eemaldatud: ",
|
||||||
@ -1207,8 +1218,8 @@
|
|||||||
"notify1": "Tehingu kinnitamine",
|
"notify1": "Tehingu kinnitamine",
|
||||||
"notify2": "Tehing kinnitatud",
|
"notify2": "Tehing kinnitatud",
|
||||||
"explanation": "Sinu tehing kinnitatakse. Edenemise jälgimiseks klõpsa kellaikoonil.",
|
"explanation": "Sinu tehing kinnitatakse. Edenemise jälgimiseks klõpsa kellaikoonil.",
|
||||||
"status1": "Täielikult sünkroonitud",
|
"status1": "Täielikult sünkroniseeritud",
|
||||||
"status2": "Pole sünkroonitud",
|
"status2": "Pole sünkroniseeritud",
|
||||||
"notify3": "Märguandeid pole",
|
"notify3": "Märguandeid pole",
|
||||||
"notify4": "Tx-teatised"
|
"notify4": "Tx-teatised"
|
||||||
},
|
},
|
||||||
@ -1266,8 +1277,8 @@
|
|||||||
"profile26": "Lisa sõbraks"
|
"profile26": "Lisa sõbraks"
|
||||||
},
|
},
|
||||||
"tour": {
|
"tour": {
|
||||||
"tour1": "Qortali kasutamiseks peab Core olema sünkroonitud. See ikoon on sünkroonimisel sinine.",
|
"tour1": "Qortali kasutamiseks peab Core olema sünkroniseeritud. See ikoon on Sünkroniseerimisel sinine.",
|
||||||
"tour2": "Sünkroonitud",
|
"tour2": "sünkroniseeritud",
|
||||||
"tour3": "Sünkroonimine ja vermimine",
|
"tour3": "Sünkroonimine ja vermimine",
|
||||||
"tour4": "Sünkroonimine",
|
"tour4": "Sünkroonimine",
|
||||||
"tour5": "Sünkrooni oma tuum",
|
"tour5": "Sünkrooni oma tuum",
|
||||||
@ -1278,13 +1289,13 @@
|
|||||||
"tour10": "See on vahekaardi vaikevaade, kus pääsete juurde olulistele Qortali sätetele ja Q-rakendustele, nagu Q-Tube.",
|
"tour10": "See on vahekaardi vaikevaade, kus pääsete juurde olulistele Qortali sätetele ja Q-rakendustele, nagu Q-Tube.",
|
||||||
"tour11": "Saage täielik kogemus",
|
"tour11": "Saage täielik kogemus",
|
||||||
"tour12": "Qortali täieliku kogemuse saamiseks soovitame järgida seda kontroll-loendit.",
|
"tour12": "Qortali täieliku kogemuse saamiseks soovitame järgida seda kontroll-loendit.",
|
||||||
"tour13": "Olete täielikult sünkroonitud! Nüüd saate kogeda Qortali plokiahela võimsust.",
|
"tour13": "Olete täielikult sünkroniseeritud! Nüüd saate kogeda Qortali plokiahela võimsust.",
|
||||||
"tour14": "Proovime külastada Q-Tube'i!",
|
"tour14": "Proovime külastada Q-Tube'i!",
|
||||||
"tour15": "Külastage Q-Tube'i",
|
"tour15": "Külastage Q-Tube'i",
|
||||||
"tour16": "Kontrollnimekiri",
|
"tour16": "Kontrollnimekiri",
|
||||||
"tour17": "Qortali plokiahelale juurdepääsuks käivitage Core.",
|
"tour17": "Qortali plokiahelale juurdepääsuks käivitage Core.",
|
||||||
"tour18": "Värskenda (bootstrap)",
|
"tour18": "Värskenda (bootstrap)",
|
||||||
"tour19": "Praegu sünkroonimine... Qortali kasutamiseks peate olema täielikult sünkroonitud",
|
"tour19": "Praegu sünkroonimine... Qortali kasutamiseks peate olema täielikult sünkroniseeritud",
|
||||||
"tour20": "blokeerib taga. Kas soovite sünkroonimisprotsessi kiirendamiseks värskendada (bootstrap)?",
|
"tour20": "blokeerib taga. Kas soovite sünkroonimisprotsessi kiirendamiseks värskendada (bootstrap)?",
|
||||||
"tour21": "jäänud plokke.",
|
"tour21": "jäänud plokke.",
|
||||||
"tour22": "Taotleb värskendamist (bootstrap). Palun oodake."
|
"tour22": "Taotleb värskendamist (bootstrap). Palun oodake."
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
"mintingdetails": "LOUHINTA TIEDOT",
|
"mintingdetails": "LOUHINTA TIEDOT",
|
||||||
"becomeAMinter": "LIITY LOUHINTA",
|
"becomeAMinter": "LIITY LOUHINTA",
|
||||||
"wallets": "LOMPAKOT",
|
"wallets": "LOMPAKOT",
|
||||||
"tradeportal": "KAUPPA PORTAALI",
|
"tradeportal": "KRYPTOKAUPPAA",
|
||||||
"rewardshare": "PALKINTO JAKO",
|
"rewardshare": "PALKINTO JAKO",
|
||||||
"nameregistration": "NIMEN REKISTERÖINTI",
|
"nameregistration": "NIMEN REKISTERÖINTI",
|
||||||
"websites": "VERKKOSIVUSTOJA",
|
"websites": "VERKKOSIVUSTOJA",
|
||||||
@ -50,8 +50,8 @@
|
|||||||
"tm2": "Liity louhinta",
|
"tm2": "Liity louhinta",
|
||||||
"tm3": "Luettelo sponsoreista",
|
"tm3": "Luettelo sponsoreista",
|
||||||
"tm4": "Lompakot",
|
"tm4": "Lompakot",
|
||||||
"tm5": "Kaupan portaali",
|
"tm5": "Kryptokauppaa",
|
||||||
"tm6": "Automaattinen osto",
|
"tm6": "Automatisoidut kryptokaupat",
|
||||||
"tm7": "Palkinnon jako",
|
"tm7": "Palkinnon jako",
|
||||||
"tm8": "Q-Chat",
|
"tm8": "Q-Chat",
|
||||||
"tm9": "Nimen rekisteröinti",
|
"tm9": "Nimen rekisteröinti",
|
||||||
@ -103,38 +103,38 @@
|
|||||||
"seed": "Siemenlause",
|
"seed": "Siemenlause",
|
||||||
"seedphrase": "siemenlause",
|
"seedphrase": "siemenlause",
|
||||||
"saved": "Tili tallennettu",
|
"saved": "Tili tallennettu",
|
||||||
"qora": "Qora osoite siemen",
|
"qora": "QORA osoite siemen",
|
||||||
"backup": "Qortal lompakon varmuuskopio",
|
"backup": "Qortal lompakon varmuuskopio",
|
||||||
"decrypt": "Pura varmuuskopion salaus",
|
"decrypt": "Pura varmuuskopion salaus",
|
||||||
"save": "Tallenna tässä selaimessa.",
|
"save": "Tallenna tässä selaimessa.",
|
||||||
"prepare": "Tilin valmistelu...",
|
"prepare": "Tilin valmistelu...",
|
||||||
"areyousure": "Haluatko varmasti poistaa tämän lompakon tallennetuista lompakoistasi?",
|
"areyousure": "Haluatko varmasti poistaa tämän lompakon tallennetuista lompakoistasi? (Jos se poistetaan, eikä varmuuskopiotiedostoa ole, tili voi kadota lopullisesti! Varmista, että sinulla on varmuuskopiotiedosto ennen kuin teet tämän!)",
|
||||||
"error1": "Varmuuskopion on oltava oikeassa JSON-muodossa",
|
"error1": "Varmuuskopion on oltava oikeassa JSON-muodossa",
|
||||||
"error2": "Kirjautumistapaa ei ole valittu",
|
"error2": "Kirjautumistapaa ei ole valittu",
|
||||||
"createwelcome": "Tervetuloa Qortaliin! Sinulle luodaan nyt uusi satunnainen siemenlause, jota käytetään yksityisen avaimesi ja osoitteesi luomiseen Qortal-lohkoketjussa. Lisäksi, jos päätät aloittaa myös Qortal-alustalla, ts. kolikonlaskijana sinulla on mahdollisuus saavuttaa korkeampi taso Qortal-tililläsi, mikä tuo sinulle korkeamman lohkopalkkion QORT-digitaalisissa kolikoissa sekä suuremman äänivallan tulevissa Qortaliin liittyvissä päätöksissä.",
|
"createwelcome": "Tervetuloa Qortaliin! Hajautettu digitaalinen tulevaisuutesi odottaa sinua! Vain Qortalissa voit hallita tietojasi täydellisesti. Qortal tarjoaa perustason uudelle, täysin käyttäjän ohjaamalle digitaaliselle maailmalle.",
|
||||||
"createa": "luo",
|
"createa": "luo",
|
||||||
"click": "Klikkaa tästä, et tarkastella seemnefraasi",
|
"click": "Klikkaa tästä, et tarkastella seemnefraasi",
|
||||||
"confirmpass": "Vahvista salasana",
|
"confirmpass": "Vahvista salasana",
|
||||||
"willbe": "<- täällä näet siemenlauseesi.",
|
"willbe": "<- luodaan taustalla satunnaisesti. Jos haluat NÄYTÄ aloituslausetta, napsauta korostettua 'siemenlausetta' tässä tekstissä. Tätä käytetään yksityisen avaimen luojana lohkoketjutilillesi Qortalissa.. Oletusarvoisesti suojaussyistä alkulauseita ei näytetä, ellei niitä ole erikseen valittu.",
|
||||||
"clicknext": "Luo Qortal-tili napsauttamalla alla olevaa SEURAAVA-painiketta.",
|
"clicknext": "Luo Qortal-tili napsauttamalla alla olevaa SEURAAVA-painiketta.",
|
||||||
"ready": "Tili on melkein valmis ja tallennetaan tänne (Qortal UI -selaimeen). Jos et jostain syystä halua tallentaa sitä, voit poistaa alla olevan valintaruudun. Voit silti kirjautua sisään uudella tililläsi (uloskirjautumisen jälkeen) käyttämällä tilisi lompakkovarmuuskopiotiedostoa, joka TÄYTYY tilin luomisen jälkeen tallentaa johonkin kansioon tietokoneellesi.",
|
"ready": "Tili on melkein valmis ja tallennetaan tänne (Qortal UI). Jos et jostain syystä halua tallentaa sitä, voit poistaa alla olevan valintaruudun. Voit silti kirjautua sisään uudella tililläsi (uloskirjautumisen jälkeen) käyttämällä tilisi lompakkovarmuuskopiotiedostoa, joka TÄYTYY tilin luomisen jälkeen tallentaa johonkin kansioon tietokoneellesi.",
|
||||||
"welmessage": "Tervetuloa Qortaliin",
|
"welmessage": "Tervetuloa Qortaliin",
|
||||||
"pleaseenter": "Ole hyvä ja anna salasana!",
|
"pleaseenter": "Ole hyvä ja anna salasana!",
|
||||||
"notmatch": "Salasanat eivät täsmää!",
|
"notmatch": "Salasanat eivät täsmää!",
|
||||||
"lessthen8": "Salasana on alle 5 merkkiä pitkä! Tätä ei suositella turvallisuussyistä, vaikka se voidaan tehdä.",
|
"lessthen8": "Salasana on alle 5 merkkiä pitkä! Tätä ei suositella turvallisuussyistä, vaikka se voidaan tehdä.",
|
||||||
"lessthen8-2": "Salasana on alle 5 merkkiä pitkä!",
|
"lessthen8-2": "Salasana on alle 5 merkkiä pitkä!",
|
||||||
"entername": "Anna nimi!",
|
"entername": "Kirjoita näyttönimi",
|
||||||
"downloaded": "Lompakkosi varmuuskopio on ladattu.",
|
"downloaded": "Lompakkosi varmuuskopiotiedosto tallennettiin.",
|
||||||
"loading": "Ladataan, odota...",
|
"loading": "Ladataan, odota...",
|
||||||
"createdseed": "Loit alkulauseen",
|
"createdseed": "Loit alkulauseen",
|
||||||
"saveseed": "Tallenna siemenlause",
|
"saveseed": "Tallenna siemenlause",
|
||||||
"savein": "Tallenna selaimeen",
|
"savein": "Tallenna tässä Qortal-käyttöliittymässä",
|
||||||
"backup2": "Tilin varmuuskopiotiedosto on turvallisesti salattu ja sen salaus voidaan purkaa antamallasi salasanalla, ja tämä tiedosto on AINOA TAPA päästä tilillesi, jos tiliä ei ole tallennettu Qortal UI -selaimeen. TEE TÄSTÄ TIEDOSTOSTA VARMUUSKOPIO(T), jotta et menetä pääsyä tiliisi!",
|
"backup2": "Tilin varmuuskopiotiedosto on turvallisesti salattu ja sen salaus voidaan purkaa antamallasi salasanalla, ja tämä tiedosto on AINOA TAPA päästä tilillesi, jos tiliä ei ole tallennettu Qortal UI -selaimeen. TEE TÄSTÄ TIEDOSTOSTA VARMUUSKOPIO(T), jotta et menetä pääsyä tiliisi!",
|
||||||
"savewallet": "Tallenna lompakon varmuuskopiotiedosto",
|
"savewallet": "Tallenna lompakon varmuuskopiotiedosto",
|
||||||
"created1": "Tilisi on nyt luotu",
|
"created1": "Tilisi on nyt luotu",
|
||||||
"created2": " ja tallennettu tämän tietokoneen selaimeen.",
|
"created2": " ja tallennettu tähän käyttöliittymään salatussa muodossa",
|
||||||
"downloadbackup": "Lataa lompakon varmuuskopiotiedosto",
|
"downloadbackup": "Tallenna Qortal-varmuuskopiotiedosto",
|
||||||
"passwordhint": "Salasanan tulee olla vähintään 5 merkkiä pitkä.",
|
"passwordhint": "Salaussalasanassa on oltava vähintään 5 merkkiä",
|
||||||
"lp1": "Lukitse näyttö",
|
"lp1": "Lukitse näyttö",
|
||||||
"lp2": "Näytön lukituksen salasanaa ei ole asetettu.",
|
"lp2": "Näytön lukituksen salasanaa ei ole asetettu.",
|
||||||
"lp3": "Ole hyvä ja luo salasana tätä varten",
|
"lp3": "Ole hyvä ja luo salasana tätä varten",
|
||||||
@ -163,14 +163,14 @@
|
|||||||
"confirmlogout": "Haluatko varmasti kirjautua ulos?"
|
"confirmlogout": "Haluatko varmasti kirjautua ulos?"
|
||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "Valitse tiedosto",
|
"selectfile": "Valitse varmuuskopiotiedosto",
|
||||||
"dragfile": "tai vedä varmuuskopiotiedosto tähän"
|
"dragfile": "valitse napsauttamalla tai vedä varmuuskopiotiedosto tähän"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "Yleiset tilitiedot",
|
"generalinfo": "Yleiset tilitiedot",
|
||||||
"address": "Osoite",
|
"address": "Osoite",
|
||||||
"publickey": "Julkinen avain",
|
"publickey": "Julkinen avain",
|
||||||
"settings": "Asetukset",
|
"settings": "Solmun Asetukset",
|
||||||
"account": "Tili",
|
"account": "Tili",
|
||||||
"security": "Turvallisuus",
|
"security": "Turvallisuus",
|
||||||
"qr_login_menu_item": "QR-kirjautuminen",
|
"qr_login_menu_item": "QR-kirjautuminen",
|
||||||
@ -181,7 +181,7 @@
|
|||||||
"notifications": "Ilmoitukset",
|
"notifications": "Ilmoitukset",
|
||||||
"accountsecurity": "Tilin turvallisuus",
|
"accountsecurity": "Tilin turvallisuus",
|
||||||
"password": "Salasana",
|
"password": "Salasana",
|
||||||
"download": "Lataa varmuuskopiotiedosto",
|
"download": "Tallenna/vie varmuuskopiotiedosto",
|
||||||
"choose": "Valitse salasana salataksesi varmuuskopion. (Tämä voi olla sama kuin se, jolla kirjauduit sisään, tai eri).",
|
"choose": "Valitse salasana salataksesi varmuuskopion. (Tämä voi olla sama kuin se, jolla kirjauduit sisään, tai eri).",
|
||||||
"playsound": "Soita ääni",
|
"playsound": "Soita ääni",
|
||||||
"shownotifications": "Näytä ilmoitukset",
|
"shownotifications": "Näytä ilmoitukset",
|
||||||
@ -192,8 +192,8 @@
|
|||||||
"protocol": "Protokolla",
|
"protocol": "Protokolla",
|
||||||
"domain": "Verkkotunnus",
|
"domain": "Verkkotunnus",
|
||||||
"port": "Portti",
|
"port": "Portti",
|
||||||
"import": "Tuo solmut",
|
"import": "tuo tallennetut solmut",
|
||||||
"export": "Vie solmuja",
|
"export": "Vie tallennetut solmut",
|
||||||
"deletecustomnode": "Poista kaikki mukautetut solmut",
|
"deletecustomnode": "Poista kaikki mukautetut solmut",
|
||||||
"warning": "Sinun olemassa olevat solmut poistetaan ja palautetaan oletusasetuksiin.",
|
"warning": "Sinun olemassa olevat solmut poistetaan ja palautetaan oletusasetuksiin.",
|
||||||
"snack1": "Oletussolmujen poistaminen ja lisäys onnistui",
|
"snack1": "Oletussolmujen poistaminen ja lisäys onnistui",
|
||||||
@ -207,11 +207,11 @@
|
|||||||
"exp2": "Vie pääavain",
|
"exp2": "Vie pääavain",
|
||||||
"exp3": "Viedä",
|
"exp3": "Viedä",
|
||||||
"exp4": "Valitse lompakko varmuuskopioidaksesi yksityisen julkisen avaimesi.",
|
"exp4": "Valitse lompakko varmuuskopioidaksesi yksityisen julkisen avaimesi.",
|
||||||
"core": "Ytimen käynnistysasetukset",
|
"core": "Qortalin automaattisen käynnistysasetukset",
|
||||||
"qappNotification1": "Q-App-ilmoitukset",
|
"qappNotification1": "Q-App-ilmoitukset",
|
||||||
"selectnode": "Ole hyvä ja tee valinta",
|
"selectnode": "Ole hyvä ja tee valinta",
|
||||||
"arrr1": "ARRR-lompakkoa ei ole alustettu!",
|
"arrr1": "ARRR-lompakkoa ei ole alustettu!",
|
||||||
"arrr2": "Siirry lompakko-välilehdelle ja nollaa ensin ARRR-lompakkosi.",
|
"arrr2": "Siirry kohtaan 'lompakot' ja käytä ARRR-lompakkoa ensin",
|
||||||
"arrr3": "Tarvitaan iso päivitys!",
|
"arrr3": "Tarvitaan iso päivitys!",
|
||||||
"arrr4": "Jotta voit tallentaa ARRR-lompakkosi yksityisen avaimesi, tarvitset ensin pääpäivityksen!",
|
"arrr4": "Jotta voit tallentaa ARRR-lompakkosi yksityisen avaimesi, tarvitset ensin pääpäivityksen!",
|
||||||
"sync_indicator": "Poista synkronoinnin ilmaisimen ponnahdusikkuna"
|
"sync_indicator": "Poista synkronoinnin ilmaisimen ponnahdusikkuna"
|
||||||
@ -220,13 +220,13 @@
|
|||||||
"blockheight": "Lohkon korkeus",
|
"blockheight": "Lohkon korkeus",
|
||||||
"uiversion": "UI versio",
|
"uiversion": "UI versio",
|
||||||
"coreversion": "Ytimen versio",
|
"coreversion": "Ytimen versio",
|
||||||
"minting": "(Lohintaan)",
|
"minting": "(Louhintan)",
|
||||||
"synchronizing": "Synkronoidaan",
|
"synchronizing": "Synkronoidaan",
|
||||||
"peers": "Yhdistettyjä yhteistyökumppanit"
|
"peers": "Yhdistettyjä yhteistyökumppanit"
|
||||||
},
|
},
|
||||||
"walletprofile": {
|
"walletprofile": {
|
||||||
"minterlevel": "Louhinta taso",
|
"minterlevel": "Louhinta taso",
|
||||||
"blocksminted": "Lohkoiksi yhdessä",
|
"blocksminted": "Louhitut lohkot",
|
||||||
"wp1": "Louhinta",
|
"wp1": "Louhinta",
|
||||||
"wp2": "Louhinta ei toimi",
|
"wp2": "Louhinta ei toimi",
|
||||||
"wp3": "Perustiedot",
|
"wp3": "Perustiedot",
|
||||||
@ -234,12 +234,12 @@
|
|||||||
"wp5": "Synkronoinnin tila"
|
"wp5": "Synkronoinnin tila"
|
||||||
},
|
},
|
||||||
"general": {
|
"general": {
|
||||||
"yes": "Joo",
|
"yes": "Kyllä",
|
||||||
"no": "Ei",
|
"no": "Ei",
|
||||||
"confirm": "Vahvistaa",
|
"confirm": "Vahvistaa",
|
||||||
"decline": "Kieltäytyä",
|
"decline": "Kieltäytyä",
|
||||||
"open": "Avata",
|
"open": "Avata",
|
||||||
"close": "Kiinni",
|
"close": "Sulje",
|
||||||
"back": "Takaisin",
|
"back": "Takaisin",
|
||||||
"next": "Seuraava",
|
"next": "Seuraava",
|
||||||
"create": "Luoda",
|
"create": "Luoda",
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "Saldosi",
|
"balance": "Saldosi",
|
||||||
"balances": "Sinun saldosi",
|
"balances": "Sinun saldosi",
|
||||||
"update": "Saldot päivitetään",
|
"update": "Saldot päivitetään",
|
||||||
"view": "Katso"
|
"view": "Katso",
|
||||||
|
"all": "Kaikki",
|
||||||
|
"page": "Sivu"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Gif tutkija",
|
"gchange1": "Gif tutkija",
|
||||||
@ -311,15 +313,15 @@
|
|||||||
"mchange15": "Nykyinen tila",
|
"mchange15": "Nykyinen tila",
|
||||||
"mchange16": "Nykyinen taso",
|
"mchange16": "Nykyinen taso",
|
||||||
"mchange17": "Lohkoja puuttu pääsemäksi seuraavalle tasolle",
|
"mchange17": "Lohkoja puuttu pääsemäksi seuraavalle tasolle",
|
||||||
"mchange18": "Jos jatkat keksimistä 24/7, nouset tasolle",
|
"mchange18": "Jos jätkat louinta 24/7, nouset tasolle",
|
||||||
"mchange19": "Lohkontaan palkintojen tiedot",
|
"mchange19": "Lohkontaan palkintojen tiedot",
|
||||||
"mchange20": "Nykyinen taso",
|
"mchange20": "Nykyinen taso",
|
||||||
"mchange21": "Lohkijaita yhteensä tällä tasolla",
|
"mchange21": "Lohkijaita yhteensä tällä tasolla",
|
||||||
"mchange22": "Osa tasosta lohkoa kohti",
|
"mchange22": "Oletettav palkinto päivässä",
|
||||||
"mchange23": "Keskimääräinen palkkio lohkoa kohti",
|
"mchange23": "Keskimääräinen palkkio lohkoa kohti",
|
||||||
"mchange24": "Odotettu palkinto päivässä",
|
"mchange24": "Odotettu palkinto päivässä",
|
||||||
"mchange25": "Sekuntia",
|
"mchange25": "Sekuntia",
|
||||||
"mchange26": "Blocks",
|
"mchange26": "Lohkot",
|
||||||
"mchange27": "Taso",
|
"mchange27": "Taso",
|
||||||
"mchange28": "Taso",
|
"mchange28": "Taso",
|
||||||
"mchange29": "päivä",
|
"mchange29": "päivä",
|
||||||
@ -347,7 +349,7 @@
|
|||||||
},
|
},
|
||||||
"walletpage": {
|
"walletpage": {
|
||||||
"wchange1": "Haetaan saldoa...",
|
"wchange1": "Haetaan saldoa...",
|
||||||
"wchange2": "Nykyinen lompakko",
|
"wchange2": "Päivitä lompakko",
|
||||||
"wchange3": "Kopioi lompakon osoite leikepöydälle",
|
"wchange3": "Kopioi lompakon osoite leikepöydälle",
|
||||||
"wchange4": "Osoite kopioitu leikepöydälle",
|
"wchange4": "Osoite kopioitu leikepöydälle",
|
||||||
"wchange5": "Tapahtuman tiedot",
|
"wchange5": "Tapahtuman tiedot",
|
||||||
@ -363,10 +365,10 @@
|
|||||||
"wchange15": "Tapahtuman allekirjoitus",
|
"wchange15": "Tapahtuman allekirjoitus",
|
||||||
"wchange16": "Tapahtuman hajautus",
|
"wchange16": "Tapahtuman hajautus",
|
||||||
"wchange17": "Lähetä",
|
"wchange17": "Lähetä",
|
||||||
"wchange18": "Alkaen",
|
"wchange18": "Osoitteesta",
|
||||||
"wchange19": "Saatavilla oleva saldo",
|
"wchange19": "Saatavilla oleva saldo",
|
||||||
"wchange20": "(osoitteeseen tai nimeen)",
|
"wchange20": "(osoite tai nimi)",
|
||||||
"wchange21": "Nykyinen staattinen varaus:",
|
"wchange21": "Palvelumaksu:",
|
||||||
"wchange22": "Lompakot",
|
"wchange22": "Lompakot",
|
||||||
"wchange23": "(vastaanottajan osoite)",
|
"wchange23": "(vastaanottajan osoite)",
|
||||||
"wchange24": "Tarjouksen välitön maksu",
|
"wchange24": "Tarjouksen välitön maksu",
|
||||||
@ -385,14 +387,14 @@
|
|||||||
"wchange37": "Kokonaismäärä",
|
"wchange37": "Kokonaismäärä",
|
||||||
"wchange38": "Tässä osoitteessa ei ole tapahtumia.",
|
"wchange38": "Tässä osoitteessa ei ole tapahtumia.",
|
||||||
"wchange39": "Osotetta ei voi kopioida.",
|
"wchange39": "Osotetta ei voi kopioida.",
|
||||||
"wchange40": "PAYMENT",
|
"wchange40": "MAKSU",
|
||||||
"wchange41": "Tila",
|
"wchange41": "Tila",
|
||||||
"wchange42": "Vahvistukset",
|
"wchange42": "Vahvistukset",
|
||||||
"wchange43": "Tapahtuma ei näy ennen vahvistusta, ole kärsivällinen...",
|
"wchange43": "Tapahtuma ei näy ennen vahvistusta, ole kärsivällinen...",
|
||||||
"wchange44": "Yritä uudelleen...",
|
"wchange44": "Yritä uudelleen...",
|
||||||
"wchange45": "Lähetä kaikki",
|
"wchange45": "Lähetä kaikki",
|
||||||
"wchange46": "Lähetä tähän osoitteeseen",
|
"wchange46": "Lähetä tähän osoitteeseen",
|
||||||
"wchange47": "Osoitekirja",
|
"wchange47": "Vastaanottajat",
|
||||||
"wchange48": "Tämä osoitekirja on tyhjä!",
|
"wchange48": "Tämä osoitekirja on tyhjä!",
|
||||||
"wchange49": "Lisää osoitekirjaan",
|
"wchange49": "Lisää osoitekirjaan",
|
||||||
"wchange50": "Nimisolu ei voi olla tyhjä!",
|
"wchange50": "Nimisolu ei voi olla tyhjä!",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "Alennushinta",
|
"nchange23": "Alennushinta",
|
||||||
"nchange24": "Ei nimiä myytävänä",
|
"nchange24": "Ei nimiä myytävänä",
|
||||||
"nchange25": "Myynnin nimi",
|
"nchange25": "Myynnin nimi",
|
||||||
"nchange26": "Haluatko varmasti myydä tämän Nimen?",
|
"nchange26": "Oletko varma, että haluat myydä tämän nimen? Jos joku muu ostaa nimen, kaikki aikaisemmat nimitiedot eivät ole sinun hallinnassasi!",
|
||||||
"nchange27": "Tähän hintaan (QORT)",
|
"nchange27": "Tähän hintaan (QORT)",
|
||||||
"nchange28": "Jos painat Vahvista, Nimen myyntipyyntö lähetetään!",
|
"nchange28": "Jos painat Vahvista, Nimen myyntipyyntö lähetetään!",
|
||||||
"nchange29": "Nimen peruuttaminen",
|
"nchange29": "Nimen peruuttaminen",
|
||||||
@ -533,7 +535,7 @@
|
|||||||
},
|
},
|
||||||
"websitespage": {
|
"websitespage": {
|
||||||
"schange1": "Selaa verkkosivuja",
|
"schange1": "Selaa verkkosivuja",
|
||||||
"schange2": "Valvotut verkkosivustot",
|
"schange2": "Seuratut verkkosivustot",
|
||||||
"schange3": "Estetyt verkkosivustot",
|
"schange3": "Estetyt verkkosivustot",
|
||||||
"schange4": "Hae Web-sivuilta",
|
"schange4": "Hae Web-sivuilta",
|
||||||
"schange5": "Avatar",
|
"schange5": "Avatar",
|
||||||
@ -549,7 +551,7 @@
|
|||||||
"schange15": "Estetyt verkkosivustot",
|
"schange15": "Estetyt verkkosivustot",
|
||||||
"schange16": "Et ole estänyt yhtään verkkosivustoa",
|
"schange16": "Et ole estänyt yhtään verkkosivustoa",
|
||||||
"schange17": "Nimeä ei löydy!",
|
"schange17": "Nimeä ei löydy!",
|
||||||
"schange18": "Relay-tila on käytössä. Tämä tarkoittaa, että solmusi (tietokoneesi) auttaa siirtämään salattua dataa Qortal-verkossa, jos joku toinen solmu pyytää sitä. Jos haluat kytkeä sen pois päältä, sinun on kirjoitettava rivi, kuten Tämä",
|
"schange18": "Relay-tila on käytössä. Tämä tarkoittaa, että solmusi (tietokoneesi) auttaa siirtämään dataa Qortal-verkossa, jos joku toinen solmu pyytää sitä. Jos haluat kytkeä sen pois päältä, sinun on kirjoitettava rivi, kuten Tämä.",
|
||||||
"schange19": "määritystiedosto",
|
"schange19": "määritystiedosto",
|
||||||
"schange20": "Reletila on kytketty pois päältä. Jos haluat ottaa sen käyttöön, sinun on kirjoitettava tämä rivi",
|
"schange20": "Reletila on kytketty pois päältä. Jos haluat ottaa sen käyttöön, sinun on kirjoitettava tämä rivi",
|
||||||
"schange21": "Julkaise verkkosivusto",
|
"schange21": "Julkaise verkkosivusto",
|
||||||
@ -557,7 +559,7 @@
|
|||||||
"schange23": "Tämän nimen seuraamisen lopettamisessa tapahtui virhe. Yritä uudelleen!",
|
"schange23": "Tämän nimen seuraamisen lopettamisessa tapahtui virhe. Yritä uudelleen!",
|
||||||
"schange24": "Tapahtui virhe tämän nimen estämisessä. Yritä uudelleen!",
|
"schange24": "Tapahtui virhe tämän nimen estämisessä. Yritä uudelleen!",
|
||||||
"schange25": "Tapahtui virhe yritettäessä poistaa tämän nimen estoa. Yritä uudelleen!",
|
"schange25": "Tapahtui virhe yritettäessä poistaa tämän nimen estoa. Yritä uudelleen!",
|
||||||
"schange26": "Uncategorized",
|
"schange26": "Luokittelematon",
|
||||||
"schange27": "Koko",
|
"schange27": "Koko",
|
||||||
"schange28": "Tila",
|
"schange28": "Tila",
|
||||||
"schange29": "Seuraa",
|
"schange29": "Seuraa",
|
||||||
@ -594,7 +596,7 @@
|
|||||||
"schange23": "Tämän nimen seuraamisen lopettamisessa tapahtui virhe. Yritä uudelleen!",
|
"schange23": "Tämän nimen seuraamisen lopettamisessa tapahtui virhe. Yritä uudelleen!",
|
||||||
"schange24": "Tapahtui virhe tämän nimen estämisessä. Yritä uudelleen!",
|
"schange24": "Tapahtui virhe tämän nimen estämisessä. Yritä uudelleen!",
|
||||||
"schange25": "Tapahtui virhe yritettäessä poistaa tämän nimen estoa. Yritä uudelleen!",
|
"schange25": "Tapahtui virhe yritettäessä poistaa tämän nimen estoa. Yritä uudelleen!",
|
||||||
"schange26": "Uncategorized",
|
"schange26": "Luokittelematon",
|
||||||
"schange27": "Koko",
|
"schange27": "Koko",
|
||||||
"schange28": "Tila",
|
"schange28": "Tila",
|
||||||
"schange29": "Seuraa",
|
"schange29": "Seuraa",
|
||||||
@ -608,14 +610,14 @@
|
|||||||
"schange37": "Ladattu",
|
"schange37": "Ladattu",
|
||||||
"schange38": "Päivitä",
|
"schange38": "Päivitä",
|
||||||
"schange39": "Avaa",
|
"schange39": "Avaa",
|
||||||
"schange40": "Näyttö",
|
"schange40": "Esikatselu",
|
||||||
"schange41": "Ladataan, odota...",
|
"schange41": "Ladataan, odota...",
|
||||||
"schange42": "Lataukset",
|
"schange42": "Lataukset",
|
||||||
"schange43": "Kaikki latausyritykset jatkuvat taustalla, yritä hetken kuluttua uudelleen."
|
"schange43": "Kaikki latausyritykset jatkuvat taustalla, yritä hetken kuluttua uudelleen."
|
||||||
},
|
},
|
||||||
"tubespage": {
|
"tubespage": {
|
||||||
"schange1": "Selaa Q-Tubea",
|
"schange1": "Selaa Q-Tubea",
|
||||||
"schange2": "Tracked Q-Tubes",
|
"schange2": "Seurattu Q-Tubes",
|
||||||
"schange3": "Estetty Q-Tubes",
|
"schange3": "Estetty Q-Tubes",
|
||||||
"schange4": "Hae Q-Tubea",
|
"schange4": "Hae Q-Tubea",
|
||||||
"schange5": "Kansi",
|
"schange5": "Kansi",
|
||||||
@ -639,7 +641,7 @@
|
|||||||
"schange23": "Tämän nimen seuraamisen lopettamisessa tapahtui virhe. Yritä uudelleen!",
|
"schange23": "Tämän nimen seuraamisen lopettamisessa tapahtui virhe. Yritä uudelleen!",
|
||||||
"schange24": "Tapahtui virhe tämän nimen estämisessä. Yritä uudelleen!",
|
"schange24": "Tapahtui virhe tämän nimen estämisessä. Yritä uudelleen!",
|
||||||
"schange25": "Tapahtui virhe yritettäessä poistaa tämän nimen estoa. Yritä uudelleen!",
|
"schange25": "Tapahtui virhe yritettäessä poistaa tämän nimen estoa. Yritä uudelleen!",
|
||||||
"schange26": "Uncategorized",
|
"schange26": "Luokittelematon",
|
||||||
"schange27": "Koko",
|
"schange27": "Koko",
|
||||||
"schange28": "Tila",
|
"schange28": "Tila",
|
||||||
"schange29": "Seuraa",
|
"schange29": "Seuraa",
|
||||||
@ -666,7 +668,7 @@
|
|||||||
"pchange5": "Otsikko",
|
"pchange5": "Otsikko",
|
||||||
"pchange6": "Kuvaus",
|
"pchange6": "Kuvaus",
|
||||||
"pchange7": "Valitse luokka",
|
"pchange7": "Valitse luokka",
|
||||||
"pchange8": "Label",
|
"pchange8": "Tarra",
|
||||||
"pchange9": "Palvelu",
|
"pchange9": "Palvelu",
|
||||||
"pchange10": "Tunnus",
|
"pchange10": "Tunnus",
|
||||||
"pchange11": "Julkaise",
|
"pchange11": "Julkaise",
|
||||||
@ -804,7 +806,7 @@
|
|||||||
"cchange37": "Ei tuloksia löytynyt",
|
"cchange37": "Ei tuloksia löytynyt",
|
||||||
"cchange38": "Käyttäjä vahvistettu",
|
"cchange38": "Käyttäjä vahvistettu",
|
||||||
"cchange39": "Tälle käyttäjälle ei voida lähettää salattua viestiä, koska hänen julkinen avaimensa ei ole lohkoketjussa.",
|
"cchange39": "Tälle käyttäjälle ei voida lähettää salattua viestiä, koska hänen julkinen avaimensa ei ole lohkoketjussa.",
|
||||||
"cchange40": "PICTURE (näytä napsauttamalla)",
|
"cchange40": "KUVA (näytä napsauttamalla)",
|
||||||
"cchange41": "Saldosi on alle 4 QORT",
|
"cchange41": "Saldosi on alle 4 QORT",
|
||||||
"cchange42": "Roskapostin torjumiseksi kestää kauan lähettää viestejä Q-Chatissa, jos QORT-osoitteesi saldo on alle 4. Jos haluat nopeuttaa viestien lähetystä Q-Chatissa, hanki vähintään 4 QORT:t. Tämä voidaan tehdä kaupankäyntiportaalin tapahtumilla tai joku lähettää sinulle QORT:n. Jos osoitteessa on enemmän kuin 4 QORTia, Q-Chat-viestit ovat välittömiä. Kiitos, että ymmärrät tämän välttämättömän roskapostin estomenetelmän ja toivomme, että nautit Qortalista alusta!",
|
"cchange42": "Roskapostin torjumiseksi kestää kauan lähettää viestejä Q-Chatissa, jos QORT-osoitteesi saldo on alle 4. Jos haluat nopeuttaa viestien lähetystä Q-Chatissa, hanki vähintään 4 QORT:t. Tämä voidaan tehdä kaupankäyntiportaalin tapahtumilla tai joku lähettää sinulle QORT:n. Jos osoitteessa on enemmän kuin 4 QORTia, Q-Chat-viestit ovat välittömiä. Kiitos, että ymmärrät tämän välttämättömän roskapostin estomenetelmän ja toivomme, että nautit Qortalista alusta!",
|
||||||
"cchange43": "Jätä tippi (QORT)",
|
"cchange43": "Jätä tippi (QORT)",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "Hae ryhmän nimeä",
|
"gchange56": "Hae ryhmän nimeä",
|
||||||
"gchange57": "Yksityisen ryhmän nimeä ei löydy",
|
"gchange57": "Yksityisen ryhmän nimeä ei löydy",
|
||||||
"gchange58": "Ryhmän nimen on oltava täsmällinen.",
|
"gchange58": "Ryhmän nimen on oltava täsmällinen.",
|
||||||
"gchange59": "Näytä/piilota saldot"
|
"gchange59": "Näytä/piilota saldot",
|
||||||
|
"gchange60": "Anna ryhmän nimi",
|
||||||
|
"gchange61": "Anna kuvaus",
|
||||||
|
"gchange62": "Oletko varma, että päivität tämän ryhmän?",
|
||||||
|
"gchange63": "Kun painat vahvista, UPDATE_GROUP pyyntö lähetetään!",
|
||||||
|
"gchange64": "Nykyinen / uusi omistaja",
|
||||||
|
"gchange65": "Korvaa tämä osoite muotoon SIIRRÄ RYHMÄN OMISTAJUUS!",
|
||||||
|
"gchange66": "Virheellinen omistaja / uuden omistajan osoite",
|
||||||
|
"gchange67": "Ryhmän päivitys onnistui!",
|
||||||
|
"gchange68": "Aseta ryhmän avatar"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Palapelit",
|
"pchange1": "Palapelit",
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
"tm32": "Ce compte ne suit aucun utilisateur",
|
"tm32": "Ce compte ne suit aucun utilisateur",
|
||||||
"tm33": "Menu de l'onglet Importer",
|
"tm33": "Menu de l'onglet Importer",
|
||||||
"tm34": "Menu de l'onglet Exporter",
|
"tm34": "Menu de l'onglet Exporter",
|
||||||
"tm35": "Votre menu d'onglets existant sera supprimé et défini sur le menu d'onglets téléchargé.",
|
"tm35": "Votre nouvelle page à onglet existante sera supprimée et définie sur la nouvelle page à onglet importée.",
|
||||||
"tm36": "Le menu des onglets a été restauré avec succès",
|
"tm36": "Le menu des onglets a été restauré avec succès",
|
||||||
"tm37": "Le menu des onglets a été enregistré avec succès sous",
|
"tm37": "Le menu des onglets a été enregistré avec succès sous",
|
||||||
"tm38": "MODE DEV",
|
"tm38": "MODE DEV",
|
||||||
@ -96,45 +96,45 @@
|
|||||||
"address": "Adresse",
|
"address": "Adresse",
|
||||||
"password": "Mot de passe",
|
"password": "Mot de passe",
|
||||||
"youraccounts": "Vos comptes",
|
"youraccounts": "Vos comptes",
|
||||||
"clickto": "Cliquez sur votre compte pour vous connecter",
|
"clickto": "Cliquez sur compte pour vous connecter",
|
||||||
"needcreate": "Vous devez créer ou sauver un compte avant de pouvoir vous connecter!",
|
"needcreate": "Vous devez créer ou sauver un compte avant de pouvoir vous connecter!",
|
||||||
"upload": "Envoyer votre sauvegarde Qortal",
|
"upload": "Importez votre fichier de sauvegarde Qortal",
|
||||||
"howlogin": "Comment voulez-vous vous connecter ?",
|
"howlogin": "Comment voulez-vous vous connecter ?",
|
||||||
"seed": "Phrase mnémonique",
|
"seed": "Phrase mnémonique",
|
||||||
"seedphrase": "phrase mnémonique",
|
"seedphrase": "phrase mnémonique",
|
||||||
"saved": "Compte sauvegardé",
|
"saved": "Compte sauvegardé",
|
||||||
"qora": "Adresse de contrôle Qora",
|
"qora": "Graine d'adresse QORA",
|
||||||
"backup": "Sauvegarde du portefeuille Qortal",
|
"backup": "Fichier de Sauvegarde Qortal",
|
||||||
"decrypt": "Déchiffrer la sauvegarde",
|
"decrypt": "Décrypter le fichier de sauvegarde Qortal",
|
||||||
"save": "Sauvegarder dans ce navigateur.",
|
"save": "Sauvegarder dans ce navigateur.",
|
||||||
"prepare": "Préparation de votre compte",
|
"prepare": "Préparation de votre compte...",
|
||||||
"areyousure": "Êtes-vous sûr de vouloir retirer ce portefeuille des portefeuilles sauvegardés?",
|
"areyousure": "Etes-vous sûr de vouloir supprimer ce compte ? (S'il est supprimé et qu'aucune sauvegarde Qortal n'existe, le compte pourrait être perdu à jamais ! Assurez-vous d'avoir un fichier de sauvegarde avant de faire cela !)",
|
||||||
"error1": "La sauvegarde doit être un JSON valide",
|
"error1": "La sauvegarde doit être un JSON valide",
|
||||||
"error2": "Option de connexion non sélectionnée",
|
"error2": "Option de connexion non sélectionnée",
|
||||||
"createwelcome": "Bienvenue dans Qortal, vous trouverez des similitudes avec un jeu de rôle, où, vous, en tant que frappeur dans le réseau Qortal (si vous choisissez d'en devenir un), aurez la chance d'augmenter votre niveau, vous donnant à la fois une plus grande partie de la récompense de bloc QORT et une plus grande influence sur le réseau en termes de vote sur les décisions pour la plate-forme.",
|
"createwelcome": "Bienvenue à Qortal ! Votre avenir numérique décentralisé vous attend ! Sur Qortal, vous seul avez un contrôle absolu sur vos données. Qortal fournit le niveau de base d'un nouveau monde numérique entièrement contrôlé par l'utilisateur.",
|
||||||
"createa": "Une",
|
"createa": "Une",
|
||||||
"click": "Cliquez pour voir la phrase mnémonique",
|
"click": "Cliquez pour voir la phrase mnémonique",
|
||||||
"confirmpass": "Confirmez votre mot de passe",
|
"confirmpass": "Confirmez votre mot de passe",
|
||||||
"willbe": "sera généré au hasard en arrière-plan. Il sera utilisé comme votre générateur de clé privée pour votre compte blockchain dans Qortal.",
|
"willbe": "sera généré aléatoirement en arrière-plan. Si vous souhaitez VOIR la phrase de départ, cliquez sur la « phrase de départ » en surbrillance dans ce texte. Ceci est utilisé comme générateur de clé privée pour votre compte blockchain dans Qortal. Pour des raisons de sécurité, par défaut, les phrases de départ ne sont pas affichées à moins d'être spécifiquement choisies.",
|
||||||
"clicknext": "Créez votre compte Qortal en cliquant sur SUIVANT ci-dessous.",
|
"clicknext": "Créez votre compte Qortal en cliquant sur SUIVANT ci-dessous.",
|
||||||
"ready": "Votre compte est maintenant prêt à être créé. Il sera enregistré dans ce navigateur. Si vous ne souhaitez pas que votre nouveau compte soit enregistré dans votre navigateur, vous pouvez décocher la case ci-dessous. Vous serez toujours en mesure de vous connecter avec votre nouveau compte (après la déconnexion), en utilisant votre fichier de sauvegarde de portefeuille que vous DEVEZ télécharger une fois que vous créez votre compte.",
|
"ready": "Votre compte est maintenant prêt à être créé. Il sera enregistré par défaut dans cette copie de l'interface utilisateur de Qortal, sous forme cryptée. Si vous ne souhaitez pas que votre nouveau compte soit enregistré ici, vous pouvez décocher la case ci-dessous. Vous pourrez toujours vous connecter avec votre nouveau compte (après vous être déconnecté), en utilisant votre fichier de sauvegarde Qortal que vous DEVEZ télécharger une fois votre compte créé.",
|
||||||
"welmessage": "Bienvenue dans Qortal",
|
"welmessage": "Bienvenue dans Qortal",
|
||||||
"pleaseenter": "Veuillez entrer un mot de passe!",
|
"pleaseenter": "Veuillez entrer un mot de passe!",
|
||||||
"notmatch": "Les mots de passe ne correspondent pas!",
|
"notmatch": "Oops! Les mots de passe ne coïncident pas ! Essayer à nouveau!",
|
||||||
"lessthen8": "Votre mot de passe est inférieur à 5 caractères! Ceci n’est pas recommandé. Vous pouvez continuer en ignorant cet avertissement.",
|
"lessthen8": "Votre mot de passe est inférieur à 5 caractères! Ceci n’est pas recommandé. Vous pouvez continuer en ignorant cet avertissement.",
|
||||||
"lessthen8-2": "Votre mot de passe est inférieur à 5 caractères!",
|
"lessthen8-2": "Votre mot de passe est inférieur à 5 caractères!",
|
||||||
"entername": "Veuillez saisir un nom!",
|
"entername": "S'il vous plaît entrer un nom d'affichage!",
|
||||||
"downloaded": "Le fichier de sauvegarde de votre portefeuille va être téléchargé!",
|
"downloaded": "Votre fichier de compte Qortal a été enregistré!",
|
||||||
"loading": "Chargement en cours, veuillez patienter...",
|
"loading": "Chargement en cours, veuillez patienter...",
|
||||||
"createdseed": "Votre phrase mnémonique créee",
|
"createdseed": "Votre phrase mnémonique créee",
|
||||||
"saveseed": "Sauvegarder votre phrase mnémonique",
|
"saveseed": "Sauvegarder votre phrase mnémonique",
|
||||||
"savein": "Sauvegarder dans le navigateur",
|
"savein": "Enregistrer dans l'interface utilisateur",
|
||||||
"backup2": "Ce fichier est la SEULE façon d’accéder à votre compte sur un système qui ne l’a pas d'enregistré dans l’application ou le navigateur. ASSUREZ-VOUS DE SAUVEGARDER CE FICHIER À PLUSIEURS ENDROITS. Le fichier est chiffré de manière très sécurisée et déchiffré avec votre mot de passe local que vous avez créé à l’étape précédente. Vous pouvez l’enregistrer n’importe où en toute sécurité, mais assurez-vous de le faire à plusieurs endroits.",
|
"backup2": "Ce fichier est la SEULE façon d’accéder à votre compte sur un système qui ne l’a pas d'enregistré dans l’application ou le navigateur. ASSUREZ-VOUS DE SAUVEGARDER CE FICHIER À PLUSIEURS ENDROITS. Le fichier est chiffré de manière très sécurisée et déchiffré avec votre mot de passe local que vous avez créé à l’étape précédente. Vous pouvez l’enregistrer n’importe où en toute sécurité, mais assurez-vous de le faire à plusieurs endroits.",
|
||||||
"savewallet": "Sauvegarder le fichier de sauvegarde du portefeuille",
|
"savewallet": "Enregistrer le fichier de sauvegarde Qortal",
|
||||||
"created1": "Votre compte est maintenant créé",
|
"created1": "Votre compte est maintenant créé",
|
||||||
"created2": " et sera enregistré dans ce navigateur.",
|
"created2": " et enregistré dans cette interface utilisateur sous forme cryptée.",
|
||||||
"downloadbackup": "Télécharger le fichier de sauvegarde du portefeuille",
|
"downloadbackup": "Enregistrer le fichier de sauvegarde Qortal",
|
||||||
"passwordhint": "Un mot de passe doit comporter au moins 5 caractères.",
|
"passwordhint": "Le mot de passe doit comporter au moins 5 caractères.",
|
||||||
"lp1": "Verrouiller l'écran",
|
"lp1": "Verrouiller l'écran",
|
||||||
"lp2": "Aucun mot de passe d'écran de verrouillage n'est défini !",
|
"lp2": "Aucun mot de passe d'écran de verrouillage n'est défini !",
|
||||||
"lp3": "Veuillez en définir un",
|
"lp3": "Veuillez en définir un",
|
||||||
@ -163,8 +163,8 @@
|
|||||||
"confirmlogout": "Êtes-vous certain de vouloir vous déconnecter?"
|
"confirmlogout": "Êtes-vous certain de vouloir vous déconnecter?"
|
||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "Sélectionnez un fichier",
|
"selectfile": "Sélectionnez le fichier de sauvegarde",
|
||||||
"dragfile": "Glisser-déposer la sauvegarde ici"
|
"dragfile": "Glissez-déposez ou cliquez ici pour sélectionner le fichier de sauvegarde"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "Informations générales du compte",
|
"generalinfo": "Informations générales du compte",
|
||||||
@ -181,7 +181,7 @@
|
|||||||
"notifications": "Notifications",
|
"notifications": "Notifications",
|
||||||
"accountsecurity": "Sécurité du compte",
|
"accountsecurity": "Sécurité du compte",
|
||||||
"password": "Mot de passe",
|
"password": "Mot de passe",
|
||||||
"download": "Télécharger le fichier de sauvegarde",
|
"download": "Exporter/Enregistrer le fichier de sauvegarde",
|
||||||
"choose": "Veuillez choisir un mot de passe pour chiffrer votre sauvegarde. (Il peut s’agir du même mot de passe que celui avec lequel vous vous êtes connecté, ou différent)",
|
"choose": "Veuillez choisir un mot de passe pour chiffrer votre sauvegarde. (Il peut s’agir du même mot de passe que celui avec lequel vous vous êtes connecté, ou différent)",
|
||||||
"playsound": "Lire le son",
|
"playsound": "Lire le son",
|
||||||
"shownotifications": "Afficher les notifications",
|
"shownotifications": "Afficher les notifications",
|
||||||
@ -203,17 +203,17 @@
|
|||||||
"snack5": "Les noeuds ont été importés avec succès",
|
"snack5": "Les noeuds ont été importés avec succès",
|
||||||
"snack6": "Nœud personnalisé supprimé avec succès",
|
"snack6": "Nœud personnalisé supprimé avec succès",
|
||||||
"snack7": "Nœud personnalisé édité avec succès",
|
"snack7": "Nœud personnalisé édité avec succès",
|
||||||
"exp1": "Exporter la clé principale privée",
|
"exp1": "Exporter la clé privée principale (xpriv)",
|
||||||
"exp2": "Exporter la clé principale",
|
"exp2": "Exporter la clé principale",
|
||||||
"exp3": "Exporter",
|
"exp3": "Exporter",
|
||||||
"exp4": "Veuillez choisir un portefeuille pour sauvegarder la clé principale privée.",
|
"exp4": "Veuillez choisir un portefeuille pour sauvegarder la clé privée principale.",
|
||||||
"core": "Démarrer les paramètres du noyau",
|
"core": "Paramètres de démarrage automatique de Qortal Core",
|
||||||
"qappNotification1": "Notifications Q-App",
|
"qappNotification1": "Notifications Q-App",
|
||||||
"selectnode": "Veuillez sélectionner une option",
|
"selectnode": "Veuillez sélectionner une option",
|
||||||
"arrr1": "Portefeuille ARRR non initialisé !",
|
"arrr1": "Portefeuille ARRR non initialisé !",
|
||||||
"arrr2": "Veuillez aller dans l'onglet Portefeuille et initialiser d'abord votre portefeuille arrr.",
|
"arrr2": "Veuillez accéder à « Portefeuilles » et accéder au portefeuille ARRR pour initialiser d'abord le portefeuille.",
|
||||||
"arrr3": "Besoin d'une mise à jour principale !",
|
"arrr3": "Besoin d'une mise à jour principale !",
|
||||||
"arrr4": "Pour sauvegarder la clé privée de votre portefeuille arrr, vous avez d'abord besoin d'une mise à jour principale !",
|
"arrr4": "Pour sauvegarder la clé privée de votre portefeuille ARRR vous devez d'abord mettre à jour le Qortal Core!",
|
||||||
"sync_indicator": "Désactiver la fenêtre contextuelle de l'indicateur de synchronisation"
|
"sync_indicator": "Désactiver la fenêtre contextuelle de l'indicateur de synchronisation"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "Solde",
|
"balance": "Solde",
|
||||||
"balances": "VOS SOLDES DE PORTEFEUILLE",
|
"balances": "VOS SOLDES DE PORTEFEUILLE",
|
||||||
"update": "METTRE À JOUR LES SOLDES DES PORTEFEUILLES",
|
"update": "METTRE À JOUR LES SOLDES DES PORTEFEUILLES",
|
||||||
"view": "Voir"
|
"view": "Voir",
|
||||||
|
"all": "Tous",
|
||||||
|
"page": "Page"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Explorateur GIF",
|
"gchange1": "Explorateur GIF",
|
||||||
@ -284,7 +286,7 @@
|
|||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "Impossible de récupérer les comptes de frappe",
|
"smchange1": "Impossible de récupérer les comptes de frappe",
|
||||||
"smchange2": "Échec de la suppression de la clé",
|
"smchange2": "Échec de la suppression de la clé",
|
||||||
"smchange3": "Échec de l'ajout de la clé de frappe",
|
"smchange3": "Échec de l'ajout de la clé de frappe, si la clé vient d'être créée, essayez d'attendre quelques blocs et d'ajouter à nouveau.",
|
||||||
"smchange4": "Impossible de créer la clé de parrainage",
|
"smchange4": "Impossible de créer la clé de parrainage",
|
||||||
"smchange5": "Créer une relation",
|
"smchange5": "Créer une relation",
|
||||||
"smchange6": "En attente de confirmation sur blockchain",
|
"smchange6": "En attente de confirmation sur blockchain",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "Prix de vente",
|
"nchange23": "Prix de vente",
|
||||||
"nchange24": "Aucun nom à vendre",
|
"nchange24": "Aucun nom à vendre",
|
||||||
"nchange25": "Nom à vendre",
|
"nchange25": "Nom à vendre",
|
||||||
"nchange26": "Êtes-vous sûr de vendre ce nom ?",
|
"nchange26": "Êtes-vous sûr de vouloir vendre ce nom ? Si le nom est acheté par un autre compte, les données publiées par ce nom ne seront plus modifiables par vous !",
|
||||||
"nchange27": "Pour ce prix en QORT",
|
"nchange27": "Pour ce prix en QORT",
|
||||||
"nchange28": "En appuyant sur confirmer, la demande de nom de vente sera envoyée !",
|
"nchange28": "En appuyant sur confirmer, la demande de nom de vente sera envoyée !",
|
||||||
"nchange29": "Nom à annuler",
|
"nchange29": "Nom à annuler",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "Nom du groupe à rechercher",
|
"gchange56": "Nom du groupe à rechercher",
|
||||||
"gchange57": "Nom de groupe privé introuvable",
|
"gchange57": "Nom de groupe privé introuvable",
|
||||||
"gchange58": "Notez que le nom du groupe doit correspondre exactement.",
|
"gchange58": "Notez que le nom du groupe doit correspondre exactement.",
|
||||||
"gchange59": "Afficher / Masquer le téléscripteur"
|
"gchange59": "Afficher / Masquer le téléscripteur",
|
||||||
|
"gchange60": "Veuillez saisir le nom du groupe",
|
||||||
|
"gchange61": "Veuillez entrer la description",
|
||||||
|
"gchange62": "Êtes-vous sûr de mettre à jour ce groupe?",
|
||||||
|
"gchange63": "En appuyant sur CONFIRMER, la demande de UPDATE_GROUP sera envoyée !",
|
||||||
|
"gchange64": "Propriétaire actuel / Nouveau propriétaire",
|
||||||
|
"gchange65": "Remplacez cette adresse par TRANSFERT DE PROPRIÉTÉ du groupe !",
|
||||||
|
"gchange66": "Invalid Owner / New Owner Address",
|
||||||
|
"gchange67": "MISE À JOUR DE GROUPE réussie !",
|
||||||
|
"gchange68": "Définir l'avatar de groupe"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Puzzles",
|
"pchange1": "Puzzles",
|
||||||
|
@ -108,16 +108,16 @@
|
|||||||
"decrypt": "डिक्रिप्ट बैकअप",
|
"decrypt": "डिक्रिप्ट बैकअप",
|
||||||
"save": "इस ब्राउज़र में सेव करें.",
|
"save": "इस ब्राउज़र में सेव करें.",
|
||||||
"prepare": "आपका खाता तैयार करना",
|
"prepare": "आपका खाता तैयार करना",
|
||||||
"areyousure": "क्या आप वाकई इस वॉलेट को सहेजे गए वॉलेट से निकालना चाहते हैं?",
|
"areyousure": "क्या आप वाकई इस वॉलेट को सहेजे गए वॉलेट से निकालना चाहते हैं? (यदि हटा दिया गया है और कोई बैकअप फ़ाइल मौजूद नहीं है, तो खाता हमेशा के लिए खो सकता है! ऐसा करने से पहले सुनिश्चित करें कि आपके पास एक बैकअप फ़ाइल है!)",
|
||||||
"error1": "बैकअप मान्य जेसन होना चाहिए",
|
"error1": "बैकअप मान्य जेसन होना चाहिए",
|
||||||
"error2": "लॉगिन विकल्प नहीं चुना गया",
|
"error2": "लॉगिन विकल्प नहीं चुना गया",
|
||||||
"createwelcome": "क्वॉर्टल में आपका स्वागत है, आप इसे आरपीजी गेम के समान पाएंगे, आप, क्वॉर्टल नेटवर्क पर एक मिंटर के रूप में (यदि आप एक बनना चुनते हैं) आपके पास अपने खाते को समतल करने का मौका होगा, जिससे आप दोनों को और अधिक मिलेगा मंच के निर्णयों पर मतदान के संदर्भ में क्वॉर्ट ब्लॉक इनाम और नेटवर्क पर भी बड़ा प्रभाव है।",
|
"createwelcome": "क्वॉर्टल में आपका स्वागत है! आपका विकेन्द्रीकृत डिजिटल भविष्य आपका इंतजार कर रहा है! Qortal पर केवल आपका अपने डेटा पर पूर्ण नियंत्रण होता है। क्वॉर्टल एक नई और पूरी तरह से उपयोगकर्ता-नियंत्रित डिजिटल दुनिया का आधार स्तर प्रदान करता है।",
|
||||||
"createa": "ए",
|
"createa": "ए",
|
||||||
"click": "बीजवाक्य देखने के लिए क्लिक करें",
|
"click": "बीजवाक्य देखने के लिए क्लिक करें",
|
||||||
"confirmpass": "पासवर्ड की पुष्टि कीजिये",
|
"confirmpass": "पासवर्ड की पुष्टि कीजिये",
|
||||||
"willbe": "पृष्ठभूमि में बेतरतीब ढंग से उत्पन्न होगा। यह क्वॉर्टल में आपके ब्लॉकचेन खाते के लिए आपके निजी कुंजी जनरेटर के रूप में उपयोग किया जाता है।",
|
"willbe": "पृष्ठभूमि में बेतरतीब ढंग से उत्पन्न किया जाएगा. यदि आप सीडफ़्रेज़ देखना चाहते हैं, तो इस पाठ में हाइलाइट किए गए 'सीडफ़्रेज़' पर क्लिक करें। इसका उपयोग Qortal में आपके ब्लॉकचेन खाते के लिए आपके निजी कुंजी जनरेटर के रूप में किया जाता है। डिफ़ॉल्ट रूप से सुरक्षा के लिए, सीडफ़्रेज़ प्रदर्शित नहीं किए जाते हैं जब तक कि विशेष रूप से चुना न जाए।",
|
||||||
"clicknext": "नीचे अगला पर क्लिक करके अपना क्वॉर्टल अकाउंट बनाएं।",
|
"clicknext": "नीचे अगला पर क्लिक करके अपना क्वॉर्टल अकाउंट बनाएं।",
|
||||||
"ready": "आपका खाता अब बनने के लिए तैयार है। यह इस ब्राउज़र में सेव हो जाएगा। यदि आप नहीं चाहते कि आपका नया खाता आपके ब्राउज़र में सहेजा जाए, तो आप नीचे दिए गए बॉक्स को अनचेक कर सकते हैं। आप अभी भी अपने वॉलेट बैकअप फ़ाइल का उपयोग करके अपने नए खाते (लॉग आउट करने के बाद) के साथ लॉगिन करने में सक्षम होंगे, जिसे आपको अपना खाता बनाने के बाद डाउनलोड करना होगा।",
|
"ready": "अब आपका अकाउंट बनने के लिए तैयार है. इसे डिफ़ॉल्ट रूप से, एन्क्रिप्टेड रूप में, Qortal UI की इस प्रति में सहेजा जाएगा। यदि आप नहीं चाहते कि आपका नया खाता यहां सहेजा जाए, तो आप नीचे दिए गए बॉक्स को अनचेक कर सकते हैं। आप अभी भी अपने वॉलेट बैकअप फ़ाइल का उपयोग करके अपने नए खाते से (लॉग आउट करने के बाद) लॉग इन कर पाएंगे, जिसे आपको अपना खाता बनाने के बाद डाउनलोड करना होगा।",
|
||||||
"welmessage": "क्वॉर्टल में आपका स्वागत है",
|
"welmessage": "क्वॉर्टल में आपका स्वागत है",
|
||||||
"pleaseenter": "कृपया पासवर्ड दर्ज करें!",
|
"pleaseenter": "कृपया पासवर्ड दर्ज करें!",
|
||||||
"notmatch": "पासवर्ड मेल नहीं खाता!",
|
"notmatch": "पासवर्ड मेल नहीं खाता!",
|
||||||
@ -128,7 +128,7 @@
|
|||||||
"loading": "लोड हो रहा है कृपया प्रतीक्षा करें...",
|
"loading": "लोड हो रहा है कृपया प्रतीक्षा करें...",
|
||||||
"createdseed": "आपका बनाएँ बीज वाक्यांश",
|
"createdseed": "आपका बनाएँ बीज वाक्यांश",
|
||||||
"saveseed": "सीडफ़्रेज़ सहेजें",
|
"saveseed": "सीडफ़्रेज़ सहेजें",
|
||||||
"savein": "ब्राउज़र में सहेजें",
|
"savein": "इस यूआई में सहेजें",
|
||||||
"backup2": "यह फ़ाइल किसी ऐसे सिस्टम पर आपके खाते तक पहुँचने का एकमात्र तरीका है, जिसमें इसे ऐप/ब्राउज़र में सहेजा नहीं गया है। इस फ़ाइल का कई स्थानों पर बैकअप लेना सुनिश्चित करें। फ़ाइल बहुत सुरक्षित रूप से एन्क्रिप्ट की गई है और पिछले चरण में आपके द्वारा बनाए गए आपके स्थानीय पासवर्ड से डिक्रिप्ट की गई है। आप इसे कहीं भी सुरक्षित रूप से सहेज सकते हैं, लेकिन इसे कई स्थानों पर करना सुनिश्चित करें।",
|
"backup2": "यह फ़ाइल किसी ऐसे सिस्टम पर आपके खाते तक पहुँचने का एकमात्र तरीका है, जिसमें इसे ऐप/ब्राउज़र में सहेजा नहीं गया है। इस फ़ाइल का कई स्थानों पर बैकअप लेना सुनिश्चित करें। फ़ाइल बहुत सुरक्षित रूप से एन्क्रिप्ट की गई है और पिछले चरण में आपके द्वारा बनाए गए आपके स्थानीय पासवर्ड से डिक्रिप्ट की गई है। आप इसे कहीं भी सुरक्षित रूप से सहेज सकते हैं, लेकिन इसे कई स्थानों पर करना सुनिश्चित करें।",
|
||||||
"savewallet": "वॉलेट बैकअप फ़ाइल सहेजें",
|
"savewallet": "वॉलेट बैकअप फ़ाइल सहेजें",
|
||||||
"created1": "आपका खाता अब निर्मित हो गया है",
|
"created1": "आपका खाता अब निर्मित हो गया है",
|
||||||
@ -164,7 +164,7 @@
|
|||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "फ़ाइल का चयन करें",
|
"selectfile": "फ़ाइल का चयन करें",
|
||||||
"dragfile": "बैकअप को यहां खींचें और छोड़ें"
|
"dragfile": "बैकअप फ़ाइल का चयन करने के लिए खींचें और छोड़ें या यहां क्लिक करें"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "सामान्य खाता जानकारी",
|
"generalinfo": "सामान्य खाता जानकारी",
|
||||||
@ -181,7 +181,7 @@
|
|||||||
"qr_login_button_2": "लॉगिन क्यूआर कोड जनरेट करें",
|
"qr_login_button_2": "लॉगिन क्यूआर कोड जनरेट करें",
|
||||||
"accountsecurity": "खाते की सुरक्षा",
|
"accountsecurity": "खाते की सुरक्षा",
|
||||||
"password": "पासवर्ड",
|
"password": "पासवर्ड",
|
||||||
"download": "बैकअप फ़ाइल डाउनलोड करें",
|
"download": "बैकअप फ़ाइल निर्यात/सहेजें",
|
||||||
"choose": "कृपया अपने बैकअप को एन्क्रिप्ट करने के लिए पासवर्ड चुनें। (यह वही हो सकता है जैसा आपने एक लॉग इन किया है, या अलग)",
|
"choose": "कृपया अपने बैकअप को एन्क्रिप्ट करने के लिए पासवर्ड चुनें। (यह वही हो सकता है जैसा आपने एक लॉग इन किया है, या अलग)",
|
||||||
"playsound": "ध्वनि चलाएं",
|
"playsound": "ध्वनि चलाएं",
|
||||||
"shownotifications": "सूचनाएं दिखाएं",
|
"shownotifications": "सूचनाएं दिखाएं",
|
||||||
@ -192,8 +192,8 @@
|
|||||||
"protocol": "परोटोकोल",
|
"protocol": "परोटोकोल",
|
||||||
"domain": "डोमेन",
|
"domain": "डोमेन",
|
||||||
"port": "पोर्ट",
|
"port": "पोर्ट",
|
||||||
"import": "आयात नोड्स",
|
"import": "सहेजे गए नोड्स आयात करें",
|
||||||
"export": "निर्यात नोड्स",
|
"export": "सहेजे गए नोड्स निर्यात करें",
|
||||||
"deletecustomnode": "सभी कस्टम नोड्स निकालें",
|
"deletecustomnode": "सभी कस्टम नोड्स निकालें",
|
||||||
"warning": "आपके मौजूदा नोड्स हटा दिए जाएंगे और बैकअप से नया बनाया जाएगा।",
|
"warning": "आपके मौजूदा नोड्स हटा दिए जाएंगे और बैकअप से नया बनाया जाएगा।",
|
||||||
"snack1": "मानक नोड्स को सफलतापूर्वक हटा दिया गया और जोड़ा गया",
|
"snack1": "मानक नोड्स को सफलतापूर्वक हटा दिया गया और जोड़ा गया",
|
||||||
@ -203,15 +203,15 @@
|
|||||||
"snack5": "नोड्स सफलतापूर्वक आयात किए गए",
|
"snack5": "नोड्स सफलतापूर्वक आयात किए गए",
|
||||||
"snack6": "कस्टम नोड सफलतापूर्वक हटा दिया गया",
|
"snack6": "कस्टम नोड सफलतापूर्वक हटा दिया गया",
|
||||||
"snack7": "कस्टम नोड सफलतापूर्वक संपादित",
|
"snack7": "कस्टम नोड सफलतापूर्वक संपादित",
|
||||||
"exp1": "निजी मास्टर कुंजी निर्यात करें",
|
"exp1": "निजी मास्टर कुंजी निर्यात करें (xpriv)",
|
||||||
"exp2": "निर्यात मास्टर कुंजी",
|
"exp2": "निर्यात मास्टर कुंजी",
|
||||||
"exp3": "निर्यात",
|
"exp3": "निर्यात",
|
||||||
"exp4": "निजी मास्टर कुंजी का बैकअप लेने के लिए कृपया एक वॉलेट चुनें।",
|
"exp4": "निजी मास्टर कुंजी का बैकअप लेने के लिए कृपया एक वॉलेट चुनें।",
|
||||||
"core": "कोर सेटिंग प्रारंभ करें",
|
"core": "कोर ऑटो-स्टार्ट सेटिंग्स",
|
||||||
"qappNotification1": "क्यू-ऐप अधिसूचनाएँ",
|
"qappNotification1": "क्यू-ऐप अधिसूचनाएँ",
|
||||||
"selectnode": "कृपया एक विकल्प चुनें",
|
"selectnode": "कृपया एक विकल्प चुनें",
|
||||||
"arrr1": "ARRR वॉलेट प्रारंभ नहीं हुआ!",
|
"arrr1": "ARRR वॉलेट प्रारंभ नहीं हुआ!",
|
||||||
"arrr2": "कृपया वॉलेट टैब पर जाएं और पहले अपना Arrr वॉलेट प्रारंभ करें।",
|
"arrr2": "कृपया पहले वॉलेट प्रारंभ करने के लिए वॉलेट टैब पर जाएं और ARRR वॉलेट तक पहुंचें",
|
||||||
"arrr3": "मुख्य अद्यतन की आवश्यकता है!",
|
"arrr3": "मुख्य अद्यतन की आवश्यकता है!",
|
||||||
"arrr4": "अपने Arrr वॉलेट की निजी कुंजी को सहेजने के लिए आपको पहले एक कोर अपडेट की आवश्यकता है!",
|
"arrr4": "अपने Arrr वॉलेट की निजी कुंजी को सहेजने के लिए आपको पहले एक कोर अपडेट की आवश्यकता है!",
|
||||||
"sync_indicator": "सिंक संकेतक पॉपअप अक्षम करें"
|
"sync_indicator": "सिंक संकेतक पॉपअप अक्षम करें"
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "संतुलन",
|
"balance": "संतुलन",
|
||||||
"balances": "आपका वॉलेट बैलेंस",
|
"balances": "आपका वॉलेट बैलेंस",
|
||||||
"update": "अपडेट वॉलेट बैलेंस",
|
"update": "अपडेट वॉलेट बैलेंस",
|
||||||
"view": "देखना"
|
"view": "देखना",
|
||||||
|
"all": "सभी",
|
||||||
|
"page": "पृष्ठ"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "जीआईएफ एक्सप्लोरर",
|
"gchange1": "जीआईएफ एक्सप्लोरर",
|
||||||
@ -284,7 +286,7 @@
|
|||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "खनन खाते नहीं लाए जा सकते",
|
"smchange1": "खनन खाते नहीं लाए जा सकते",
|
||||||
"smchange2": "कुंजी निकालने में विफल",
|
"smchange2": "कुंजी निकालने में विफल",
|
||||||
"smchange3": "मिंटिंग की जोड़ने में विफल",
|
"smchange3": "मिंटिंग कुंजी जोड़ने में विफल, यदि कुंजी अभी-अभी बनाई गई है तो कुछ ब्लॉक प्रतीक्षा करके पुनः जोड़ने का प्रयास करें",
|
||||||
"smchange4": "प्रायोजन कुंजी नहीं बना सकता",
|
"smchange4": "प्रायोजन कुंजी नहीं बना सकता",
|
||||||
"smchange5": "संबंध बनाना",
|
"smchange5": "संबंध बनाना",
|
||||||
"smchange6": "ब्लॉकचेन पर पुष्टि की प्रतीक्षा में",
|
"smchange6": "ब्लॉकचेन पर पुष्टि की प्रतीक्षा में",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "मूल्य बेचें",
|
"nchange23": "मूल्य बेचें",
|
||||||
"nchange24": "बिक्री के लिए कोई नाम नहीं",
|
"nchange24": "बिक्री के लिए कोई नाम नहीं",
|
||||||
"nchange25": "बेचने के लिए नाम",
|
"nchange25": "बेचने के लिए नाम",
|
||||||
"nchange26": "क्या आप वाकई इस नाम को बेचना चाहते हैं?",
|
"nchange26": "क्या आप वाकई यह नाम बेचना चाहते हैं? यदि नाम किसी अन्य खाते से खरीदा जाता है तो यह आपके नियंत्रण से बाहर हो जाएगा!",
|
||||||
"nchange27": "QORT में इस कीमत के लिए",
|
"nchange27": "QORT में इस कीमत के लिए",
|
||||||
"nchange28": "पुष्टि करें दबाने पर, विक्रय नाम अनुरोध भेजा जाएगा!",
|
"nchange28": "पुष्टि करें दबाने पर, विक्रय नाम अनुरोध भेजा जाएगा!",
|
||||||
"nchange29": "रद्द करने के लिए नाम",
|
"nchange29": "रद्द करने के लिए नाम",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "खोजने के लिए समूह का नाम",
|
"gchange56": "खोजने के लिए समूह का नाम",
|
||||||
"gchange57": "निजी समूह का नाम नहीं मिला",
|
"gchange57": "निजी समूह का नाम नहीं मिला",
|
||||||
"gchange58": "ध्यान दें कि समूह का नाम सटीक मेल खाना चाहिए।",
|
"gchange58": "ध्यान दें कि समूह का नाम सटीक मेल खाना चाहिए।",
|
||||||
"gchange59": "टिकर दिखाएं / छुपाएं"
|
"gchange59": "टिकर दिखाएं / छुपाएं",
|
||||||
|
"gchange60": "कृपया समूह का नाम दर्ज करें",
|
||||||
|
"gchange61": "कृपया विवरण दर्ज करें",
|
||||||
|
"gchange62": "क्या आप इस समूह को अपडेट करने के लिए सुनिश्चित हैं?",
|
||||||
|
"gchange63": "पुष्टि करने पर UPDATE_GROUP अनुरोध भेजा जाएगा!",
|
||||||
|
"gchange64": "वर्तमान मालिक /",
|
||||||
|
"gchange65": "इस पते को समूह के स्थानांतरण स्वामित्व में बदलें!",
|
||||||
|
"gchange66": "अमान्य मालिक/नए मालिक का पता",
|
||||||
|
"gchange67": "समूह अद्यतन सफल!",
|
||||||
|
"gchange68": "समूह अवतार सेट करें"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "पहेलि",
|
"pchange1": "पहेलि",
|
||||||
|
@ -96,28 +96,28 @@
|
|||||||
"address": "Adresa",
|
"address": "Adresa",
|
||||||
"password": "Lozinka",
|
"password": "Lozinka",
|
||||||
"youraccounts": "Tvoji računi",
|
"youraccounts": "Tvoji računi",
|
||||||
"clickto": "Kliknite svoj račun da biste se prijavili s njim",
|
"clickto": "Pritisnite račun za prijavu",
|
||||||
"needcreate": "Morate stvoriti ili spremiti račun prije nego što se možete prijaviti!",
|
"needcreate": "Morate stvoriti ili spremiti račun prije nego što se možete prijaviti!",
|
||||||
"upload": "Prenesite Qortal sigurnosnu kopiju",
|
"upload": "Uvezite datoteku sigurnosne kopije Qortal",
|
||||||
"howlogin": "Kako biste se željeli prijaviti?",
|
"howlogin": "Kako biste se željeli prijaviti?",
|
||||||
"seed": "Seed fraza",
|
"seed": "Seed fraza",
|
||||||
"seedphrase": "seedphrase",
|
"seedphrase": "seedphrase",
|
||||||
"saved": "Sačuvani račun",
|
"saved": "Sačuvani račun",
|
||||||
"qora": "Qora Adresa Seed",
|
"qora": "QORA Adresa Seed",
|
||||||
"backup": "Qortal sigurnosna kopija novčanika",
|
"backup": "Qortal backup datoteka",
|
||||||
"decrypt": "Decrypt sigurnosna kopija",
|
"decrypt": "Dešifrirajte datoteku sigurnosne kopije",
|
||||||
"save": "Spremite u ovom pregledniku",
|
"save": "Spremite u ovom pregledniku",
|
||||||
"prepare": "Pripremite vaš račun",
|
"prepare": "Pripremite vaš račun",
|
||||||
"areyousure": "Jeste li sigurni da želite ukloniti ovaj novčanik od spremljenih novčanika?",
|
"areyousure": "Jeste li sigurni da želite ukloniti ovaj novčanik iz spremljenih novčanika? (Ako se ukloni, a ne postoji datoteka sigurnosne kopije, račun bi mogao biti zauvijek izgubljen! Provjerite imate li datoteku sigurnosne kopije prije nego to učinite!)",
|
||||||
"error1": "Sigurnosna kopija mora biti valjan JSON",
|
"error1": "Sigurnosna kopija mora biti valjan JSON",
|
||||||
"error2": "Opcija prijave nije odabrana",
|
"error2": "Opcija prijave nije odabrana",
|
||||||
"createwelcome": "Dobro došli u Qortal, naći ćete da je sličan onome RPG igre, vi, kao MINTER na Qortal mreži (ako se odlučite da postanete), imat ćete priliku za dizanjem vašeg računa, dajući vam oboje i QORT blok nagrade i također veći utjecaj na mrežu u smislu glasovanja o odlukama za platformu.",
|
"createwelcome": "Dobrodošli u Qortal! Vaša decentralizirana digitalna budućnost čeka na vas! Samo na Qortalu imate apsolutnu kontrolu nad svojim podacima. Qortal pruža osnovnu razinu novog digitalnog svijeta koji u potpunosti kontrolira korisnik.",
|
||||||
"createa": "A",
|
"createa": "A",
|
||||||
"click": "Kliknite da vidite Seed frazu",
|
"click": "Kliknite da vidite Seed frazu",
|
||||||
"confirmpass": "Potvrdi lozinku",
|
"confirmpass": "Potvrdi lozinku",
|
||||||
"willbe": "će se slučajno generirati u pozadini. To se koristi kao vaš generator privatnog ključa za vaš blockchain račun u Qortal-u.",
|
"willbe": "će se nasumično generirati u pozadini. Ako želite POGLEDATI početnu frazu, kliknite označenu 'seedphrase' u ovom tekstu. Ovo se koristi kao vaš generator privatnog ključa za vaš blockchain račun u Qortalu. Za sigurnost prema zadanim postavkama, početne fraze se ne prikazuju osim ako nije posebno odabrano da budu.",
|
||||||
"clicknext": "Stvorite Qortal račun klikom na SLJEDEĆE ispod.",
|
"clicknext": "Stvorite Qortal račun klikom na SLJEDEĆE ispod.",
|
||||||
"ready": "Vaš je račun sada spreman za izradu. Bit će spremljen u ovom pregledniku. Ako ne želite da vaš novi račun bude spremljen u vašem pregledniku, možete poništiti okvir u nastavku. I dalje ćete se moći prijaviti svojim novim računom (nakon odjave), pomoću datoteke sigurnosna kopija novčanika koju morate preuzeti nakon što stvorite svoj račun.",
|
"ready": "Vaš račun je sada spreman za izradu. Bit će spremljen unutar ove kopije Qortal korisničkog sučelja prema zadanim postavkama, u šifriranom obliku. Ako ne želite da se vaš novi račun ovdje spremi, možete poništiti okvir ispod. I dalje ćete se moći prijaviti sa svojim novim računom (nakon što se odjavite), koristeći datoteku sigurnosne kopije novčanika koju MORATE preuzeti nakon što kreirate svoj račun.",
|
||||||
"welmessage": "Dobrodošli u Qortal",
|
"welmessage": "Dobrodošli u Qortal",
|
||||||
"pleaseenter": "Unesite lozinku!",
|
"pleaseenter": "Unesite lozinku!",
|
||||||
"notmatch": "Lozinke se ne podudaraju!",
|
"notmatch": "Lozinke se ne podudaraju!",
|
||||||
@ -164,7 +164,7 @@
|
|||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "Odaberite datoteku",
|
"selectfile": "Odaberite datoteku",
|
||||||
"dragfile": "Povucite i ispustite sigurnosnu kopiju ovdje"
|
"dragfile": "Povucite i ispustite ili kliknite ovdje za odabir datoteke sigurnosne kopije"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "Opće informacije o računu",
|
"generalinfo": "Opće informacije o računu",
|
||||||
@ -181,7 +181,7 @@
|
|||||||
"notifications": "Obavijesti",
|
"notifications": "Obavijesti",
|
||||||
"accountsecurity": "Sigurnost računa",
|
"accountsecurity": "Sigurnost računa",
|
||||||
"password": "Lozinka",
|
"password": "Lozinka",
|
||||||
"download": "Preuzmite sigurnosnu kopiju računa",
|
"download": "Izvezi/spremi datoteku sigurnosne kopije",
|
||||||
"choose": "Odaberite lozinku za šifriranje sigurnosne kopije. (Ovo može biti ista kao i ona sa kojom ste se prijavili ili različita)",
|
"choose": "Odaberite lozinku za šifriranje sigurnosne kopije. (Ovo može biti ista kao i ona sa kojom ste se prijavili ili različita)",
|
||||||
"playsound": "Puštanje zvuka",
|
"playsound": "Puštanje zvuka",
|
||||||
"shownotifications": "Prikaži obavijesti",
|
"shownotifications": "Prikaži obavijesti",
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "Kreditna",
|
"balance": "Kreditna",
|
||||||
"balances": "VAŠ NOVČANIK JE NA SALJU",
|
"balances": "VAŠ NOVČANIK JE NA SALJU",
|
||||||
"update": "AŽURIRAJTE STANJE NOVČANIKA",
|
"update": "AŽURIRAJTE STANJE NOVČANIKA",
|
||||||
"view": "Pogled"
|
"view": "Pogled",
|
||||||
|
"all": "svi",
|
||||||
|
"page": "Stranica"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Gif Explorer",
|
"gchange1": "Gif Explorer",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "Prodajna cijena",
|
"nchange23": "Prodajna cijena",
|
||||||
"nchange24": "Nema imena za prodaju",
|
"nchange24": "Nema imena za prodaju",
|
||||||
"nchange25": "Ime za prodaju",
|
"nchange25": "Ime za prodaju",
|
||||||
"nchange26": "Jeste li sigurni da ćete prodati ovo ime?",
|
"nchange26": "Jeste li sigurni da želite prodati ovo ime? Ako je ime kupljeno putem drugog računa, bit će izvan vaše kontrole!",
|
||||||
"nchange27": "Za ovu cijenu u QORT",
|
"nchange27": "Za ovu cijenu u QORT",
|
||||||
"nchange28": "Pritiskom na potvrdu, zahtjev za prodajnim imenom bit će poslan!",
|
"nchange28": "Pritiskom na potvrdu, zahtjev za prodajnim imenom bit će poslan!",
|
||||||
"nchange29": "Ime za poništavanje",
|
"nchange29": "Ime za poništavanje",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "Naziv grupe za pretraživanje",
|
"gchange56": "Naziv grupe za pretraživanje",
|
||||||
"gchange57": "Ime privatne grupe nije pronađeno",
|
"gchange57": "Ime privatne grupe nije pronađeno",
|
||||||
"gchange58": "Imajte na umu da se naziv grupe mora točno podudarati.",
|
"gchange58": "Imajte na umu da se naziv grupe mora točno podudarati.",
|
||||||
"gchange59": "Prikaži / sakrij ticker"
|
"gchange59": "Prikaži / sakrij ticker",
|
||||||
|
"gchange60": "Unesite naziv grupe",
|
||||||
|
"gchange61": "Unesite opis",
|
||||||
|
"gchange62": "Jeste li sigurni da AŽURIRATE ovu grupu?",
|
||||||
|
"gchange63": "Pritiskom na CONFIRM, zahtjev za UPDATE_GROUP bit će poslan!",
|
||||||
|
"gchange64": "Trenutni vlasnik / novi vlasnik",
|
||||||
|
"gchange65": "Zamijenite ovu adresu u PRIJENOS VLASNIŠTVA grupe!",
|
||||||
|
"gchange66": "Vlasnik / nova adresa vlasnika nisu valjani",
|
||||||
|
"gchange67": "Grupa UPDATE Uspješna!",
|
||||||
|
"gchange68": "Postavi grupni avatar"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Zagonetke",
|
"pchange1": "Zagonetke",
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
"tm32": "Ez a fiók nem követ egyetlen felhasználót sem",
|
"tm32": "Ez a fiók nem követ egyetlen felhasználót sem",
|
||||||
"tm33": "Importálás lap menü",
|
"tm33": "Importálás lap menü",
|
||||||
"tm34": "Exportálás lap menü",
|
"tm34": "Exportálás lap menü",
|
||||||
"tm35": "Meglévő lapmenüje törlésre kerül, és a feltöltött lapok menüje lesz.",
|
"tm35": "A meglévő lapmenü törlésre kerül, és az importált lapmenü lesz.",
|
||||||
"tm36": "A lap menüje sikeresen visszaállítva",
|
"tm36": "A lap menüje sikeresen visszaállítva",
|
||||||
"tm37": "A lap menüje sikeresen mentve másként",
|
"tm37": "A lap menüje sikeresen mentve másként",
|
||||||
"tm38": "DEV MODE",
|
"tm38": "DEV MODE",
|
||||||
@ -96,7 +96,7 @@
|
|||||||
"address": "Cím",
|
"address": "Cím",
|
||||||
"password": "Jelszó",
|
"password": "Jelszó",
|
||||||
"youraccounts": "Fiókjai",
|
"youraccounts": "Fiókjai",
|
||||||
"clickto": "Kattintson a fiókjára a bejelentkezéshez",
|
"clickto": "Kattintson a fiókra a bejelentkezéshez",
|
||||||
"needcreate": "A bejelentkezés előtt létre kell hoznia vagy mentenie kell egy fiókot!",
|
"needcreate": "A bejelentkezés előtt létre kell hoznia vagy mentenie kell egy fiókot!",
|
||||||
"upload": "A Qortal biztonsági másolat feltöltése",
|
"upload": "A Qortal biztonsági másolat feltöltése",
|
||||||
"howlogin": "Hogyan szertne bejelentkezni?",
|
"howlogin": "Hogyan szertne bejelentkezni?",
|
||||||
@ -108,16 +108,16 @@
|
|||||||
"decrypt": "Visszafejt biztonsági másolat",
|
"decrypt": "Visszafejt biztonsági másolat",
|
||||||
"save": "Mentés ebben a böngészőben.",
|
"save": "Mentés ebben a böngészőben.",
|
||||||
"prepare": "Fiók előkészítése",
|
"prepare": "Fiók előkészítése",
|
||||||
"areyousure": "Biztosan el akarja távolítani ezt a pénztárcát a mentett pénztárcákból?",
|
"areyousure": "Biztosan eltávolítja ezt a pénztárcát a mentett pénztárcák közül? (Ha eltávolítja, és nem létezik biztonsági mentési fájl, a fiók végleg elveszhet! Győződjön meg róla, hogy van biztonsági másolata, mielőtt ezt megtenné!)",
|
||||||
"error1": "A biztonsági másolatnak érvényes JSONnak kell lennie",
|
"error1": "A biztonsági másolatnak érvényes JSONnak kell lennie",
|
||||||
"error2": "Bejelentkezési beállítás nincs kijelölve",
|
"error2": "Bejelentkezési beállítás nincs kijelölve",
|
||||||
"createwelcome": "Üdvözöljük a Qortalban, úgy fogja találni, hogy hasonló az RPG játékhoz. Mint a Qortal hálózat verője (ha úgy dönt, hogy eggyé válik), lehetősége lesz arra, hogy kiegyenlítse fiókját. Ez mind a QORT blokk jutalmát, mind a nagyobb befolyást biztosítja a hálózatra a platformra vonatkozó döntésekről szóló szavazás tekintetében.",
|
"createwelcome": "Üdvözöljük a Qortalban! Decentralizált digitális jövője várja Önt! A Qortalon csak Önnek van abszolút ellenőrzése az adatok felett. A Qortal egy új, teljes mértékben felhasználó által vezérelt digitális világ alapszintjét biztosítja.",
|
||||||
"createa": "A",
|
"createa": "A",
|
||||||
"click": "Kattintson ide a magfrázis megtekintéséhez",
|
"click": "Kattintson ide a magfrázis megtekintéséhez",
|
||||||
"confirmpass": "Jelszó megerősítése",
|
"confirmpass": "Jelszó megerősítése",
|
||||||
"willbe": "Véletlenszerűen jön létre a háttérben. Ezt használják a Qortal blokklánc-fiókjához tartozó privát kulcsgenerátorként.",
|
"willbe": "véletlenszerűen generálódik a háttérben. Ha meg szeretné tekinteni az alapkifejezést, kattintson a kiemelt „seedphrase”-ra ebben a szövegben. Ezt használja a privát kulcs generátoraként a blokklánc-fiókjához a Qortalban. Alapértelmezés szerint a biztonság kedvéért a kezdőmondatok nem jelennek meg, hacsak nincs külön kiválasztva.",
|
||||||
"clicknext": "Qortal-fiók létrehozása az alábbi TOVÁBB/NEXT gombra kattintva",
|
"clicknext": "Qortal-fiók létrehozása az alábbi TOVÁBB/NEXT gombra kattintva",
|
||||||
"ready": "Fiókja készen áll a létrehozására. Ez a böngészőben lesz mentve.Ha nem szeretné, hogy új fiókját a böngészőbe mentse, törölje a jelet az alábbi jelölőnégyzetből. Továbbra is bejelentkezhet az új fiókjával (kijelentkezés után), a pénztárca biztonsági mentési fájljával, amelyet le kell töltenie a fiók létrehozása után.",
|
"ready": "Fiókja készen áll a létrehozásra. Alapértelmezés szerint a Qortal felhasználói felület ezen példányába kerül mentésre, titkosított formában. Ha nem szeretné, hogy új fiókja itt kerüljön mentésre, törölje a jelet az alábbi négyzetből. Továbbra is be tud majd jelentkezni az új fiókjával (kijelentkezés után), a pénztárca biztonsági mentési fájljával, amelyet a fiók létrehozása után KELL letöltenie.",
|
||||||
"welmessage": "Üdvözöljük a Qortalban",
|
"welmessage": "Üdvözöljük a Qortalban",
|
||||||
"pleaseenter": "Kérjük, adjon meg egy jelszót!",
|
"pleaseenter": "Kérjük, adjon meg egy jelszót!",
|
||||||
"notmatch": "A jelszavak nem egyeznek!",
|
"notmatch": "A jelszavak nem egyeznek!",
|
||||||
@ -164,7 +164,7 @@
|
|||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "Fájl kijelölése",
|
"selectfile": "Fájl kijelölése",
|
||||||
"dragfile": "Biztonsági mentés húzása ide"
|
"dragfile": "Húzza át vagy kattintson ide a biztonsági mentési fájl kiválasztásához"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "Általános fiókadatok",
|
"generalinfo": "Általános fiókadatok",
|
||||||
@ -181,7 +181,7 @@
|
|||||||
"notifications": "Értesítések",
|
"notifications": "Értesítések",
|
||||||
"accountsecurity": "Fiók biztonsága",
|
"accountsecurity": "Fiók biztonsága",
|
||||||
"password": "Jelszó",
|
"password": "Jelszó",
|
||||||
"download": "Biztonságimásolat-fájl letöltése",
|
"download": "Biztonsági másolat fájl exportálása/mentése",
|
||||||
"choose": "Válasszon egy jelszót a biztonsági mentés titkosításához. (Ez lehet ugyanaz, mint az, amelyikbe bejelentkezett, vagy más)",
|
"choose": "Válasszon egy jelszót a biztonsági mentés titkosításához. (Ez lehet ugyanaz, mint az, amelyikbe bejelentkezett, vagy más)",
|
||||||
"playsound": "Hang lejátszása",
|
"playsound": "Hang lejátszása",
|
||||||
"shownotifications": "Értesítések megjelenítése",
|
"shownotifications": "Értesítések megjelenítése",
|
||||||
@ -211,7 +211,7 @@
|
|||||||
"qappNotification1": "Q-App értesítések",
|
"qappNotification1": "Q-App értesítések",
|
||||||
"selectnode": "Kérjük, válasszon egy lehetőséget",
|
"selectnode": "Kérjük, válasszon egy lehetőséget",
|
||||||
"arrr1": "ARRR Wallet nincs inicializálva!",
|
"arrr1": "ARRR Wallet nincs inicializálva!",
|
||||||
"arrr2": "Kérjük, lépjen a Wallet fülre, és először inicializálja arrr pénztárcáját.",
|
"arrr2": "Kérjük, lépjen a Wallet fülre, és nyissa meg az ARRR pénztárcát a pénztárca inicializálásához.",
|
||||||
"arrr3": "Alapfrissítésre van szükség!",
|
"arrr3": "Alapfrissítésre van szükség!",
|
||||||
"arrr4": "Az arrr pénztárca privát kulcsának mentéséhez először egy alapvető frissítésre van szükség!",
|
"arrr4": "Az arrr pénztárca privát kulcsának mentéséhez először egy alapvető frissítésre van szükség!",
|
||||||
"sync_indicator": "Szinkronizálásjelző előugró ablak letiltása"
|
"sync_indicator": "Szinkronizálásjelző előugró ablak letiltása"
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "Hitel",
|
"balance": "Hitel",
|
||||||
"balances": "A PÉNZTÁRCSA EGYENLEGEK",
|
"balances": "A PÉNZTÁRCSA EGYENLEGEK",
|
||||||
"update": "FRISSÍTSE A PÉNZTÁRCSA-EGYENLEGEKET",
|
"update": "FRISSÍTSE A PÉNZTÁRCSA-EGYENLEGEKET",
|
||||||
"view": "Kilátás"
|
"view": "Kilátás",
|
||||||
|
"all": "Minden",
|
||||||
|
"page": "Oldal"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Gif Explorer",
|
"gchange1": "Gif Explorer",
|
||||||
@ -284,7 +286,7 @@
|
|||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "Nem lehet lekérni a pénzverési számlákat",
|
"smchange1": "Nem lehet lekérni a pénzverési számlákat",
|
||||||
"smchange2": "Nem sikerült eltávolítani a kulcsot",
|
"smchange2": "Nem sikerült eltávolítani a kulcsot",
|
||||||
"smchange3": "Nem sikerült hozzáadni a pénzverési kulcsot",
|
"smchange3": "Nem sikerült hozzáadni a pénzverési kulcsot. Ha a kulcs most jött létre, várjon néhány blokkot, majd adja hozzá újra",
|
||||||
"smchange4": "Nem hozható létre szponzori kulcs",
|
"smchange4": "Nem hozható létre szponzori kulcs",
|
||||||
"smchange5": "Kapcsolatteremtés",
|
"smchange5": "Kapcsolatteremtés",
|
||||||
"smchange6": "Megerősítésre vár a blokkláncon",
|
"smchange6": "Megerősítésre vár a blokkláncon",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "Eladási ár",
|
"nchange23": "Eladási ár",
|
||||||
"nchange24": "Nincsenek eladható nevek",
|
"nchange24": "Nincsenek eladható nevek",
|
||||||
"nchange25": "Eladó név",
|
"nchange25": "Eladó név",
|
||||||
"nchange26": "Biztosan eladja ezt a nevet?",
|
"nchange26": "Biztos, hogy el akarja adni ezt a nevet? Ha a nevet egy másik fiók vásárolja meg, az nem lesz ellenőrzése!",
|
||||||
"nchange27": "Erre az árra QORT-ban",
|
"nchange27": "Erre az árra QORT-ban",
|
||||||
"nchange28": "A megerősítés megnyomására elküldjük az eladási névkérést!",
|
"nchange28": "A megerősítés megnyomására elküldjük az eladási névkérést!",
|
||||||
"nchange29": "Megszakítandó név",
|
"nchange29": "Megszakítandó név",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "A keresendő csoport neve",
|
"gchange56": "A keresendő csoport neve",
|
||||||
"gchange57": "A privát csoport neve nem található",
|
"gchange57": "A privát csoport neve nem található",
|
||||||
"gchange58": "Ne feledje, hogy a csoport nevének pontosan meg kell egyeznie.",
|
"gchange58": "Ne feledje, hogy a csoport nevének pontosan meg kell egyeznie.",
|
||||||
"gchange59": "Ticker megjelenítése / elrejtése"
|
"gchange59": "Ticker megjelenítése / elrejtése",
|
||||||
|
"gchange60": "Kérjük, adja meg a csoport nevét",
|
||||||
|
"gchange61": "Kérjük, adja meg a leírást",
|
||||||
|
"gchange62": "Biztosan FRISSÍTI ezt a csoportot?",
|
||||||
|
"gchange63": "A MEGERŐSÍTÉS gomb megnyomásával elküldésre kerül a UPDATE_GROUP kérés!",
|
||||||
|
"gchange64": "Jelenlegi tulajdonos / Új tulajdonos",
|
||||||
|
"gchange65": "Cserélje ki ezt a címet erre: A CSOPORT TULAJDONJOGÁNAK ÁTRUHÁZÁSA!",
|
||||||
|
"gchange66": "Érvénytelen tulajdonos / új tulajdonos címe",
|
||||||
|
"gchange67": "Csoportos FRISSÍTÉS sikeres!",
|
||||||
|
"gchange68": "Csoportavatar beállítása"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Rejtvények",
|
"pchange1": "Rejtvények",
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
"tm32": "Questo account non segue nessun utente",
|
"tm32": "Questo account non segue nessun utente",
|
||||||
"tm33": "Menu scheda Importa",
|
"tm33": "Menu scheda Importa",
|
||||||
"tm34": "Menu scheda Esporta",
|
"tm34": "Menu scheda Esporta",
|
||||||
"tm35": "Il menu della scheda esistente verrà eliminato e impostato sul menu della scheda caricato.",
|
"tm35": "Il menu della scheda esistente verrà eliminato e impostato sul menu della scheda importato.",
|
||||||
"tm36": "Menu scheda ripristinato con successo",
|
"tm36": "Menu scheda ripristinato con successo",
|
||||||
"tm37": "Menu scheda salvato con successo con nome",
|
"tm37": "Menu scheda salvato con successo con nome",
|
||||||
"tm38": "MODALITÀ SVILUPPATORE",
|
"tm38": "MODALITÀ SVILUPPATORE",
|
||||||
@ -96,7 +96,7 @@
|
|||||||
"address": "Indirizzo",
|
"address": "Indirizzo",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"youraccounts": "I tuoi account",
|
"youraccounts": "I tuoi account",
|
||||||
"clickto": "Fai clic sul tuo account per accedere con esso",
|
"clickto": "Fare clic su account per accedere",
|
||||||
"needcreate": "Devi creare o salvare un account prima di poter accedere!",
|
"needcreate": "Devi creare o salvare un account prima di poter accedere!",
|
||||||
"upload": "Carica il tuo backup di Qortal",
|
"upload": "Carica il tuo backup di Qortal",
|
||||||
"howlogin": "Come vorresti accedere?",
|
"howlogin": "Come vorresti accedere?",
|
||||||
@ -108,16 +108,16 @@
|
|||||||
"decrypt": "Decifra backup",
|
"decrypt": "Decifra backup",
|
||||||
"save": "Salva in questo browser.",
|
"save": "Salva in questo browser.",
|
||||||
"prepare": "Preparazione del tuo account",
|
"prepare": "Preparazione del tuo account",
|
||||||
"areyousure": "Sei sicuro di voler rimuovere questo portafoglio dai portafogli salvati?",
|
"areyousure": "Sei sicuro di voler rimuovere questo portafoglio dai portafogli salvati? (Se rimosso e non esiste alcun file di backup, l'account potrebbe essere perso per sempre! Assicurati di avere un file di backup prima di farlo!)",
|
||||||
"error1": "Il backup deve essere un JSON valido",
|
"error1": "Il backup deve essere un JSON valido",
|
||||||
"error2": "Opzione di accesso non selezionata",
|
"error2": "Opzione di accesso non selezionata",
|
||||||
"createwelcome": "Benvenuto in Qortal, lo troverai simile a quello di un gioco di ruolo, tu, come minatore della rete Qortal (se scegli di diventarlo) avrai la possibilità di aumentare di livello il tuo account, incrementando sia le ricompense per blocco e anche l'influenza sulla rete in termini di voto sulle decisioni per la piattaforma.",
|
"createwelcome": "Benvenuti a Qortal! Il tuo futuro digitale decentralizzato ti aspetta! Su Qortal solo tu hai il controllo assoluto sui tuoi dati. Qortal fornisce il livello base di un mondo digitale nuovo e completamente controllato dall'utente.",
|
||||||
"createa": "A",
|
"createa": "A",
|
||||||
"click": "Clicca per visualizzare la seedphrase",
|
"click": "Clicca per visualizzare la seedphrase",
|
||||||
"confirmpass": "Conferma password",
|
"confirmpass": "Conferma password",
|
||||||
"willbe": "sarà generato casualmente in background. Questo è usato come generatore di chiavi private per il tuo account sulla blockchain di Qortal.",
|
"willbe": "verrà generato casualmente in background. Se desideri VISUALIZZARE la frase seme, fai clic sulla 'frase seme' evidenziata in questo testo. Questo viene utilizzato come generatore di chiave privata per il tuo account blockchain in Qortal. Per motivi di sicurezza, per impostazione predefinita, le frasi iniziali non vengono visualizzate a meno che non venga specificatamente scelto di esserlo.",
|
||||||
"clicknext": "Crea il tuo account Qortal facendo clic su AVANTI di seguito.",
|
"clicknext": "Crea il tuo account Qortal facendo clic su AVANTI di seguito.",
|
||||||
"ready": "Il tuo account è ora pronto per essere creato. Verrà salvato in questo browser. Se non desideri che il tuo nuovo account venga salvato nel tuo browser, puoi deselezionare la casella qui sotto. Sarai comunque in grado di accedere con il tuo nuovo account (dopo il logout), utilizzando il file di backup del tuo portafoglio che DEVI scaricare una volta creato il tuo account.",
|
"ready": "Il tuo account è ora pronto per essere creato. Verrà salvato all'interno di questa copia dell'interfaccia utente Qortal per impostazione predefinita, in formato crittografato. Se non desideri che il tuo nuovo account venga salvato qui, puoi deselezionare la casella sottostante. Potrai comunque accedere con il tuo nuovo account (dopo esserti disconnesso), utilizzando il file di backup del tuo portafoglio che DEVI scaricare una volta creato il tuo account.",
|
||||||
"welmessage": "Benvenuto in Qortal",
|
"welmessage": "Benvenuto in Qortal",
|
||||||
"pleaseenter": "Inserisci una password!",
|
"pleaseenter": "Inserisci una password!",
|
||||||
"notmatch": "La password non corrisponde!",
|
"notmatch": "La password non corrisponde!",
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "Saldo",
|
"balance": "Saldo",
|
||||||
"balances": "I SALDI DEL TUO PORTAFOGLIO",
|
"balances": "I SALDI DEL TUO PORTAFOGLIO",
|
||||||
"update": "AGGIORNA I SALDI DEL PORTAFOGLIO",
|
"update": "AGGIORNA I SALDI DEL PORTAFOGLIO",
|
||||||
"view": "Vedere"
|
"view": "Vedere",
|
||||||
|
"all": "Tutto",
|
||||||
|
"page": "Pagina"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Esplora Gif",
|
"gchange1": "Esplora Gif",
|
||||||
@ -284,7 +286,7 @@
|
|||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "Impossibile recuperare i conti di conio",
|
"smchange1": "Impossibile recuperare i conti di conio",
|
||||||
"smchange2": "Impossibile rimuovere la chiave",
|
"smchange2": "Impossibile rimuovere la chiave",
|
||||||
"smchange3": "Impossibile aggiungere la chiave di conio",
|
"smchange3": "Failed to add minting key, if key was just created try waiting a few blocks and adding again",
|
||||||
"smchange4": "Impossibile creare la chiave di sponsorizzazione",
|
"smchange4": "Impossibile creare la chiave di sponsorizzazione",
|
||||||
"smchange5": "Creare relazione",
|
"smchange5": "Creare relazione",
|
||||||
"smchange6": "In attesa di conferma su blockchain",
|
"smchange6": "In attesa di conferma su blockchain",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "Prezzo di vendita",
|
"nchange23": "Prezzo di vendita",
|
||||||
"nchange24": "Nessun nome da vendere",
|
"nchange24": "Nessun nome da vendere",
|
||||||
"nchange25": "Nome da vendere",
|
"nchange25": "Nome da vendere",
|
||||||
"nchange26": "Sei sicuro di vendere questo nome?",
|
"nchange26": "Sei sicuro di voler vendere questo nome? Se il nome viene acquistato da un altro account sarà fuori dal tuo controllo!",
|
||||||
"nchange27": "Per questo prezzo in QORT",
|
"nchange27": "Per questo prezzo in QORT",
|
||||||
"nchange28": "Premendo conferma, verrà inviata la richiesta di vendita del nome!",
|
"nchange28": "Premendo conferma, verrà inviata la richiesta di vendita del nome!",
|
||||||
"nchange29": "Nome da cancellare",
|
"nchange29": "Nome da cancellare",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "Nome gruppo da cercare",
|
"gchange56": "Nome gruppo da cercare",
|
||||||
"gchange57": "Nome gruppo privato non trovato",
|
"gchange57": "Nome gruppo privato non trovato",
|
||||||
"gchange58": "Nota che il nome del gruppo deve corrispondere esattamente.",
|
"gchange58": "Nota che il nome del gruppo deve corrispondere esattamente.",
|
||||||
"gchange59": "Mostra / Nascondi ticker"
|
"gchange59": "Mostra / Nascondi ticker",
|
||||||
|
"gchange60": "Inserisci il nome del gruppo",
|
||||||
|
"gchange61": "Si prega di inserire la descrizione",
|
||||||
|
"gchange62": "Sei sicuro di AGGIORNARE questo gruppo?",
|
||||||
|
"gchange63": "Premendo CONFERMA, verrà inviata la richiesta UPDATE_GROUP!",
|
||||||
|
"gchange64": "Proprietario attuale / Nuovo proprietario",
|
||||||
|
"gchange65": "Sostituisci questo indirizzo per TRASFERIRE LA PROPRIETA' del gruppo!",
|
||||||
|
"gchange66": "Indirizzo del proprietario non valido/nuovo proprietario",
|
||||||
|
"gchange67": "AGGIORNAMENTO di gruppo riuscito!",
|
||||||
|
"gchange68": "Imposta avatar di gruppo"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Puzzle",
|
"pchange1": "Puzzle",
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
"tm32": "このアカウントはどのユーザーもフォローしていません",
|
"tm32": "このアカウントはどのユーザーもフォローしていません",
|
||||||
"tm33": "インポートタブメニュー",
|
"tm33": "インポートタブメニュー",
|
||||||
"tm34": "エクスポートタブメニュー",
|
"tm34": "エクスポートタブメニュー",
|
||||||
"tm35": "既存のタブ メニューは削除され、アップロードされたタブ メニューに設定されます。",
|
"tm35": "既存のタブメニューが削除され、インポートされたタブメニューに設定されます。",
|
||||||
"tm36": "タブメニューが正常に復元されました",
|
"tm36": "タブメニューが正常に復元されました",
|
||||||
"tm37": "タブメニューが名前を付けて保存されました",
|
"tm37": "タブメニューが名前を付けて保存されました",
|
||||||
"tm38": "開発モード",
|
"tm38": "開発モード",
|
||||||
@ -96,28 +96,28 @@
|
|||||||
"address": "アドレス",
|
"address": "アドレス",
|
||||||
"password": "パスワード",
|
"password": "パスワード",
|
||||||
"youraccounts": "あなたのアカウント",
|
"youraccounts": "あなたのアカウント",
|
||||||
"clickto": "ログインしたいアカウントをクリックして下さい",
|
"clickto": "アカウントをクリックしてログインします",
|
||||||
"needcreate": "ログインする前にアカウントを作成または保存する必要があります!",
|
"needcreate": "ログインする前にアカウントを作成または保存する必要があります!",
|
||||||
"upload": "Qortal のバックアップをアップロードします",
|
"upload": "Qortal のバックアップをアップロードします",
|
||||||
"howlogin": "どのようにログインしますか?",
|
"howlogin": "どのようにログインしますか?",
|
||||||
"seed": "シードフレーズ",
|
"seed": "シードフレーズ",
|
||||||
"seedphrase": "シードフレーズ",
|
"seedphrase": "シードフレーズ",
|
||||||
"saved": "保存したアカウント",
|
"saved": "保存したアカウント",
|
||||||
"qora": "Qora アドレス シード",
|
"qora": "QORA アドレス シード",
|
||||||
"backup": "Qortal ウォレットのバックアップ",
|
"backup": "Qortalバックアップファイル",
|
||||||
"decrypt": "バックアップを復号化",
|
"decrypt": "バックアップファイルを復号化する",
|
||||||
"save": "このブラウザに保存します。",
|
"save": "このブラウザに保存します。",
|
||||||
"prepare": "アカウントを準備",
|
"prepare": "アカウントを準備",
|
||||||
"areyousure": "保存されたウォレットからこのウォレットを削除しますか?",
|
"areyousure": "このウォレットを保存されたウォレットから削除してもよろしいですか? (削除してバックアップ ファイルが存在しない場合、アカウントが永久に失われる可能性があります。これを行う前にバックアップ ファイルがあることを確認してください。)",
|
||||||
"error1": "バックアップは有効な JSON である必要があります",
|
"error1": "バックアップは有効な JSON である必要があります",
|
||||||
"error2": "ログイン オプションが選択されていません",
|
"error2": "ログイン オプションが選択されていません",
|
||||||
"createwelcome": "Qortal へようこそ。Qortalは RPG ゲームに似ている事に気づくと思います。Qortal ネットワークのミンターとして (なりたいと選択した場合) アカウントをレベルアップすることが出来、QORT のブロック報酬をより多く得られるだけでなく、プラットフォームの決定に対する投票という点で、ネットワークに対してより大きな影響力を持つことが出来ます。",
|
"createwelcome": "Qortal へようこそ。分散型デジタルの未来があなたを待っています! Qortal では、データを完全に制御できるのはあなただけです。 Qortal は、ユーザーが完全に制御できる新しいデジタル世界の基本レベルを提供します。",
|
||||||
"createa": "A",
|
"createa": "A",
|
||||||
"click": "クリックしてシードフレーズを表示",
|
"click": "クリックしてシードフレーズを表示",
|
||||||
"confirmpass": "パスワードの確認",
|
"confirmpass": "パスワードの確認",
|
||||||
"willbe": "はバックグラウンドでランダムに生成されます。これは、Qortal のブロックチェーン アカウントの秘密キー ジェネレーターとして使用されます。",
|
"willbe": "バックグラウンドでランダムに生成されます。 シードフレーズを表示したい場合は、このテキスト内で強調表示されている「シードフレーズ」をクリックしてください。 これは、Qortal のブロックチェーン アカウントの秘密キー ジェネレーターとして使用されます。 デフォルトでは、セキュリティのため、特に選択しない限り、シードフレーズは表示されません。",
|
||||||
"clicknext": "下の [次へ] をクリックして Qortal アカウントを作成します。",
|
"clicknext": "下の [次へ] をクリックして Qortal アカウントを作成します。",
|
||||||
"ready": "アカウントを作成する準備が出来ました。アカウントはこのブラウザに保存されます。新しいアカウントをブラウザに保存したくない場合は、下のボックスのチェックを外してください。[必ず」新しいアカウントのウォレットのバックアップ ファイルをダウンロードして下さい。(ログアウト後) そのバックアップファイルが無いとログイン不可になります。",
|
"ready": "これでアカウントを作成する準備ができました。 デフォルトでは、Qortal UI のこのコピー内に暗号化された形式で保存されます。 新しいアカウントをここに保存したくない場合は、下のボックスのチェックを外してください。 アカウントを作成したら必ずダウンロードする必要があるウォレットのバックアップ ファイルを使用して、(ログアウト後も) 新しいアカウントでログインすることができます。",
|
||||||
"welmessage": "Qortal へようこそ",
|
"welmessage": "Qortal へようこそ",
|
||||||
"pleaseenter": "パスワードを入力してください!",
|
"pleaseenter": "パスワードを入力してください!",
|
||||||
"notmatch": "パスワードが一致しません!",
|
"notmatch": "パスワードが一致しません!",
|
||||||
@ -207,11 +207,11 @@
|
|||||||
"exp2": "マスターキーのエクスポート",
|
"exp2": "マスターキーのエクスポート",
|
||||||
"exp3": "エクスポート",
|
"exp3": "エクスポート",
|
||||||
"exp4": "秘密マスターキーをバックアップするウォレットを選択してください。",
|
"exp4": "秘密マスターキーをバックアップするウォレットを選択してください。",
|
||||||
"core": "Core設定を開始",
|
"core": "Core自動起動設定",
|
||||||
"qappNotification1": "Q-App 通知",
|
"qappNotification1": "Q-App 通知",
|
||||||
"selectnode": "オプションを選択してください",
|
"selectnode": "オプションを選択してください",
|
||||||
"arrr1": "ARRR ウォレットが初期化されていません!",
|
"arrr1": "ARRR ウォレットが初期化されていません!",
|
||||||
"arrr2": "ウォレットタブに移動して、まずarrrウォレットを初期化してください。",
|
"arrr2": "まずウォレットタブに移動し、ARRR ウォレットにアクセスしてウォレットを初期化してください。",
|
||||||
"arrr3": "コアのアップデートが必要です!",
|
"arrr3": "コアのアップデートが必要です!",
|
||||||
"arrr4": "arrr ウォレットの秘密キーを保存するには、まずコアのアップデートが必要です!",
|
"arrr4": "arrr ウォレットの秘密キーを保存するには、まずコアのアップデートが必要です!",
|
||||||
"sync_indicator": "同期インジケーターのポップアップを無効にする"
|
"sync_indicator": "同期インジケーターのポップアップを無効にする"
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "残高",
|
"balance": "残高",
|
||||||
"balances": "あなたのウォレット残高",
|
"balances": "あなたのウォレット残高",
|
||||||
"update": "ウォレット残高を更新",
|
"update": "ウォレット残高を更新",
|
||||||
"view": "表示"
|
"view": "表示",
|
||||||
|
"all": "全て",
|
||||||
|
"page": "ページ"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "GIF エクスプローラー",
|
"gchange1": "GIF エクスプローラー",
|
||||||
@ -284,7 +286,7 @@
|
|||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "ミントアカウントを取得出来ません",
|
"smchange1": "ミントアカウントを取得出来ません",
|
||||||
"smchange2": "キーの削除に失敗しました",
|
"smchange2": "キーの削除に失敗しました",
|
||||||
"smchange3": "ミントキーの追加に失敗しました",
|
"smchange3": "ミントキーを追加できませんでした。キーが作成されたばかりの場合は、数ブロック待ってから再度追加してください",
|
||||||
"smchange4": "スポンサーシップ キーを作成出来ません",
|
"smchange4": "スポンサーシップ キーを作成出来ません",
|
||||||
"smchange5": "関係の構築開始",
|
"smchange5": "関係の構築開始",
|
||||||
"smchange6": "ブロックチェーンの承認を待っています",
|
"smchange6": "ブロックチェーンの承認を待っています",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "売値",
|
"nchange23": "売値",
|
||||||
"nchange24": "売却する名前はありません",
|
"nchange24": "売却する名前はありません",
|
||||||
"nchange25": "売却する名前",
|
"nchange25": "売却する名前",
|
||||||
"nchange26": "この名前を売却しますか?",
|
"nchange26": "この名前を販売してもよろしいですか? この名前が別のアカウントによって購入された場合、販売された名前によって公開されたデータにアクセスできなくなります。",
|
||||||
"nchange27": "QORT建価格",
|
"nchange27": "QORT建価格",
|
||||||
"nchange28": "確認を押すと、名前の売却リクエストが送信されます!",
|
"nchange28": "確認を押すと、名前の売却リクエストが送信されます!",
|
||||||
"nchange29": "売却中止する名前",
|
"nchange29": "売却中止する名前",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "検索するグループ名",
|
"gchange56": "検索するグループ名",
|
||||||
"gchange57": "非公開 グループ名が見つかりません",
|
"gchange57": "非公開 グループ名が見つかりません",
|
||||||
"gchange58": "グループ名は完全に一致する必要があります",
|
"gchange58": "グループ名は完全に一致する必要があります",
|
||||||
"gchange59": "ティッカーの表示/非表示"
|
"gchange59": "ティッカーの表示/非表示",
|
||||||
|
"gchange60": "グループ名を入力してください",
|
||||||
|
"gchange61": "説明を入力してください",
|
||||||
|
"gchange62": "このグループを更新してもよろしいですか?",
|
||||||
|
"gchange63": "CONFIRMを押すと、UPDATE_GROUPリクエストが送信されます。",
|
||||||
|
"gchange64": "現在の所有者/新しい所有者",
|
||||||
|
"gchange65": "このアドレスをグループの所有権の譲渡に置き換えてください。",
|
||||||
|
"gchange66": "無効な所有者/新しい所有者のアドレス",
|
||||||
|
"gchange67": "グループ UPDATE 成功しました!",
|
||||||
|
"gchange68": "グループアバターの設定"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "パズル",
|
"pchange1": "パズル",
|
||||||
|
@ -108,16 +108,16 @@
|
|||||||
"decrypt": "백업 암호 해독",
|
"decrypt": "백업 암호 해독",
|
||||||
"save": "이 브라우저에 저장",
|
"save": "이 브라우저에 저장",
|
||||||
"prepare": "계정 준비",
|
"prepare": "계정 준비",
|
||||||
"areyousure": "저장된 지갑에서 이 지갑을 제거하시겠습니까?",
|
"areyousure": "저장된 지갑에서 이 지갑을 제거하시겠습니까? (제거되고 백업 파일이 없으면 계정이 영원히 손실될 수 있습니다. 이 작업을 수행하기 전에 백업 파일이 있는지 확인하십시오!)",
|
||||||
"error1": "백업은 유호한 json파일 형식이어야 합니다.",
|
"error1": "백업은 유호한 json파일 형식이어야 합니다.",
|
||||||
"error2": "로그인 옵션이 선택되지 않았습니다.",
|
"error2": "로그인 옵션이 선택되지 않았습니다.",
|
||||||
"createwelcome": "Qortal에 오신 것을 환영합니다. RPG 게임과 비슷하다는 것을 알게 되실 것입니다. Qortal 네트워크의 관리자로서(만약 당신이 하나를 선택한다면) 계정을 레벨업할 수 있는 기회를 갖게 될 것입니다. Qortal 네트워크에 대한 더 많은 블록 보상은 물론 플랫폼 결정에 대한 투표 측면에서 네트워크에 대한 더 큰 영향력을 갖게 될 것입니다..",
|
"createwelcome": "Qortal에 오신 것을 환영합니다! 귀하의 분산형 디지털 미래가 귀하를 기다립니다! Qortal에서는 귀하만이 귀하의 데이터를 절대적으로 통제할 수 있습니다. Qortal은 새로운 완전 사용자 제어 디지털 세계의 기본 수준을 제공합니다.",
|
||||||
"createa": "A",
|
"createa": "A",
|
||||||
"click": "시드 구문을 보려면 클릭하십시오.",
|
"click": "시드 구문을 보려면 클릭하십시오.",
|
||||||
"confirmpass": "암호 확인",
|
"confirmpass": "암호 확인",
|
||||||
"willbe": "백그라운드에서 랜덤하게 생성됩니다. 이것은 Qortal의 블록체인 계정에 대한 개인 키 생성기로 사용됩니다.",
|
"willbe": "백그라운드에서 무작위로 생성됩니다. Seedphrase를 보려면 이 텍스트에서 강조표시된 'seedphrase'를 클릭하세요. 이는 Qortal의 블록체인 계정에 대한 개인 키 생성기로 사용됩니다. 기본적으로 보안을 위해 특별히 선택하지 않는 한 시드 문구는 표시되지 않습니다.",
|
||||||
"clicknext": "아래 NEXT를 클릭하여 Qortal 계정을 만드십시오.",
|
"clicknext": "아래 NEXT를 클릭하여 Qortal 계정을 만드십시오.",
|
||||||
"ready": "계정을 만들 준비가 되었습니다. 이 브라우저에 저장됩니다. 브라우저에 새 계정을 저장하지 않으려면 아래 상자를 선택 취소할 수 있습니다. 계정을 만든 후에는 반드시 다운로드해야 하는 지갑 백업 파일을 사용하여 새 계정으로 로그인할 수 있습니다(로그아웃 후).",
|
"ready": "이제 귀하의 계정을 생성할 준비가 되었습니다. 기본적으로 이 Qortal UI 복사본 내에 암호화된 형식으로 저장됩니다. 새 계정을 저장하지 않으려면 아래 확인란을 선택 취소하세요. 계정 생성 시 반드시 다운로드해야 하는 지갑 백업 파일을 사용하여 언제든지 새 계정에 액세스할 수 있습니다(로그아웃 후).",
|
||||||
"welmessage": "Qortal에 오신 것을 환영합니다.",
|
"welmessage": "Qortal에 오신 것을 환영합니다.",
|
||||||
"pleaseenter": "암호를 입력하십시오!",
|
"pleaseenter": "암호를 입력하십시오!",
|
||||||
"notmatch": "암호가 일치하지 않습니다!",
|
"notmatch": "암호가 일치하지 않습니다!",
|
||||||
@ -129,11 +129,11 @@
|
|||||||
"createdseed": "귀하의 시드구문",
|
"createdseed": "귀하의 시드구문",
|
||||||
"saveseed": "시드구문 저장",
|
"saveseed": "시드구문 저장",
|
||||||
"savein": "브라우저에 저장",
|
"savein": "브라우저에 저장",
|
||||||
"backup2": "이 파일은 앱/브라우저에 저장되지 않은 시스템의 계정에 액세스할 수 있는 유일한 방법입니다. 이 파일을 여러 곳에 백업하십시오. 파일은 매우 안전하게 암호화되고 이전 단계에서 만든 로컬 암호로 해독됩니다. 어디에나 안전하게 저장할 수 있지만 여러 위치에서 저장해야 합니다.",
|
"backup2": "Qortal 백업 파일은 UI에 저장되지 않는 한 (기본적으로) 계정에 액세스할 수 있는 유일한 방법입니다. 이 파일을 여러 장소에 백업해 두세요! 파일은 매우 안전하게 암호화되었으며 이전 단계에서 생성한 로컬 비밀번호로 해독됩니다. 어디에나 안전하게 저장할 수 있지만 반드시 여러 위치에 저장하세요.",
|
||||||
"savewallet": "지갑 백업 파일 저장",
|
"savewallet": "지갑 백업 파일 저장",
|
||||||
"created1": "이제 계정이 생성되었습니다.",
|
"created1": "이제 계정이 생성되었습니다.",
|
||||||
"created2": " 이 브라우저에 저장됩니다.",
|
"created2": " 암호화된 형태로 이 UI에 저장됩니다.",
|
||||||
"downloadbackup": "지갑 백업 파일 다운로드",
|
"downloadbackup": "Qortal 백업 파일을 저장하십시오.",
|
||||||
"passwordhint": "비밀번호는 5자 이상이어야 합니다.",
|
"passwordhint": "비밀번호는 5자 이상이어야 합니다.",
|
||||||
"lp1": "잠금 화면",
|
"lp1": "잠금 화면",
|
||||||
"lp2": "잠금 화면 암호가 설정되지 않았습니다!",
|
"lp2": "잠금 화면 암호가 설정되지 않았습니다!",
|
||||||
@ -164,7 +164,7 @@
|
|||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "파일선택",
|
"selectfile": "파일선택",
|
||||||
"dragfile": "백업을 여기에 드래그"
|
"dragfile": "끌어서 놓거나 여기를 클릭하여 백업 파일을 선택하세요."
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "일반 계정 정보",
|
"generalinfo": "일반 계정 정보",
|
||||||
@ -181,7 +181,7 @@
|
|||||||
"notifications": "알림",
|
"notifications": "알림",
|
||||||
"accountsecurity": "계정 보안",
|
"accountsecurity": "계정 보안",
|
||||||
"password": "비밀번호",
|
"password": "비밀번호",
|
||||||
"download": "백업 파일 다운로드",
|
"download": "Qortal 백업 파일 내보내기/저장",
|
||||||
"choose": "백업을 암호화할 암호를 선택하십시오. 암호는 로그인한 암호와 같거나 다를 수 있습니다.",
|
"choose": "백업을 암호화할 암호를 선택하십시오. 암호는 로그인한 암호와 같거나 다를 수 있습니다.",
|
||||||
"playsound": "소리 재생",
|
"playsound": "소리 재생",
|
||||||
"shownotifications": "알림 표시",
|
"shownotifications": "알림 표시",
|
||||||
@ -192,8 +192,8 @@
|
|||||||
"protocol": "프로토콜",
|
"protocol": "프로토콜",
|
||||||
"domain": "도메인",
|
"domain": "도메인",
|
||||||
"port": "포트",
|
"port": "포트",
|
||||||
"import": "노드 가져오기",
|
"import": "저장된 노드 가져오기",
|
||||||
"export": "노드 내보내기",
|
"export": "저장된 노드 내보내기",
|
||||||
"deletecustomnode": "모든 사용자 정의 노드 제거",
|
"deletecustomnode": "모든 사용자 정의 노드 제거",
|
||||||
"warning": "기존 노드가 삭제되고 백업에서 새로 생성됩니다.",
|
"warning": "기존 노드가 삭제되고 백업에서 새로 생성됩니다.",
|
||||||
"snack1": "표준 노드를 성공적으로 삭제 및 추가했습니다.",
|
"snack1": "표준 노드를 성공적으로 삭제 및 추가했습니다.",
|
||||||
@ -203,17 +203,17 @@
|
|||||||
"snack5": "노드를 성공적으로 가져왔습니다.",
|
"snack5": "노드를 성공적으로 가져왔습니다.",
|
||||||
"snack6": "사용자 정의 노드를 성공적으로 제거했습니다",
|
"snack6": "사용자 정의 노드를 성공적으로 제거했습니다",
|
||||||
"snack7": "사용자 정의 노드를 성공적으로 편집했습니다",
|
"snack7": "사용자 정의 노드를 성공적으로 편집했습니다",
|
||||||
"exp1": "개인 마스터 키 내보내기",
|
"exp1": "마스터 개인 키 내보내기(xpriv)",
|
||||||
"exp2": "마스터 키 내보내기",
|
"exp2": "마스터 키 내보내기",
|
||||||
"exp3": "내보내기",
|
"exp3": "내보내기",
|
||||||
"exp4": "개인 마스터 키를 백업할 지갑을 선택하세요.",
|
"exp4": "마스터 개인키 백업을 위한 지갑을 선택해주세요",
|
||||||
"core": "코어 설정 시작",
|
"core": "코어 설정 시작",
|
||||||
"qappNotification1": "Q-App 알림",
|
"qappNotification1": "Q-App 알림",
|
||||||
"selectnode": "옵션을 선택하세요",
|
"selectnode": "옵션을 선택하세요",
|
||||||
"arrr1": "ARRR 지갑이 초기화되지 않았습니다!",
|
"arrr1": "ARRR 지갑이 초기화되지 않음!",
|
||||||
"arrr2": "지갑 탭으로 이동하여 먼저 arrr 지갑을 초기화하세요.",
|
"arrr2": "'지갑'으로 이동하여 ARRR 지갑에 접속하여 먼저 초기화하세요.",
|
||||||
"arrr3": "핵심 업데이트가 필요합니다!",
|
"arrr3": "핵심 업데이트가 필요합니다!",
|
||||||
"arrr4": "arrr 지갑의 개인 키를 저장하려면 먼저 핵심 업데이트가 필요합니다!",
|
"arrr4": "ARRR 지갑의 개인 키를 저장하려면 먼저 Qortal Core를 업데이트해야 합니다!",
|
||||||
"sync_indicator": "동기화 표시 팝업 비활성화"
|
"sync_indicator": "동기화 표시 팝업 비활성화"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "균형",
|
"balance": "균형",
|
||||||
"balances": "지갑 잔액",
|
"balances": "지갑 잔액",
|
||||||
"update": "월렛 잔액 업데이트",
|
"update": "월렛 잔액 업데이트",
|
||||||
"view": "보다"
|
"view": "보다",
|
||||||
|
"all": "모두",
|
||||||
|
"page": "페이지"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Gif 탐색기",
|
"gchange1": "Gif 탐색기",
|
||||||
@ -284,14 +286,14 @@
|
|||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "발행 계정을 가져올 수 없습니다",
|
"smchange1": "발행 계정을 가져올 수 없습니다",
|
||||||
"smchange2": "키 제거 실패",
|
"smchange2": "키 제거 실패",
|
||||||
"smchange3": "발행 키를 추가하지 못했습니다.",
|
"smchange3": "'민팅 키' 추가에 실패했습니다. 키가 방금 생성된 경우 몇 블록을 기다렸다가 다시 추가해 보세요.",
|
||||||
"smchange4": "스폰서십 키를 생성할 수 없습니다.",
|
"smchange4": "스폰서십 키를 생성할 수 없습니다.",
|
||||||
"smchange5": "관계 만들기",
|
"smchange5": "관계 만들기",
|
||||||
"smchange6": "블록체인에서 확인 대기 중",
|
"smchange6": "블록체인에서 확인 대기 중",
|
||||||
"smchange7": "관계 마무리",
|
"smchange7": "관계 마무리",
|
||||||
"smchange8": "노드에 발행 키 추가",
|
"smchange8": "노드에 발행 키 추가",
|
||||||
"smchange9": "완벽한",
|
"smchange9": "완벽한",
|
||||||
"smchange10": "노드당 발행 키 2개만 허용됩니다. 키 3개를 할당하려고 합니다. 관리 - 노드 관리로 이동하여 이 노드에 할당하고 싶지 않은 키를 제거하십시오. 감사합니다!"
|
"smchange10": "노드당 2개의 '민팅 키'만 허용됩니다. 현재 3개의 키를 시도하고 있습니다. 노드 관리로 이동하여 불필요한 키를 제거하십시오. 감사합니다!"
|
||||||
},
|
},
|
||||||
"mintingpage": {
|
"mintingpage": {
|
||||||
"mchange1": "일반 민팅 정보",
|
"mchange1": "일반 민팅 정보",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "판매 가격",
|
"nchange23": "판매 가격",
|
||||||
"nchange24": "판매할 이름 없음",
|
"nchange24": "판매할 이름 없음",
|
||||||
"nchange25": "판매할 이름",
|
"nchange25": "판매할 이름",
|
||||||
"nchange26": "이 이름을 판매하시겠습니까?",
|
"nchange26": "이 이름을 판매하시겠습니까? 판매되면 이 이름으로 게시된 모든 데이터에 더 이상 액세스할 수 없습니다!",
|
||||||
"nchange27": "QORT에서 이 가격",
|
"nchange27": "QORT에서 이 가격",
|
||||||
"nchange28": "확인을 누르면 판매 이름 요청이 전송됩니다!",
|
"nchange28": "확인을 누르면 판매 이름 요청이 전송됩니다!",
|
||||||
"nchange29": "취소할 이름",
|
"nchange29": "취소할 이름",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "검색할 그룹 이름",
|
"gchange56": "검색할 그룹 이름",
|
||||||
"gchange57": "비공개 그룹 이름을 찾을 수 없음",
|
"gchange57": "비공개 그룹 이름을 찾을 수 없음",
|
||||||
"gchange58": "그룹 이름이 정확히 일치해야 합니다.",
|
"gchange58": "그룹 이름이 정확히 일치해야 합니다.",
|
||||||
"gchange59": "티커 표시/숨기기"
|
"gchange59": "티커 표시/숨기기",
|
||||||
|
"gchange60": "그룹 이름을 입력해 주세요.",
|
||||||
|
"gchange61": "설명을 입력하십시오.",
|
||||||
|
"gchange62": "이 그룹을 업데이트하시겠습니까?",
|
||||||
|
"gchange63": "CONFIRM을 누르면 UPDATE_GROUP 요청이 전송됩니다!",
|
||||||
|
"gchange64": "현재 소유자/새 소유자",
|
||||||
|
"gchange65": "이 주소를 그룹의 소유권 이전으로 바꾸십시오!",
|
||||||
|
"gchange66": "잘못된 소유자/새 소유자 주소",
|
||||||
|
"gchange67": "그룹 업데이트 성공!",
|
||||||
|
"gchange68": "그룹 아바타 설정"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "퍼즐",
|
"pchange1": "퍼즐",
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
"tm32": "Dit account volgt geen enkele gebruiker",
|
"tm32": "Dit account volgt geen enkele gebruiker",
|
||||||
"tm33": "Teb-menu importeren",
|
"tm33": "Teb-menu importeren",
|
||||||
"tm34": "Tab-menu exporteren",
|
"tm34": "Tab-menu exporteren",
|
||||||
"tm35": "Het huidige Tab-menu wordt verwijderd, en vervangen door het opgeladen Tab-menu.",
|
"tm35": "Uw bestaande tab-menu wordt verwijderd en ingesteld op het geïmporteerde tab-menu.",
|
||||||
"tm36": "Tab-menu werd opgeladen",
|
"tm36": "Tab-menu werd opgeladen",
|
||||||
"tm37": "Tab-Menü werd opgeslagen als",
|
"tm37": "Tab-Menü werd opgeslagen als",
|
||||||
"tm38": "DEV-MODUS",
|
"tm38": "DEV-MODUS",
|
||||||
@ -98,43 +98,43 @@
|
|||||||
"youraccounts": "Uw accounts",
|
"youraccounts": "Uw accounts",
|
||||||
"clickto": "Klik op uw account om aan te melden",
|
"clickto": "Klik op uw account om aan te melden",
|
||||||
"needcreate": "U moet een account aanmaken of bewaren, alvorens U kan aanmelden!",
|
"needcreate": "U moet een account aanmaken of bewaren, alvorens U kan aanmelden!",
|
||||||
"upload": "Qortal-Backup opladen",
|
"upload": "Importeer uw Qortal-backup-bestand",
|
||||||
"howlogin": "Hoe wenst U aan te melden?",
|
"howlogin": "Hoe wenst U aan te melden?",
|
||||||
"seed": "Memo-zin",
|
"seed": "Memo-zin",
|
||||||
"seedphrase": "memo-zin",
|
"seedphrase": "memo-zin",
|
||||||
"saved": "Opgeslagen account",
|
"saved": "Opgeslagen account",
|
||||||
"qora": "Qora adres",
|
"qora": "QORA-adres-memo",
|
||||||
"backup": "Backup van Qortal portefeuille",
|
"backup": "Qortal-backup-bestand",
|
||||||
"decrypt": "Backup ontcijferen",
|
"decrypt": "Backup-bestand decoderen",
|
||||||
"save": "Bewaren in deze browser.",
|
"save": "Bewaren in deze browser.",
|
||||||
"prepare": "Voorbereiding van uw account",
|
"prepare": "Voorbereiding van uw account",
|
||||||
"areyousure": "Bent U zeker dat U deze portefeuille wenst te verwijderen uit de bewaarde portefeuilles?",
|
"areyousure": "Weet U zeker dat U deze portefeuille uit de opgeslagen portefeuilles wilt verwijderen? (Als het wordt verwijderd en er geen backup-bestand bestaat, kan het account voor altijd verloren gaan! Zorg ervoor dat U over een backup-bestand beschikt voor U dit doet!)",
|
||||||
"error1": "De backup moet een geldig JSON formaat zijn",
|
"error1": "De backup moet een geldig JSON formaat zijn",
|
||||||
"error2": "Geen aanmeld-optie geselecteerd",
|
"error2": "Geen aanmeld-optie geselecteerd",
|
||||||
"createwelcome": "Welkom bij Qortal. U zal merken dat het vergelijkbaar is met een RPG-spel, waarbij U als 'minter' (als U 'minter' wil worden) in het Qortal-netwerk kan opklimmen naar volgende levels, waardoor U meer QORT-blokbeloning krijgt en meer invloed zal krijgen in het netwerk in termen van stemmen bij beslissingen voor het platform.",
|
"createwelcome": "Welkom bij Qortal! Uw gedecentraliseerde digitale toekomst wacht op u! Binnen Qortal bent U de enige die toegang heeft tot uw gegevens. Qortal biedt de laagdrempelige infrastructuur van een nieuwe, en volledig door de gebruiker bestuurde digitale wereld.",
|
||||||
"createa": "Een willekeurige",
|
"createa": "Een willekeurige",
|
||||||
"click": "Klik hier om uw memo-zin zichtbaar te maken",
|
"click": "Klik hier om uw memo-zin zichtbaar te maken",
|
||||||
"confirmpass": "Wachtwoord bevestigen",
|
"confirmpass": "Wachtwoord bevestigen",
|
||||||
"willbe": "zal in achtergrond gegenereerd worden. Deze wordt gebruikt als jouw private-sleutel-generator voor jouw blockchain-account in Qortal.",
|
"willbe": "wordt willekeurig op de achtergrond gegenereerd. Als u de memo-zin wilt BEKIJKEN, klikt u op de gemarkeerde 'memo-zin' in deze tekst. Dit wordt gebruikt als privé-sleutel-generator voor uw blockchain-account in Qortal. Uit veiligheidsoverwegingen worden memo-zinnen niet weergegeven, tenzij dit specifiek is gekozen.",
|
||||||
"clicknext": "Klik hieronder op VERDER om jouw Qortal-account aan te maken.",
|
"clicknext": "Klik hieronder op VERDER om jouw Qortal-account aan te maken.",
|
||||||
"ready": "Uw account is nu klaar om aan te maken. Het zal bewaard worden in deze browser. Heb je dat liever niet, dan kan je die optie hieronder deactivieren. Je kan je daarna met jouw nieuwe account aanmelden (na het afmelden), met behulp van de backup van je portefeuille, die je MOET DOWNLOADEN van zodra je account aangemaakt werd.",
|
"ready": "Uw account is nu klaar om te worden aangemaakt. Het wordt standaard in gecodeerde vorm opgeslagen binnen deze kopie van de Qortal-gebruikersinterface. Als U niet wilt dat uw nieuwe account hierin wordt opgeslagen, kunt U dit hieronder uitschakelen. U kunt nog steeds inloggen met uw nieuwe account (na het uitloggen), met behulp van uw Qortal-backup-bestand, dat U daarom MOET opslaan bij het aanmaken van uw account.",
|
||||||
"welmessage": "Welkom bij Qortal",
|
"welmessage": "Welkom bij Qortal",
|
||||||
"pleaseenter": "Geef een wachtwoord in!",
|
"pleaseenter": "Geef een wachtwoord in!",
|
||||||
"notmatch": "De wachtwoorden komen niet overeen!",
|
"notmatch": "Oeps! Wachtwoorden komen niet overeen! Probeer het nog eens!",
|
||||||
"lessthen8": "Uw wachtwoord is minder dan 5 karakters! Dat is niet aan te raden, maar je bent vrij om deze waarschuwing negeren.",
|
"lessthen8": "Uw wachtwoord is minder dan 5 karakters! Dat is niet aan te raden, maar je bent vrij om deze waarschuwing negeren.",
|
||||||
"lessthen8-2": "Uw wachtwoord is minder dan 5 karakters!",
|
"lessthen8-2": "Uw wachtwoord is minder dan 5 karakters!",
|
||||||
"entername": "Gelieve een naam in te geven!",
|
"entername": "Geef een weergavenaam op!",
|
||||||
"downloaded": "De backup van uw portefeuille werd gedownload!",
|
"downloaded": "Uw Qortal-backup-bestand is opgeslagen!",
|
||||||
"loading": "Bezig met laden. Even geduld...",
|
"loading": "Bezig met laden. Even geduld...",
|
||||||
"createdseed": "De memo-zin voor uw account",
|
"createdseed": "De memo-zin voor uw account:",
|
||||||
"saveseed": "Memo-zin bewaren",
|
"saveseed": "Memo-zin bewaren",
|
||||||
"savein": "In de browser bewaren",
|
"savein": "Bewaar in deze gebruikersinterface",
|
||||||
"backup2": "Dit bestand is de ENIGE manier om uw account te openen wanneer de browser/app op de computer uw account niet bewaard heeft. ZORG ERVOOR DAT JE DIT BESTAND OP MEERDERE PLAATSEN BEWAARD. Dit bestand werd uitermate veilig versleuteld op basis van het wachtwoord uit de vorige stap, wat de enige manier is om het te ontgrendelen. U kan dit bestand dus overal bewaren. Zorg zéker dat je dit bestand op verschillende plaatsen bewaard.",
|
"backup2": "Dit bestand is de ENIGE (standaard) manier om toegang te krijgen tot uw account, tenzij het is opgeslagen in de gebruikersinterface. ZORG ERVOOR DAT U OP MEERDERE PLAATSEN EEN BACKUP VAN DIT BESTAND BEWAARD. Dit bestand wordt uitermate veilig gecodeerd en gedecodeerd met het wachtwoord dat U in de vorige stap heeft aangemaakt. U kan dit bestand dus overal bewaren, en bij voorkeur zelfs op meerdere locaties.",
|
||||||
"savewallet": "Bewaar het backup-bestand van de portefeuille",
|
"savewallet": "Sla het Qortal-backup-bestand op",
|
||||||
"created1": "Uw account werd aangemaakt",
|
"created1": "Uw account werd aangemaakt",
|
||||||
"created2": " en werd in deze browser bewaard.",
|
"created2": " en werd in gecodeerde vorm opgeslagen in deze gebruikersinterface.",
|
||||||
"downloadbackup": "Download het backup-bestand van de portefeuille",
|
"downloadbackup": "Sla het Qortal-backup-bestand op",
|
||||||
"passwordhint": "Uw wachtwoord moet minstens 5 karakters lang zijn.",
|
"passwordhint": "Het versleutelingswachtwoord moet minimaal 5 tekens lang zijn.",
|
||||||
"lp1": "Scherm vergrendelen",
|
"lp1": "Scherm vergrendelen",
|
||||||
"lp2": "Er werd nog geen wachtwoord voor schermvergrendeling vastgelegd!",
|
"lp2": "Er werd nog geen wachtwoord voor schermvergrendeling vastgelegd!",
|
||||||
"lp3": "Gelieve dat nu te doen",
|
"lp3": "Gelieve dat nu te doen",
|
||||||
@ -163,8 +163,8 @@
|
|||||||
"confirmlogout": "Wenst U echt af te melden?"
|
"confirmlogout": "Wenst U echt af te melden?"
|
||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "Bestand selecteren",
|
"selectfile": "Selecteer het Qortal-backup-bestand",
|
||||||
"dragfile": "Sleep je backup-bestand naar hier"
|
"dragfile": "Sleep uw Qortal-backup-bestand naar hier, of klik hier om het te selecteren"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "Algemene account-informatie",
|
"generalinfo": "Algemene account-informatie",
|
||||||
@ -181,8 +181,8 @@
|
|||||||
"notifications": "Waarschuwingen",
|
"notifications": "Waarschuwingen",
|
||||||
"accountsecurity": "Account-beveiliging",
|
"accountsecurity": "Account-beveiliging",
|
||||||
"password": "Wachtwoord",
|
"password": "Wachtwoord",
|
||||||
"download": "Download backup-bestand",
|
"download": "Qortal-backup-bestand exporteren/opslaan",
|
||||||
"choose": "Kies een wachtwoord om het backup-bestand te versleutelen. (Dit kan hetzelfde zijn als bij aanmelding, of een ander)",
|
"choose": "Kies een wachtwoord om uw Qortal-backup-bestand te versleutelen. (Dit kan hetzelfde wachtwoord zijn als waarmee U bent ingelogd, of een ander.)",
|
||||||
"playsound": "Geluid afspelen",
|
"playsound": "Geluid afspelen",
|
||||||
"shownotifications": "Toon waarschuwingen",
|
"shownotifications": "Toon waarschuwingen",
|
||||||
"nodeurl": "Adres van de node",
|
"nodeurl": "Adres van de node",
|
||||||
@ -203,17 +203,17 @@
|
|||||||
"snack5": "Lijst van nodes werd geïmporteerd",
|
"snack5": "Lijst van nodes werd geïmporteerd",
|
||||||
"snack6": "Manueel toegevoegde nodes werd verwijderd",
|
"snack6": "Manueel toegevoegde nodes werd verwijderd",
|
||||||
"snack7": "Manueel toegevoegde nodes werd aangepast",
|
"snack7": "Manueel toegevoegde nodes werd aangepast",
|
||||||
"exp1": "Export/download jouw PRIVÉ hoofdsleutel",
|
"exp1": "Master-privé-sleutel exporteren (xpriv)",
|
||||||
"exp2": "Export/download jouw hoofdsleutel",
|
"exp2": "Export/download jouw hoofdsleutel",
|
||||||
"exp3": "Exporteren",
|
"exp3": "Exporteren",
|
||||||
"exp4": "Selecteer een portefeuille om de PRIVÉ hoofdsleutel te bewaren.",
|
"exp4": "Selecteer een portefeuille om de PRIVÉ hoofdsleutel te bewaren.",
|
||||||
"core": "Core-instellingen starten",
|
"core": "Core automatisch starten",
|
||||||
"qappNotification1": "Q-App waarschuwingen",
|
"qappNotification1": "Q-App waarschuwingen",
|
||||||
"selectnode": "Gelieve een optie te selecteren",
|
"selectnode": "Gelieve een optie te selecteren",
|
||||||
"arrr1": "ARRR portefeuille is niet geïnitialiseerd!",
|
"arrr1": "ARRR portefeuille is niet geïnitialiseerd!",
|
||||||
"arrr2": "Ga naar de portefeuille-tab en initialiseer eerst jouw ARRR portefeuille.",
|
"arrr2": "Ga naar de portefeuille-tab en open de ARRR-portefeuille om deze te initialiseren.",
|
||||||
"arrr3": "De 'core' heeft een update nodig!",
|
"arrr3": "De 'core' heeft een update nodig!",
|
||||||
"arrr4": "Om de privé-sleutel van jouw ARRR portefeuille te kunnen bewaren, moet je voor de 'core' eerst een update installeren!",
|
"arrr4": "Om de privé-sleutel van uw ARRR-portefeuille op te slaan, moet U eerst de Qortal Core updaten!",
|
||||||
"sync_indicator": "Synchronisatie-indicator pop-up uitschakelen"
|
"sync_indicator": "Synchronisatie-indicator pop-up uitschakelen"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "Saldo",
|
"balance": "Saldo",
|
||||||
"balances": "SALDI VAN UW PORTEFEUILLES",
|
"balances": "SALDI VAN UW PORTEFEUILLES",
|
||||||
"update": "SALDI VAN PORTEFEUILLES HEROPVRAGEN",
|
"update": "SALDI VAN PORTEFEUILLES HEROPVRAGEN",
|
||||||
"view": "Bekijken"
|
"view": "Bekijken",
|
||||||
|
"all": "Alle",
|
||||||
|
"page": "Bladzijde"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "GIF-Explorer",
|
"gchange1": "GIF-Explorer",
|
||||||
@ -283,15 +285,15 @@
|
|||||||
},
|
},
|
||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "Minting-accounts kunnen niet opgehaald worden",
|
"smchange1": "Minting-accounts kunnen niet opgehaald worden",
|
||||||
"smchange2": "Sleutel kon niet verwijderd worden",
|
"smchange2": "De Qortal-minting-sleutel kon niet verwijderd worden!",
|
||||||
"smchange3": "Mint-sleutel kon niet toegevoegd worden",
|
"smchange3": "Het is niet gelukt om de Qortal-minting-sleutel toe te wijzen. Als de sleutel net is aangemaakt, wacht dan een paar blokken en voeg opnieuw toe",
|
||||||
"smchange4": "Sponsor-sleutel kon niet aangemaakt worden",
|
"smchange4": "Sponsor-sleutel kon niet aangemaakt worden",
|
||||||
"smchange5": "Relatie wordt aangemaakt",
|
"smchange5": "Relatie wordt aangemaakt",
|
||||||
"smchange6": "Even wachten op confirmatie van de blockchain",
|
"smchange6": "Even wachten op confirmatie van de blockchain",
|
||||||
"smchange7": "Relatie wordt afgewerkt",
|
"smchange7": "Relatie wordt afgewerkt",
|
||||||
"smchange8": "Mint-sleutel wordt op node toegevoegd",
|
"smchange8": "Mint-sleutel wordt op node toegevoegd",
|
||||||
"smchange9": "Klaar",
|
"smchange9": "Klaar",
|
||||||
"smchange10": "Een node mag maximum 2 mint-sleutels hebben, en U probeert 3 keys toe te wijzen; Ga eerst naar Node-beheer en verwijder de key die U niet aan deze node wenst toe te wijzen; Dank U!"
|
"smchange10": "Per node zijn slechts 2 sleutels toegestaan. U probeert 3 sleutels toe te wijzen. Ga naar Node-beheer en verwijder eventuele onnodige sleutels; Dank U!"
|
||||||
},
|
},
|
||||||
"mintingpage": {
|
"mintingpage": {
|
||||||
"mchange1": "Algemene Minting-details",
|
"mchange1": "Algemene Minting-details",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "Verkoopprijs",
|
"nchange23": "Verkoopprijs",
|
||||||
"nchange24": "Geen namen om te verkopen",
|
"nchange24": "Geen namen om te verkopen",
|
||||||
"nchange25": "Te verkopen naam",
|
"nchange25": "Te verkopen naam",
|
||||||
"nchange26": "Bent U zeker dat U deze naam wenst te verkopen?",
|
"nchange26": "Weet U zeker dat U deze naam wenst te verkopen? Als de naam wordt aangekocht door een andere account, kunnen de gegevens die onder deze naam zijn gepubliceerd, niet langer door U worden gewijzigd!",
|
||||||
"nchange27": "Voor deze prijs in QORT",
|
"nchange27": "Voor deze prijs in QORT",
|
||||||
"nchange28": "Als je nu bevestigen kiest, dan wordt de verkoop-aanvraag verzonden!",
|
"nchange28": "Als je nu bevestigen kiest, dan wordt de verkoop-aanvraag verzonden!",
|
||||||
"nchange29": "Te onderbreken naam-verkoop",
|
"nchange29": "Te onderbreken naam-verkoop",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "Te zoeken groepsnaam",
|
"gchange56": "Te zoeken groepsnaam",
|
||||||
"gchange57": "Geen privé-groep gevonden voor opgegeven naam",
|
"gchange57": "Geen privé-groep gevonden voor opgegeven naam",
|
||||||
"gchange58": "Hou er rekening mee dat de groepsnaam exact overeen moet komen.",
|
"gchange58": "Hou er rekening mee dat de groepsnaam exact overeen moet komen.",
|
||||||
"gchange59": "Ticker wel/niet tonen"
|
"gchange59": "Ticker wel/niet tonen",
|
||||||
|
"gchange60": "Voer de groepsnaam in",
|
||||||
|
"gchange61": "Voer een beschrijving in",
|
||||||
|
"gchange62": "Weet je zeker dat je deze groep wil UPDATEN?",
|
||||||
|
"gchange63": "Bij confirmatie wordt het UPDATE_GROUP verzoek verzonden!",
|
||||||
|
"gchange64": "Huidige eigenaar / nieuwe eigenaar",
|
||||||
|
"gchange65": "Vervang dit adres enkel als U de EIGENDOM van de groep wenst OVER TE DRAGEN!",
|
||||||
|
"gchange66": "Ongeldig adres van huidige of nieuwe eigenaar",
|
||||||
|
"gchange67": "Groep UPDATE succesvol uitgevoerd!",
|
||||||
|
"gchange68": "Groepsavatar instellen"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Puzzels",
|
"pchange1": "Puzzels",
|
||||||
@ -1176,7 +1187,7 @@
|
|||||||
"inf7": "Informatie over automatische aankoop",
|
"inf7": "Informatie over automatische aankoop",
|
||||||
"inf8": "Info over automatische aankoop sluiten",
|
"inf8": "Info over automatische aankoop sluiten",
|
||||||
"inf9": "'Automatische aamkoop' is een functie waarmee je 'aankoop-orders' op het handelsportaal kan plaatsen. Die 'aankoop-orders' zijn enkel zichtbaar voor de persoon die ze plaatst. Het zijn geen 'publiek zichtbare orders' zoals de 'open-markt-verkoop-orders' en ze worden NIET op de Qortal blockchain bewaard. 'Automatische aankoop' is een UI-functie, die bij gevolg enkel werkt zolang de UI blijft draaien.",
|
"inf9": "'Automatische aamkoop' is een functie waarmee je 'aankoop-orders' op het handelsportaal kan plaatsen. Die 'aankoop-orders' zijn enkel zichtbaar voor de persoon die ze plaatst. Het zijn geen 'publiek zichtbare orders' zoals de 'open-markt-verkoop-orders' en ze worden NIET op de Qortal blockchain bewaard. 'Automatische aankoop' is een UI-functie, die bij gevolg enkel werkt zolang de UI blijft draaien.",
|
||||||
"inf10": "Om via 'Automatiche aankoop' een bestelling te plaatsen, klik je op 'auto-aankoop toevoegen' en vul je de velden in het dialoogje in. Geef het QORT-BEDRAG in dat je wenst te KOPEN, en de MAXIMUM PRIJS DIE JE ERVOOR WIL BETALEN. Zodra de bestelling actief is, zal 'Auto aankoop' QORT aankopen tot het opgegeven QORT-BEDRAG en daarbij maximum de door jou vastgelegde prijs, én beginnend bij de laagst aangeboden verkoop-prijs in het verkoop-orderboek.",
|
"inf10": "Om via 'Automatiche aankoop' een bestelling te plaatsen, klikt U op de knop 'auto-aankoop toevoegen' en vult U het vakje in dat verschijnt. Voer het BEDRAG VAN QORT in dat U wilt KOPEN of het aantal LTC dat U wilt gebruiken, en de PRIJS waartoe u bereid bent te KOPEN. Zodra de bestelling actief is, koopt 'Automatische aankoop' TOT dat bedrag QORT voor U, tegen TOT de prijs die U instelt (beginnend bij de laagste bestelling en hogerop in het verkoop-orderboek).",
|
||||||
"inf11": "Laat vervolgens de UI gewoon open staan, en de 'auto aankoop' functie doet de rest, volledig automatisch!",
|
"inf11": "Laat vervolgens de UI gewoon open staan, en de 'auto aankoop' functie doet de rest, volledig automatisch!",
|
||||||
"inf12": "Je KAN ondertussen ook gewoon andere Qortal UI plugins gebruiken (Q-Chat, Portefeuille, etc), maar je mag DE UI NIET SLUITEN, als je wil dat 'Auto aankoop' functie blijft werken. De UI 'minimized' zetten (op de 'taskbar' of 'panel') mag wel. Zolang UI actief is, blijft de 'Auto aankoop' functie werken.",
|
"inf12": "Je KAN ondertussen ook gewoon andere Qortal UI plugins gebruiken (Q-Chat, Portefeuille, etc), maar je mag DE UI NIET SLUITEN, als je wil dat 'Auto aankoop' functie blijft werken. De UI 'minimized' zetten (op de 'taskbar' of 'panel') mag wel. Zolang UI actief is, blijft de 'Auto aankoop' functie werken.",
|
||||||
"inf13": "Automatisch aankopen",
|
"inf13": "Automatisch aankopen",
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
"tm32": "Denne kontoen følger ikke noen bruker",
|
"tm32": "Denne kontoen følger ikke noen bruker",
|
||||||
"tm33": "Importer meny",
|
"tm33": "Importer meny",
|
||||||
"tm34": "Eksporter fanemeny",
|
"tm34": "Eksporter fanemeny",
|
||||||
"tm35": "Din eksisterende fanemeny vil bli slettet og satt til opplastet fanemeny.",
|
"tm35": "Din eksisterende fanemeny vil bli slettet og satt til importert fanemeny.",
|
||||||
"tm36": "Fanemenyen ble gjenopprettet",
|
"tm36": "Fanemenyen ble gjenopprettet",
|
||||||
"tm37": "Fanemeny ble lagret som",
|
"tm37": "Fanemeny ble lagret som",
|
||||||
"tm38": "DEV MODUS",
|
"tm38": "DEV MODUS",
|
||||||
@ -108,19 +108,19 @@
|
|||||||
"decrypt": "Dekrypter backup",
|
"decrypt": "Dekrypter backup",
|
||||||
"save": "Lagre i denne nettleseren.",
|
"save": "Lagre i denne nettleseren.",
|
||||||
"prepare": "Forbereder kontoen din.",
|
"prepare": "Forbereder kontoen din.",
|
||||||
"areyousure": "Er du sikker på at du vil fjerne denne lommeboken fra lagrede lommebøker?",
|
"areyousure": "Er du sikker på at du vil fjerne denne kontoen fra lagrede kontoer? (Hvis fjernet og ingen sikkerhetskopifil eksisterer, kan kontoen gå tapt for alltid! Sørg for at du har en sikkerhetskopifil før du gjør dette!)",
|
||||||
"error1": "Backupen må være gyldig JSON",
|
"error1": "Backupen må være gyldig JSON",
|
||||||
"error2": "Måte for pålogging ikke valgt",
|
"error2": "Måte for pålogging ikke valgt",
|
||||||
"createwelcome": "Velkommen til Qortal. Likt et RPG-spill, vil du som minter i Qortal-nettverket (hvis du velger å bli det), ha sjansen til å øke din kontos nivå, noe som gir deg både mer av QORT-blokkbelønning, så vel som større innflytelse over nettverket når det gjelder å stemme på beslutninger for plattformen.",
|
"createwelcome": "Velkommen til Qortal! Din desentraliserte digitale fremtid venter på deg! I Qortal har du og bare du full kontroll over dataene dine. Qortal gir infrastrukturen til en ny og fullt brukerstyrt digital verden.",
|
||||||
"createa": "A",
|
"createa": "A",
|
||||||
"click": "Klikk for å se minnefrase (seedphrase)",
|
"click": "Klikk for å se minnefrase (seedphrase)",
|
||||||
"confirmpass": "Bekreft passord",
|
"confirmpass": "Bekreft passord",
|
||||||
"willbe": "vil bli generert tilfeldig i bakgrunnen. Dette brukes som din private nøkkelgenerator for din blokkjedekonto i Qortal.",
|
"willbe": "vil bli generert tilfeldig i bakgrunnen. Hvis du ønsker å SE seedfrasen, klikk på den uthevede 'seedfrasen' i denne teksten. Dette brukes som din private nøkkelgenerator for din blokkjedekonto i Qortal. For sikkerhet som standard, vises ikke seedfraser med mindre det er spesifikt valgt å være det.",
|
||||||
"clicknext": "Opprett din Qortal-konto ved å klikke på NESTE nedenfor.",
|
"clicknext": "Opprett din Qortal-konto ved å klikke på NESTE nedenfor.",
|
||||||
"ready": "Kontoen din er nå klar til å opprettes. Den vil bli lagret i denne nettleseren. Hvis du ikke vil at den nye kontoen din skal lagres i nettleseren, kan du fjerne avhukningen i boksen nedenfor. Du vil fortsatt kunne logge på med den nye kontoen din (etter å ha logget av), ved å bruke backup-filen for lommeboken som du MÅ laste ned når du har opprettet kontoen din.",
|
"ready": "Kontoen din er nå klar til å opprettes. Den vil som standard lagres i denne kopien av Qortal-grensesnittet, i kryptert form. Hvis du ikke vil at den nye kontoen din skal lagres her, kan du fjerne merket i boksen nedenfor. Du vil fortsatt kunne logge på med den nye kontoen din (etter å ha logget ut), ved å bruke sikkerhetskopifilen for lommeboken som du MÅ laste ned når du har opprettet kontoen din.",
|
||||||
"welmessage": "Velkommen til Qortal",
|
"welmessage": "Velkommen til Qortal",
|
||||||
"pleaseenter": "Skriv inn et passord!",
|
"pleaseenter": "Skriv inn et passord!",
|
||||||
"notmatch": "Passord matcher ikke!",
|
"notmatch": "Oops! Passordene samsvarer ikke! Prøv igjen!",
|
||||||
"lessthen8": "Passordet ditt er mindre enn 5 tegn! Dette anbefales ikke. Du kan velge å fortsette, og ignorere denne advarselen.",
|
"lessthen8": "Passordet ditt er mindre enn 5 tegn! Dette anbefales ikke. Du kan velge å fortsette, og ignorere denne advarselen.",
|
||||||
"lessthen8-2": "Passordet ditt er mindre enn 5 tegn!",
|
"lessthen8-2": "Passordet ditt er mindre enn 5 tegn!",
|
||||||
"entername": "Skriv inn et navn!",
|
"entername": "Skriv inn et navn!",
|
||||||
@ -132,7 +132,7 @@
|
|||||||
"backup2": "Denne filen er den ENESTE måten å få tilgang på kontoen din i et system hvor den ikke lagres i appen/nettleseren. SØRG FOR Å LAGE BACKUP AV DENNE FILEN PÅ FLERE STEDER. Filen er kryptert veldig sikkert og dekrypteres med ditt lokale passord som du opprettet i forrige trinn. Du kan trygt lagre den hvor som helst, men sørg for å gjøre det på flere steder.",
|
"backup2": "Denne filen er den ENESTE måten å få tilgang på kontoen din i et system hvor den ikke lagres i appen/nettleseren. SØRG FOR Å LAGE BACKUP AV DENNE FILEN PÅ FLERE STEDER. Filen er kryptert veldig sikkert og dekrypteres med ditt lokale passord som du opprettet i forrige trinn. Du kan trygt lagre den hvor som helst, men sørg for å gjøre det på flere steder.",
|
||||||
"savewallet": "Lagre backup-fil for lommebok",
|
"savewallet": "Lagre backup-fil for lommebok",
|
||||||
"created1": "Kontoen din er nå opprettet",
|
"created1": "Kontoen din er nå opprettet",
|
||||||
"created2": " og vil bli lagret i denne nettleseren.",
|
"created2": " og lagret i denne UI i kryptert form.",
|
||||||
"downloadbackup": "Last ned backup-fil for lommebok",
|
"downloadbackup": "Last ned backup-fil for lommebok",
|
||||||
"passwordhint": "Et passord må være på minst 5 tegn.",
|
"passwordhint": "Et passord må være på minst 5 tegn.",
|
||||||
"lp1": "Lås skjerm",
|
"lp1": "Lås skjerm",
|
||||||
@ -163,8 +163,8 @@
|
|||||||
"confirmlogout": "Er du sikker på at du vil logge av?"
|
"confirmlogout": "Er du sikker på at du vil logge av?"
|
||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "Velg fil",
|
"selectfile": "Velg sikkerhetskopifil",
|
||||||
"dragfile": "Dra og slipp backup her"
|
"dragfile": "Dra og slipp eller klikk her for å velge sikkerhetskopifil"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "Generell kontoinformasjon",
|
"generalinfo": "Generell kontoinformasjon",
|
||||||
@ -203,17 +203,17 @@
|
|||||||
"snack5": "Noder ble importert",
|
"snack5": "Noder ble importert",
|
||||||
"snack6": "Tilpasset node er fjernet",
|
"snack6": "Tilpasset node er fjernet",
|
||||||
"snack7": "Redigert tilpasset node",
|
"snack7": "Redigert tilpasset node",
|
||||||
"exp1": "Eksporter privat hovednøkkel",
|
"exp1": "Eksporter privat hovednøkkel (xpriv)",
|
||||||
"exp2": "Eksporter hovednøkkel",
|
"exp2": "Eksporter hovednøkkel",
|
||||||
"exp3": "Eksporter",
|
"exp3": "Eksporter",
|
||||||
"exp4": "Velg en lommebok for å sikkerhetskopiere den private hovednøkkelen.",
|
"exp4": "Velg en lommebok for å sikkerhetskopiere den private hovednøkkelen.",
|
||||||
"core": "Start kjerneinnstillinger",
|
"core": "Kjerneinnstillinger for automatisk start",
|
||||||
"qappNotification1": "Q-App varsler",
|
"qappNotification1": "Q-App varsler",
|
||||||
"selectnode": "Vennligst velg et alternativ",
|
"selectnode": "Vennligst velg et alternativ",
|
||||||
"arrr1": "ARRR-lommebok ikke initialisert !",
|
"arrr1": "ARRR-lommebok ikke initialisert !",
|
||||||
"arrr2": "Vennligst gå til lommebok-fanen og initialiser arrr-lommeboken først.",
|
"arrr2": "Gå til lommebok-fanen og få tilgang til ARRR-lommeboken for å initialisere lommeboken først.",
|
||||||
"arrr3": "Trenger kjerneoppdatering!",
|
"arrr3": "Trenger kjerneoppdatering!",
|
||||||
"arrr4": "For å lagre den private nøkkelen til arrr-lommeboken din trenger du en kjerneoppdatering først!",
|
"arrr4": "For å lagre den private nøkkelen til ARRR-lommeboken din må du først oppdatere Qortal Core!",
|
||||||
"sync_indicator": "Deaktiver popup for synkroniseringsindikator"
|
"sync_indicator": "Deaktiver popup for synkroniseringsindikator"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "Saldo",
|
"balance": "Saldo",
|
||||||
"balances": "DIN WALLET-SALDO",
|
"balances": "DIN WALLET-SALDO",
|
||||||
"update": "OPPDATERT WALLET-SALDOER",
|
"update": "OPPDATERT WALLET-SALDOER",
|
||||||
"view": "Utsikt"
|
"view": "Utsikt",
|
||||||
|
"all": "Alle",
|
||||||
|
"page": "Side"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Gif Explorer",
|
"gchange1": "Gif Explorer",
|
||||||
@ -284,7 +286,7 @@
|
|||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "Kan ikke hente myntingkontoer",
|
"smchange1": "Kan ikke hente myntingkontoer",
|
||||||
"smchange2": "Kunne ikke fjerne nøkkelen",
|
"smchange2": "Kunne ikke fjerne nøkkelen",
|
||||||
"smchange3": "Kunne ikke legge til myntnøkkel",
|
"smchange3": "Kunne ikke legge til myntnøkkel, hvis nøkkelen nettopp ble opprettet, prøv å vente noen blokker og legg til på nytt.",
|
||||||
"smchange4": "Kan ikke opprette sponsornøkkel",
|
"smchange4": "Kan ikke opprette sponsornøkkel",
|
||||||
"smchange5": "Skaper forhold",
|
"smchange5": "Skaper forhold",
|
||||||
"smchange6": "Venter på bekreftelse på blockchain",
|
"smchange6": "Venter på bekreftelse på blockchain",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "Selgspris",
|
"nchange23": "Selgspris",
|
||||||
"nchange24": "Ingen navn å selge",
|
"nchange24": "Ingen navn å selge",
|
||||||
"nchange25": "Navn å selge",
|
"nchange25": "Navn å selge",
|
||||||
"nchange26": "Er du sikker på å selge dette navnet?",
|
"nchange26": "Er du sikker på å selge dette navnet? Hvis navnet er kjøpt av en annen konto, vil alle data publisert av den være utenfor din kontroll!",
|
||||||
"nchange27": "For denne prisen i QORT",
|
"nchange27": "For denne prisen i QORT",
|
||||||
"nchange28": "Når du trykker bekrefte, vil forespørselen om salgsnavn bli sendt!",
|
"nchange28": "Når du trykker bekrefte, vil forespørselen om salgsnavn bli sendt!",
|
||||||
"nchange29": "Navn som skal avbrytes",
|
"nchange29": "Navn som skal avbrytes",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "Gruppenavn å søke",
|
"gchange56": "Gruppenavn å søke",
|
||||||
"gchange57": "Privat gruppenavn ikke funnet",
|
"gchange57": "Privat gruppenavn ikke funnet",
|
||||||
"gchange58": "Merk at gruppenavnet må samsvare nøyaktig.",
|
"gchange58": "Merk at gruppenavnet må samsvare nøyaktig.",
|
||||||
"gchange59": "Vis / Skjul Ticker"
|
"gchange59": "Vis / Skjul Ticker",
|
||||||
|
"gchange60": "Vennligst skriv inn gruppenavn",
|
||||||
|
"gchange61": "Vennligst skriv inn beskrivelse",
|
||||||
|
"gchange62": "Er du sikker på å oppdatere denne gruppen?",
|
||||||
|
"gchange63": "Når du trykker på BEKREFT, vil den UPDATE_GROUP forespørselen bli sendt!",
|
||||||
|
"gchange64": "Nåværende eier / ny eier",
|
||||||
|
"gchange65": "Erstatt denne adressen til OVERFØR EIERSKAP av gruppen!",
|
||||||
|
"gchange66": "Ugyldig eier / ny eieradresse",
|
||||||
|
"gchange67": "Gruppeoppdatering vellykket!",
|
||||||
|
"gchange68": "Angi gruppeavatar"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Puzzles",
|
"pchange1": "Puzzles",
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
"tm32": "To konto nie obserwuje żadnego użytkownika",
|
"tm32": "To konto nie obserwuje żadnego użytkownika",
|
||||||
"tm33": "Menu zakładki Importuj",
|
"tm33": "Menu zakładki Importuj",
|
||||||
"tm34": "Menu zakładki Eksportuj",
|
"tm34": "Menu zakładki Eksportuj",
|
||||||
"tm35": "Twoje istniejące menu kart zostanie usunięte i ustawione na przesłane menu kart.",
|
"tm35": "Twoje istniejące menu zakładek zostanie usunięte i ustawione jako zaimportowane menu zakładek.",
|
||||||
"tm36": "Menu zakładki pomyślnie przywrócone",
|
"tm36": "Menu zakładki pomyślnie przywrócone",
|
||||||
"tm37": "Menu zakładki pomyślnie zapisane jako",
|
"tm37": "Menu zakładki pomyślnie zapisane jako",
|
||||||
"tm38": "TRYB DEV",
|
"tm38": "TRYB DEV",
|
||||||
@ -98,43 +98,43 @@
|
|||||||
"youraccounts": "Twoje konta",
|
"youraccounts": "Twoje konta",
|
||||||
"clickto": "Kliknij swoje konto, aby się na nim zalogować",
|
"clickto": "Kliknij swoje konto, aby się na nim zalogować",
|
||||||
"needcreate": "Musisz utworzyć lub zapisać konto, zanim będziesz mógł się zalogować!",
|
"needcreate": "Musisz utworzyć lub zapisać konto, zanim będziesz mógł się zalogować!",
|
||||||
"upload": "Prześlij swoją kopię zapasową Qortal",
|
"upload": "Zaimportuj plik kopii zapasowej Qortal",
|
||||||
"howlogin": "Jak chciałbyś się zalogować?",
|
"howlogin": "Jak chciałbyś się zalogować?",
|
||||||
"seed": "Fraza odzyskiwania",
|
"seed": "Fraza odzyskiwania",
|
||||||
"seedphrase": "fraza odzyskiwania",
|
"seedphrase": "fraza odzyskiwania",
|
||||||
"saved": "Zapisane konto",
|
"saved": "Zapisane konto",
|
||||||
"qora": "Ziarno adresu Qora",
|
"qora": "Ziarno adresu QORA",
|
||||||
"backup": "Kopia zapasowa portfela Qortal",
|
"backup": "Plik kopii zapasowej Qortal",
|
||||||
"decrypt": "Odszyfruj kopię zapasową",
|
"decrypt": "Odszyfruj plik kopii zapasowej",
|
||||||
"save": "Zapisz w tej przeglądarce.",
|
"save": "Zapisz w tej przeglądarce.",
|
||||||
"prepare": "Przygotuj swoje konto",
|
"prepare": "Przygotuj swoje konto",
|
||||||
"areyousure": "Czy na pewno chcesz usunąć ten portfel z zapisanych portfeli?",
|
"areyousure": "Czy na pewno chcesz usunąć to konto z zapisanych kont? (W przypadku usunięcia i braku pliku kopii zapasowej konto może zostać utracone na zawsze! Zanim to zrobisz, upewnij się, że masz plik kopii zapasowej!)",
|
||||||
"error1": "Kopia zapasowa musi być poprawnym JSON",
|
"error1": "Kopia zapasowa musi być poprawnym JSON",
|
||||||
"error2": "Nie wybrano opcji logowania",
|
"error2": "Nie wybrano opcji logowania",
|
||||||
"createwelcome": "Witamy w Qortal, przekonasz się, że jest to gra podobna do gry RPG, ty, jako minter w sieci Qortal (jeśli zdecydujesz się nią zostać), będziesz miał szansę ulepszyć swoje konto, zyskując więcej nagrody za blok QORT, jak i większy wpływ na sieć w zakresie głosowania na decyzje dotyczące platformy.",
|
"createwelcome": "Witamy w Qortalu! Twoja zdecentralizowana cyfrowa przyszłość czeka na Ciebie! W Qortal Ty i tylko Ty masz pełną kontrolę nad swoimi danymi. Qortal zapewnia podstawowy poziom nowego, w pełni kontrolowanego przez użytkownika cyfrowego świata.",
|
||||||
"createa": "A",
|
"createa": "A",
|
||||||
"click": "Kliknij, aby zobaczyć frazę odzyskiwania portfela",
|
"click": "Kliknij, aby zobaczyć frazę odzyskiwania portfela",
|
||||||
"confirmpass": "Potwierdź hasło",
|
"confirmpass": "Potwierdź hasło",
|
||||||
"willbe": "zostanie losowo wygenerowany w tle. To jest używane jako generator klucza prywatnego dla Twojego konta blockchain w Qortal.",
|
"willbe": "będą losowo generowane w tle. Jeśli chcesz ZOBACZYĆ frazę nasion, kliknij słowo „fraza nasion” w tym tekście. Służy jako generator klucza prywatnego dla Twojego konta Blockchain w Qortal. Ze względów bezpieczeństwa domyślnie frazy początkowe nie są wyświetlane, chyba że zostało to specjalnie wybrane.",
|
||||||
"clicknext": "Utwórz swoje konto Qortal, klikając przycisk NEXT (DALEJ) poniżej.",
|
"clicknext": "Utwórz swoje konto Qortal, klikając przycisk NEXT (DALEJ) poniżej.",
|
||||||
"ready": "Twoje konto jest teraz gotowe do utworzenia. Zostanie zapisane w tej przeglądarce. Jeśli nie chcesz, aby Twoje nowe konto było zapisywane w przeglądarce, możesz odznaczyć poniższe pole. Nadal będziesz mógł logować się na nowe konto (po wylogowaniu), korzystając z pliku kopii zapasowej portfela, który MUSISZ pobrać po utworzeniu konta.",
|
"ready": "Twoje konto jest teraz gotowe do utworzenia. Zostanie on domyślnie zapisany w tej kopii interfejsu użytkownika Qortal, w formie zaszyfrowanej. Jeśli nie chcesz, aby Twoje nowe konto było tutaj zapisywane, możesz odznaczyć pole poniżej. Nadal będziesz mógł zalogować się na swoje nowe konto (po wylogowaniu), korzystając z pliku kopii zapasowej portfela, który MUSISZ pobrać po utworzeniu konta.",
|
||||||
"welmessage": "Witamy w Qortal",
|
"welmessage": "Witamy w Qortal",
|
||||||
"pleaseenter": "Proszę wprowadzić Hasło!",
|
"pleaseenter": "Proszę wprowadzić Hasło!",
|
||||||
"notmatch": "Hasła nie pasują!",
|
"notmatch": "Hasła nie pasują!",
|
||||||
"lessthen8": "Twoje hasło ma mniej niż 5 znaków! Nie jest to zalecane. Możesz zignorować to ostrzeżenie.",
|
"lessthen8": "Twoje hasło ma mniej niż 5 znaków! Nie jest to zalecane. Możesz zignorować to ostrzeżenie.",
|
||||||
"lessthen8-2": "Twoje hasło ma mniej niż 5 znaków!",
|
"lessthen8-2": "Twoje hasło ma mniej niż 5 znaków!",
|
||||||
"entername": "Proszę podać Nazwę!",
|
"entername": "Proszę wprowadzić nazwę wyświetlaną!",
|
||||||
"downloaded": "Twój plik kopii zapasowej Portfela zostanie pobrany!",
|
"downloaded": "Twój plik kopii zapasowej Portfela został zapisany!",
|
||||||
"loading": "Ładowanie, proszę czekać...",
|
"loading": "Ładowanie, proszę czekać...",
|
||||||
"createdseed": "Twoja utworzona fraza odzyskiwania",
|
"createdseed": "Twoja utworzona fraza odzyskiwania",
|
||||||
"saveseed": "Zapisz frazę odzyskiwania",
|
"saveseed": "Zapisz frazę odzyskiwania",
|
||||||
"savein": "Zapisz w przeglądarce",
|
"savein": "Zapisz w tym interfejsie użytkownika",
|
||||||
"backup2": "Ten plik jest JEDYNYM sposobem uzyskania dostępu do konta w systemie, jeżeli nie ma go zapisanego w aplikacji/przeglądarce. PAMIĘTAJ, ABY ZAPISAĆ KOPIĘ ZAPASOWĄ TEGO PLIKU W WIELU MIEJSCACH. Plik jest bezpiecznie zaszyfrowany i może być odszyfrowany za pomocą Twojego hasła utworzonego w poprzednim kroku. Możesz go bezpiecznie zapisać w dowolnym miejscu, ale pamiętaj, aby zrobić to w wielu lokalizacjach.",
|
"backup2": "Ten plik jest JEDYNYM (domyślnym) sposobem uzyskania dostępu do Twojego konta, chyba że zostanie zapisany w interfejsie użytkownika. NALEŻY ZROBIĆ KOPIĘ ZAPASOWĄ TEGO PLIKU W WIELU MIEJSCACH. Plik zostanie bardzo bezpiecznie zaszyfrowany i odszyfrowany za pomocą lokalnego hasła utworzonego w poprzednim kroku. Możesz bezpiecznie zapisać go w dowolnym miejscu, ale pamiętaj, aby zrobić to w wielu lokalizacjach.",
|
||||||
"savewallet": "Zapisz plik kopii zapasowej portfela",
|
"savewallet": "Zapisz plik kopii zapasowej portfela",
|
||||||
"created1": "Twoje konto zostało utworzone",
|
"created1": "Twoje konto zostało utworzone",
|
||||||
"created2": " i zostanie zapisane w tej przeglądarce.",
|
"created2": " i zapisane w tym interfejsie użytkownika w formie zaszyfrowanej.",
|
||||||
"downloadbackup": "Pobierz plik kopii zapasowej portfela",
|
"downloadbackup": "Zapisz plik kopii zapasowej Qortal",
|
||||||
"passwordhint": "Hasło musi mieć co najmniej 5 znaków.",
|
"passwordhint": "Hasło szyfrujące musi składać się z co najmniej 5 znaków.",
|
||||||
"lp1": "Ekran blokady",
|
"lp1": "Ekran blokady",
|
||||||
"lp2": "Nie ustawiono hasła blokady ekranu!",
|
"lp2": "Nie ustawiono hasła blokady ekranu!",
|
||||||
"lp3": "Proszę ustawić jeden",
|
"lp3": "Proszę ustawić jeden",
|
||||||
@ -163,8 +163,8 @@
|
|||||||
"confirmlogout": "Czy na pewno chcesz się wylogować?"
|
"confirmlogout": "Czy na pewno chcesz się wylogować?"
|
||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "Wybierz plik",
|
"selectfile": "Wybierz plik kopii zapasowej",
|
||||||
"dragfile": "Przeciągnij i upuść kopię zapasową tutaj"
|
"dragfile": "Przeciągnij i upuść lub kliknij tutaj, aby wybrać plik kopii zapasowej"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "Ogólne informacje o koncie",
|
"generalinfo": "Ogólne informacje o koncie",
|
||||||
@ -203,17 +203,17 @@
|
|||||||
"snack5": "Węzły pomyślnie zaimportowane",
|
"snack5": "Węzły pomyślnie zaimportowane",
|
||||||
"snack6": "Pomyślnie usunięto węzeł niestandardowy",
|
"snack6": "Pomyślnie usunięto węzeł niestandardowy",
|
||||||
"snack7": "Pomyślnie edytowano węzeł niestandardowy",
|
"snack7": "Pomyślnie edytowano węzeł niestandardowy",
|
||||||
"exp1": "Eksportuj prywatny klucz główny",
|
"exp1": "Eksportuj główny klucz prywatny (xpriv)",
|
||||||
"exp2": "Eksportuj klucz główny",
|
"exp2": "Eksportuj klucz główny",
|
||||||
"exp3": "Eksportuj",
|
"exp3": "Eksportuj",
|
||||||
"exp4": "Wybierz portfel do wykonania kopii zapasowej prywatnego klucza głównego.",
|
"exp4": "Wybierz portfel do wykonania kopii zapasowej prywatnego klucza głównego.",
|
||||||
"core": "Uruchom podstawowe ustawienia",
|
"core": "Ustawienia automatycznego uruchamiania Qortal Core",
|
||||||
"qappNotification1": "Powiadomienia Q-App",
|
"qappNotification1": "Powiadomienia Q-App",
|
||||||
"selectnode": "Proszę wybrać opcję",
|
"selectnode": "Proszę wybrać opcję",
|
||||||
"arrr1": "Portfel ARRR nie został zainicjowany!",
|
"arrr1": "Portfel ARRR nie został zainicjowany!",
|
||||||
"arrr2": "Przejdź do zakładki portfela i najpierw zainicjalizuj swój portfel arrr.",
|
"arrr2": "Przejdź do Portfeli i uzyskaj dostęp do portfela ARRR, aby najpierw zainicjować portfel.",
|
||||||
"arrr3": "Potrzebujesz aktualizacji rdzenia!",
|
"arrr3": "Potrzebujesz aktualizacji rdzenia!",
|
||||||
"arrr4": "Aby zapisać klucz prywatny swojego portfela arrr, potrzebujesz najpierw aktualizacji rdzenia!",
|
"arrr4": "Aby zapisać klucz prywatny swojego portfela ARRR, musisz najpierw zaktualizować Qortal Core!",
|
||||||
"sync_indicator": "Wyłącz wyskakujące okienko wskaźnika synchronizacji"
|
"sync_indicator": "Wyłącz wyskakujące okienko wskaźnika synchronizacji"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "Saldo",
|
"balance": "Saldo",
|
||||||
"balances": "SALDO TWOJEGO PORTFELA",
|
"balances": "SALDO TWOJEGO PORTFELA",
|
||||||
"update": "AKTUALIZUJ SALDA W PORTFELU",
|
"update": "AKTUALIZUJ SALDA W PORTFELU",
|
||||||
"view": "Pogląd"
|
"view": "Pogląd",
|
||||||
|
"all": "Wszystko",
|
||||||
|
"page": "Strona"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Eksplorator gifów",
|
"gchange1": "Eksplorator gifów",
|
||||||
@ -284,7 +286,7 @@
|
|||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "Nie można pobrać kont menniczych",
|
"smchange1": "Nie można pobrać kont menniczych",
|
||||||
"smchange2": "Nie udało się usunąć klucza",
|
"smchange2": "Nie udało się usunąć klucza",
|
||||||
"smchange3": "Nie udało się dodać klucza bicia",
|
"smchange3": "Nie udało się dodać klucza Minting. Jeśli klucz został właśnie utworzony, spróbuj poczekać kilka bloków i dodać go ponownie",
|
||||||
"smchange4": "Nie można utworzyć klucza sponsorowania",
|
"smchange4": "Nie można utworzyć klucza sponsorowania",
|
||||||
"smchange5": "Tworzenie relacji",
|
"smchange5": "Tworzenie relacji",
|
||||||
"smchange6": "Oczekiwanie na potwierdzenie na blockchain",
|
"smchange6": "Oczekiwanie na potwierdzenie na blockchain",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "Cena sprzedaży",
|
"nchange23": "Cena sprzedaży",
|
||||||
"nchange24": "Brak nazw do sprzedania",
|
"nchange24": "Brak nazw do sprzedania",
|
||||||
"nchange25": "Nazwa do sprzedania",
|
"nchange25": "Nazwa do sprzedania",
|
||||||
"nchange26": "Czy na pewno chcesz sprzedać tę nazwę?",
|
"nchange26": "Czy na pewno chcesz sprzedać tę nazwę? Jeśli nazwa zostanie zakupiona przez inne konto, będzie to poza Twoją kontrolą!",
|
||||||
"nchange27": "Za tę cenę w QORT",
|
"nchange27": "Za tę cenę w QORT",
|
||||||
"nchange28": "Po naciśnięciu potwierdzenia zostanie wysłane zapytanie o nazwę sprzedaży!",
|
"nchange28": "Po naciśnięciu potwierdzenia zostanie wysłane zapytanie o nazwę sprzedaży!",
|
||||||
"nchange29": "Nazwa do anulowania",
|
"nchange29": "Nazwa do anulowania",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "Nazwa grupy do wyszukania",
|
"gchange56": "Nazwa grupy do wyszukania",
|
||||||
"gchange57": "Nie znaleziono nazwy grupy prywatnej",
|
"gchange57": "Nie znaleziono nazwy grupy prywatnej",
|
||||||
"gchange58": "Zauważ, że nazwa grupy musi dokładnie pasować.",
|
"gchange58": "Zauważ, że nazwa grupy musi dokładnie pasować.",
|
||||||
"gchange59": "Pokaż / Ukryj Znacznik"
|
"gchange59": "Pokaż / Ukryj Znacznik",
|
||||||
|
"gchange60": "Podaj nazwę grupy",
|
||||||
|
"gchange61": "Podaj opis",
|
||||||
|
"gchange62": "Czy na pewno AKTUALIZUJESZ tę grupę?",
|
||||||
|
"gchange63": "Po naciśnięciu przycisku POTWIERDŹ zostanie wysłane żądanie UPDATE_GROUP!",
|
||||||
|
"gchange64": "Current Owner / New Owner",
|
||||||
|
"gchange65": "Zamień ten adres na PRZENIESIENIE WŁASNOŚCI grupy!",
|
||||||
|
"gchange66": "Nieprawidłowy właściciel / nowy adres właściciela",
|
||||||
|
"gchange67": "AKTUALIZACJA grupy powiodła się!",
|
||||||
|
"gchange68": "Ustaw awatar grupy"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Zagadki",
|
"pchange1": "Zagadki",
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
"tm32": "Esta conta não segue nenhum usuário",
|
"tm32": "Esta conta não segue nenhum usuário",
|
||||||
"tm33": "Menu da Aba Importar",
|
"tm33": "Menu da Aba Importar",
|
||||||
"tm34": "Menu da guia Exportar",
|
"tm34": "Menu da guia Exportar",
|
||||||
"tm35": "Seu menu de guia existente será excluído e definido como menu de guia carregado.",
|
"tm35": "Seu menu de guias existente será excluído e definido como menu de guias importado.",
|
||||||
"tm36": "Menu de abas restaurado com sucesso",
|
"tm36": "Menu de abas restaurado com sucesso",
|
||||||
"tm37": "Menu da guia salvo com sucesso como",
|
"tm37": "Menu da guia salvo com sucesso como",
|
||||||
"tm38": "MODO DEV",
|
"tm38": "MODO DEV",
|
||||||
@ -98,42 +98,42 @@
|
|||||||
"youraccounts": "Minhas Contas",
|
"youraccounts": "Minhas Contas",
|
||||||
"clickto": "Clique em sua conta para fazer o login",
|
"clickto": "Clique em sua conta para fazer o login",
|
||||||
"needcreate": "Você precisa criar ou salvar uma conta antes de fazer o login",
|
"needcreate": "Você precisa criar ou salvar uma conta antes de fazer o login",
|
||||||
"upload": "Carregue seu backup do Qortal",
|
"upload": "Importe seu arquivo de backup Qortal",
|
||||||
"howlogin": "Como você gostaria de fazer o login?",
|
"howlogin": "Como você gostaria de fazer o login?",
|
||||||
"seed": "SeedPhrase",
|
"seed": "SeedPhrase",
|
||||||
"seedphrase": "seedphrase",
|
"seedphrase": "seedphrase",
|
||||||
"saved": "Conta Salva",
|
"saved": "Conta Salva",
|
||||||
"qora": "Endereço seed do Qora",
|
"qora": "Endereço seed do QORA",
|
||||||
"backup": "Backup da carteira do Qortal",
|
"backup": "Arquivo de backup Qortal",
|
||||||
"decrypt": "Desencriptar Backup",
|
"decrypt": "Descriptografar arquivo de backup",
|
||||||
"save": "Salvar neste Navegador",
|
"save": "Salvar neste Navegador",
|
||||||
"prepare": "Preparando sua Conta",
|
"prepare": "Preparando sua Conta...",
|
||||||
"areyousure": "Tem certeza que deseja excluir esta carteira das carteiras salvas?",
|
"areyousure": "Tem certeza de que deseja remover esta conta das contas salvas? (Se for removida e não existir nenhum arquivo de backup, a conta poderá ser perdida para sempre! Certifique-se de ter um arquivo de backup antes de fazer isso!)",
|
||||||
"error1": "Backup tem que ser um JSON valido",
|
"error1": "Backup tem que ser um JSON valido",
|
||||||
"error2": "Login opcional não selecionado",
|
"error2": "Login opcional não selecionado",
|
||||||
"createwelcome": "Bem-vindo ao Qortal, você vai achar que é semelhante ao de um jogo de RPG, você, como um mineirador na rede Qortal (se você escolher se tornar um) terá a chance de prosperar com sua conta, dando-lhe tanto mais da recompensa do bloco QORT e também maior influência sobre a rede em termos de votação sobre decisões para a plataforma.",
|
"createwelcome": "Bem-vindo ao Qortal! Seu futuro digital descentralizado espera por você! Somente no Qortal você tem controle absoluto sobre seus dados. Qortal fornece o nível básico de um mundo digital novo e totalmente controlado pelo usuário.",
|
||||||
"createa": "A",
|
"createa": "A",
|
||||||
"click": "Clique para ver a SeedPhrase",
|
"click": "Clique para ver a SeedPhrase",
|
||||||
"confirmpass": "Confirme sua Senha",
|
"confirmpass": "Confirme sua Senha",
|
||||||
"willbe": "Será gerado aleatoriamente em segundo plano. Este é usado como seu gerador de chaves privada para sua conta blockchain no Qortal.",
|
"willbe": "Será gerado aleatoriamente em segundo plano. Se você deseja VER a frase-semente, clique na 'frase-semente' destacada neste texto. Ele é usado como gerador de chave privada para sua conta blockchain no Qortal. Por segurança, por padrão, as frases-chave não são exibidas, a menos que sejam especificamente escolhidas para serem.",
|
||||||
"clicknext": "Crie sua conta no Qortal clicando em PRÓXIMO abaixo.",
|
"clicknext": "Crie sua conta no Qortal clicando em PRÓXIMO abaixo.",
|
||||||
"ready": "Sua conta está pronta para ser criada. Ela será salva neste navegador. Se você não deseja que sua nova conta seja salva no seu navegador, você pode desmarcar a caixa abaixo. Você ainda poderá fazer o login com sua nova conta (após o login), usando seu arquivo de backup de carteira que você deve baixar assim que criar sua conta.",
|
"ready": "Sua conta agora está pronta para ser criada. Ele será salvo nesta cópia da UI do Qortal por padrão, em formato criptografado. Se não quiser que sua nova conta seja salva aqui, você pode desmarcar a caixa abaixo. Você ainda poderá fazer login com sua nova conta (após sair), usando o arquivo de backup da carteira que você DEVE baixar depois de criar sua conta.",
|
||||||
"welmessage": "Bem-vindo ao Qortal",
|
"welmessage": "Bem-vindo ao Qortal",
|
||||||
"pleaseenter": "Por favor coloque sua senha!",
|
"pleaseenter": "Por favor coloque sua senha!",
|
||||||
"notmatch": "Senhas não correspondem!",
|
"notmatch": "Senhas não correspondem!",
|
||||||
"lessthen8": "Sua senha é menor que 5 caracteres! Isso não é recomendado. Você pode continuar e ignorar este aviso.",
|
"lessthen8": "Sua senha é menor que 5 caracteres! Isso não é recomendado. Você pode continuar e ignorar este aviso.",
|
||||||
"lessthen8-2": "Sua senha é menor que 5 caracteres!",
|
"lessthen8-2": "Sua senha é menor que 5 caracteres!",
|
||||||
"entername": "Por favor, digite um nome!",
|
"entername": "Por favor insira um nome de exibição!",
|
||||||
"downloaded": "Seu arquivo Wallet BackUp é baixado!",
|
"downloaded": "Seu arquivo Qortal Backup foi salvo!",
|
||||||
"loading": "Carregando, por favor espere...",
|
"loading": "Carregando, por favor espere...",
|
||||||
"createdseed": "Sua Seedphrase Criada",
|
"createdseed": "Sua Seedphrase Criada",
|
||||||
"saveseed": "Salvar Seedphrase",
|
"saveseed": "Salvar Seedphrase",
|
||||||
"savein": "Salvar no Navegador",
|
"savein": "Salvar nesta IU",
|
||||||
"backup2": "Este arquivo é a única forma de acessar sua conta em um sistema que não o tem salvo no aplicativo/navegador. CERTIFIQUE-SE DE FAZER BACKUP DESTE ARQUIVO EM VÁRIOS LUGARES. O arquivo é criptografado com muita segurança e descriptografado com sua senha local que você criou na etapa anterior. Você pode salvá-lo em qualquer lugar com segurança, mas certifique-se de fazer isso em vários locais.",
|
"backup2": "Este arquivo é a única forma de acessar sua conta em um sistema que não o tem salvo no aplicativo/navegador. CERTIFIQUE-SE DE FAZER BACKUP DESTE ARQUIVO EM VÁRIOS LUGARES. O arquivo é criptografado com muita segurança e descriptografado com sua senha local que você criou na etapa anterior. Você pode salvá-lo em qualquer lugar com segurança, mas certifique-se de fazer isso em vários locais.",
|
||||||
"savewallet": "Salvar Arquivo de BackUp da Carteira",
|
"savewallet": "Salvar arquivo de backup Qortal",
|
||||||
"created1": "Sua conta foi Criada",
|
"created1": "Sua conta foi Criada",
|
||||||
"created2": "e será salva neste navegador.",
|
"created2": " e salvo criptografado nesta UI Qortal.",
|
||||||
"downloadbackup": "Baixe o Arquivo BackUp da Carteira",
|
"downloadbackup": "Salvar arquivo de backup Qortal",
|
||||||
"passwordhint": "Uma senha deve ter pelo menos 5 caracteres.",
|
"passwordhint": "Uma senha deve ter pelo menos 5 caracteres.",
|
||||||
"lp1": "Tela de bloqueio",
|
"lp1": "Tela de bloqueio",
|
||||||
"lp2": "Nenhuma senha de tela de bloqueio foi definida!",
|
"lp2": "Nenhuma senha de tela de bloqueio foi definida!",
|
||||||
@ -164,7 +164,7 @@
|
|||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "Selecione Arquivo",
|
"selectfile": "Selecione Arquivo",
|
||||||
"dragfile": "Arrastar e soltar backup aqui"
|
"dragfile": "Arraste e solte ou clique aqui para selecionar o arquivo de backup"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "Informações gerais da conta",
|
"generalinfo": "Informações gerais da conta",
|
||||||
@ -181,7 +181,7 @@
|
|||||||
"notifications": "Notificações",
|
"notifications": "Notificações",
|
||||||
"accountsecurity": "Segurança da Conta",
|
"accountsecurity": "Segurança da Conta",
|
||||||
"password": "Senha",
|
"password": "Senha",
|
||||||
"download": "Baixar Arquivo BackUp",
|
"download": "Exportar/Salvar arquivo de backup",
|
||||||
"choose": "Por favor, escolha uma senha para criptografar seu backup. (Essa pode ser a mesma que você fez login, ou outra diferente)",
|
"choose": "Por favor, escolha uma senha para criptografar seu backup. (Essa pode ser a mesma que você fez login, ou outra diferente)",
|
||||||
"playsound": "Reproduzir som",
|
"playsound": "Reproduzir som",
|
||||||
"shownotifications": "Mostrar notificações",
|
"shownotifications": "Mostrar notificações",
|
||||||
@ -192,8 +192,8 @@
|
|||||||
"protocol": "Protocolo",
|
"protocol": "Protocolo",
|
||||||
"domain": "Domínio",
|
"domain": "Domínio",
|
||||||
"port": "Portar",
|
"port": "Portar",
|
||||||
"import": "Importar Nós",
|
"import": "Importar nós salvos",
|
||||||
"export": "Exportar Nós",
|
"export": "Exportar Nós salvos",
|
||||||
"deletecustomnode": "Remover todos os nós personalizados",
|
"deletecustomnode": "Remover todos os nós personalizados",
|
||||||
"warning": "Seus nós existentes serão excluídos e do backup será criado.",
|
"warning": "Seus nós existentes serão excluídos e do backup será criado.",
|
||||||
"snack1": "Nós padrão excluídos e adicionados com sucesso",
|
"snack1": "Nós padrão excluídos e adicionados com sucesso",
|
||||||
@ -203,17 +203,17 @@
|
|||||||
"snack5": "Nós importados com sucesso",
|
"snack5": "Nós importados com sucesso",
|
||||||
"snack6": "Nó personalizado removido com sucesso",
|
"snack6": "Nó personalizado removido com sucesso",
|
||||||
"snack7": "Nó personalizado editado com sucesso",
|
"snack7": "Nó personalizado editado com sucesso",
|
||||||
"exp1": "Exportar Chave Mestra Privada",
|
"exp1": "Exportar chave privada mestra (xpriv)",
|
||||||
"exp2": "Exportar Chave Mestra",
|
"exp2": "Exportar Chave Mestra",
|
||||||
"exp3": "Exportar",
|
"exp3": "Exportar",
|
||||||
"exp4": "Por favor, escolha uma carteira para fazer backup da chave mestra privada.",
|
"exp4": "Por favor, escolha uma carteira para fazer backup da chave privada mestra.",
|
||||||
"core": "Iniciar configurações do núcleo",
|
"core": "Configurações de inicialização automática do Qortal Core",
|
||||||
"qappNotification1": "Notificações de Q-App",
|
"qappNotification1": "Notificações de Q-App",
|
||||||
"selectnode": "Por favor selecione uma opção",
|
"selectnode": "Por favor selecione uma opção",
|
||||||
"arrr1": "Carteira ARRR não inicializada!",
|
"arrr1": "Carteira ARRR não inicializada!",
|
||||||
"arrr2": "Por favor, vá para a aba carteira e inicialize sua carteira arrr primeiro.",
|
"arrr2": "Por favor, vá para a guia carteira e acesse a carteira ARRR para inicializar a carteira primeiro.",
|
||||||
"arrr3": "Precisa de atualização principal!",
|
"arrr3": "Precisa de atualização principal!",
|
||||||
"arrr4": "Para salvar a chave privada da sua carteira arrr você precisa primeiro de uma atualização principal!",
|
"arrr4": "Para salvar a chave privada da sua carteira ARRR você deve primeiro atualizar o Qortal Core!",
|
||||||
"sync_indicator": "Desativar pop-up do indicador de sincronização"
|
"sync_indicator": "Desativar pop-up do indicador de sincronização"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "Saldo",
|
"balance": "Saldo",
|
||||||
"balances": "SEUS SALDOS DE CARTEIRA",
|
"balances": "SEUS SALDOS DE CARTEIRA",
|
||||||
"update": "ATUALIZAR SALDOS DA CARTEIRA",
|
"update": "ATUALIZAR SALDOS DA CARTEIRA",
|
||||||
"view": "Ver"
|
"view": "Ver",
|
||||||
|
"all": "Todos",
|
||||||
|
"page": "Página"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Gif Explorer",
|
"gchange1": "Gif Explorer",
|
||||||
@ -283,8 +285,8 @@
|
|||||||
},
|
},
|
||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "Não é possível buscar contas de cunhagem",
|
"smchange1": "Não é possível buscar contas de cunhagem",
|
||||||
"smchange2": "Falha ao remover a chave",
|
"smchange2": "Falha ao remover a chave Minting",
|
||||||
"smchange3": "Falha ao adicionar chave de cunhagem",
|
"smchange3": "Falha ao adicionar a chave Minting, se a chave acabou de ser criada, tente esperar alguns blocos e adicionar novamente",
|
||||||
"smchange4": "Não é possível criar a chave de patrocínio",
|
"smchange4": "Não é possível criar a chave de patrocínio",
|
||||||
"smchange5": "Criando relacionamento",
|
"smchange5": "Criando relacionamento",
|
||||||
"smchange6": "Aguardando confirmação no blockchain",
|
"smchange6": "Aguardando confirmação no blockchain",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "Preço de venda",
|
"nchange23": "Preço de venda",
|
||||||
"nchange24": "Sem nomes para vender",
|
"nchange24": "Sem nomes para vender",
|
||||||
"nchange25": "Nome para vender",
|
"nchange25": "Nome para vender",
|
||||||
"nchange26": "Tem certeza que vende este nome ?",
|
"nchange26": "Tem certeza de que deseja vender este nome? Se o nome for adquirido por outra conta, os dados publicados por esse nome não poderão ser editados por você!",
|
||||||
"nchange27": "Por este preço em QORT",
|
"nchange27": "Por este preço em QORT",
|
||||||
"nchange28": "Ao clicar em confirmar, a solicitação do nome de venda será enviada!",
|
"nchange28": "Ao clicar em confirmar, a solicitação do nome de venda será enviada!",
|
||||||
"nchange29": "Nome para Cancelar",
|
"nchange29": "Nome para Cancelar",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "Nome do grupo para pesquisar",
|
"gchange56": "Nome do grupo para pesquisar",
|
||||||
"gchange57": "Nome do grupo privado não encontrado",
|
"gchange57": "Nome do grupo privado não encontrado",
|
||||||
"gchange58": "Observe que o nome do grupo deve corresponder exatamente.",
|
"gchange58": "Observe que o nome do grupo deve corresponder exatamente.",
|
||||||
"gchange59": "Mostrar / Ocultar Ticker"
|
"gchange59": "Mostrar / Ocultar Ticker",
|
||||||
|
"gchange60": "Insira o nome do grupo",
|
||||||
|
"gchange61": "Por favor, insira a descrição",
|
||||||
|
"gchange62": "Tem certeza de que vai ATUALIZAR este grupo?",
|
||||||
|
"gchange63": "Ao pressionar CONFIRMAR, a solicitação de UPDATE_GROUP será enviada!",
|
||||||
|
"gchange64": "Proprietário Atual / Novo Proprietário",
|
||||||
|
"gchange65": "Substitua este endereço para TRANSFERIR PROPRIEDADE do grupo!",
|
||||||
|
"gchange66": "Endereço de proprietário / novo proprietário inválido",
|
||||||
|
"gchange67": "ATUALIZAÇÃO DO Grupo bem-sucedida!",
|
||||||
|
"gchange68": "Definir avatar do grupo"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Enigmas",
|
"pchange1": "Enigmas",
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
"tm32": "Acest cont nu urmărește niciun utilizator",
|
"tm32": "Acest cont nu urmărește niciun utilizator",
|
||||||
"tm33": "Meniu Filă Import",
|
"tm33": "Meniu Filă Import",
|
||||||
"tm34": "Meniu File Export",
|
"tm34": "Meniu File Export",
|
||||||
"tm35": "Meniul de file existent va fi șters și setat la meniul de file încărcat.",
|
"tm35": "Meniul de file existent va fi șters și setat la meniul de file importat.",
|
||||||
"tm36": "Meniul Tab a fost restaurat cu succes",
|
"tm36": "Meniul Tab a fost restaurat cu succes",
|
||||||
"tm37": "Meniul Tab a fost salvat cu succes ca",
|
"tm37": "Meniul Tab a fost salvat cu succes ca",
|
||||||
"tm38": "MOD DEV",
|
"tm38": "MOD DEV",
|
||||||
@ -98,42 +98,42 @@
|
|||||||
"youraccounts": "Conturile tale",
|
"youraccounts": "Conturile tale",
|
||||||
"clickto": "Fa click pe Contul tau pentru a te conecta cu el",
|
"clickto": "Fa click pe Contul tau pentru a te conecta cu el",
|
||||||
"needcreate": "Trebuie sa iti creezi sau sa salvezi un cont inainte de a te conecta!",
|
"needcreate": "Trebuie sa iti creezi sau sa salvezi un cont inainte de a te conecta!",
|
||||||
"upload": "Urca copia de siguranta Qortal",
|
"upload": "Importați fișierul de rezervă Qortal",
|
||||||
"howlogin": "Cum doresti sa te conectezi?",
|
"howlogin": "Cum doresti sa te conectezi?",
|
||||||
"seed": "frazainitiala",
|
"seed": "frazainitiala",
|
||||||
"seedphrase": "frazainitiala",
|
"seedphrase": "frazainitiala",
|
||||||
"saved": "Cont salvat",
|
"saved": "Cont salvat",
|
||||||
"qora": "Adresa initiala Qora",
|
"qora": "Adresa initiala QORA",
|
||||||
"backup": "Copia de siguranta a portofelului Qortal",
|
"backup": "Fișier de rezervă Qortal",
|
||||||
"decrypt": "Decriptare copie de siguranta",
|
"decrypt": "Decriptați fișierul de rezervă",
|
||||||
"save": "Salveaza in acest browser.",
|
"save": "Salveaza in acest browser.",
|
||||||
"prepare": "Se pregateste Contul tau",
|
"prepare": "Se pregateste Contul tau",
|
||||||
"areyousure": "Sunteti sigur ca doriti sa eliminati acest portofel din portofelele salvate?",
|
"areyousure": "Sigur doriți să eliminați acest cont din conturile salvate? (Dacă este eliminat și nu există niciun fișier de rezervă, contul poate fi pierdut pentru totdeauna! Asigurați-vă că aveți un fișier de rezervă înainte de a face acest lucru!)",
|
||||||
"error1": "Backup-ul trebuie sa fie JSON valid",
|
"error1": "Backup-ul trebuie sa fie JSON valid",
|
||||||
"error2": "Optiunea de conectare nu este selectata",
|
"error2": "Optiunea de conectare nu este selectata",
|
||||||
"createwelcome": "Bine ai venit la Qortal, vei descoperi ca este similar cu un joc RPG, tu, ca minter in reteaua Qortal (daca alegi sa devii unul), vei avea sansa de a-ti creste nivelul contului tau, oferindu-ti deopotiva o recompensa mai mare din blocul QORT, cat si o influenta mai mare asupra retelei in ceea ce priveste votul asupra deciziilor pentru platforma.",
|
"createwelcome": "Bun venit la Qortal! Viitorul tău digital descentralizat te așteaptă! Dvs. și numai dvs. aveți control deplin asupra datelor dvs. de pe Qortal. Qortal oferă infrastructura unei lumi digitale noi și complet controlate de utilizator.",
|
||||||
"createa": "A",
|
"createa": "A",
|
||||||
"click": "Da click pentru a vedea fraza initiala",
|
"click": "Da click pentru a vedea fraza initiala",
|
||||||
"confirmpass": "Confirma Parola",
|
"confirmpass": "Confirma Parola",
|
||||||
"willbe": "va fi generata aleatoriu in fundal. Aceasta este utilizata ca generator de cheie privata pentru contul tau blockchain din Qortal.",
|
"willbe": "va fi generat aleatoriu în fundal. Dacă doriți să VEZI fraza inițială, faceți clic pe „fraza inițială” evidențiată în acest text. Acesta este folosit ca generator de chei private pentru contul blockchain din Qortal. Pentru securitate, în mod implicit, frazele de bază nu sunt afișate decât dacă sunt alese în mod special.",
|
||||||
"clicknext": "Creaza-ti contul Qortal apasand butonul INAINTE.",
|
"clicknext": "Creaza-ti contul Qortal apasand butonul INAINTE.",
|
||||||
"ready": "Contul dvs. este acum gata sa fie creat. Acesta va fi salvat in acest browser. Daca nu doriti ca noul dvs. cont sa fie salvat in browserul dvs., puteti debifa caseta de mai jos. Veti putea in continuare sa va conectati cu noul dvs. cont (dupa ce va deconectati), utilizand fisierul de backup al portofelului pe care TREBUIE sa il descarcati dupa ce va creati contul.",
|
"ready": "Contul dvs. este acum gata pentru a fi creat. Acesta va fi salvat în această copie a Qortal UI în mod implicit, în formă criptată. Dacă nu doriți ca noul dvs. cont să fie salvat aici, puteți debifa caseta de mai jos. Veți putea în continuare să vă conectați cu noul cont (după deconectare), folosind fișierul de rezervă al portofelului, pe care TREBUIE să-l descărcați după ce vă creați contul.",
|
||||||
"welmessage": "Bine ai venit in Qortal",
|
"welmessage": "Bine ai venit in Qortal",
|
||||||
"pleaseenter": "Te rog introdu o parola!",
|
"pleaseenter": "Te rog introdu o parola!",
|
||||||
"notmatch": "Parola nu corespunde!",
|
"notmatch": "Parola nu corespunde!",
|
||||||
"lessthen8": "Parola ta are mai putin de 5 caractere! Acest lucru nu este recomandat. Poti continua sa ignori acest avertisment.",
|
"lessthen8": "Parola ta are mai putin de 5 caractere! Acest lucru nu este recomandat. Poti continua sa ignori acest avertisment.",
|
||||||
"lessthen8-2": "Parola ta are mai putin de 5 caractere!",
|
"lessthen8-2": "Parola ta are mai putin de 5 caractere!",
|
||||||
"entername": "Te rog introdu un Nume!",
|
"entername": "Vă rugăm să introduceți un nume afișat!",
|
||||||
"downloaded": "Copia de siguranta a portofelului este descarcata!",
|
"downloaded": "Fișierul dvs. Qortal Backup a fost salvat!",
|
||||||
"loading": "Se incarca. Va rugam asteptati...",
|
"loading": "Se incarca. Va rugam asteptati...",
|
||||||
"createdseed": "Fraza initiala personala creata",
|
"createdseed": "Fraza initiala personala creata",
|
||||||
"saveseed": "Salveaza fraza initiala",
|
"saveseed": "Salveaza fraza initiala",
|
||||||
"savein": "Salveaza in browser",
|
"savein": "Salvați în această interfață de utilizare",
|
||||||
"backup2": "Acest fisier este SINGURA modalitate de a-ti accesa contul pe un sistem care nu il are salvat in aplicatie/browser. ASIGURA-TE CA FACI O COPIE DE REZERVA A ACESTUI FISIER IN MAI MULTE LOCURI. Fisierul este criptat foarte sigur si decriptat cu parola locala pe care ai creat-o in pasul anterior. Il poti salva oriunde in siguranta, dar asigura-te ca faci acest lucru in mai multe locatii.",
|
"backup2": "Acest fișier este SINGURA modalitate (în mod implicit) de a vă accesa contul, cu excepția cazului în care este salvat în UI. ASIGURAȚI-VĂ CĂ FACEȚI BACKUP ACEST FIȘIER ÎN MULTE LOCURI. Fișierul este criptat foarte sigur și decriptat cu parola dvs. locală pe care ați creat-o la pasul anterior. Îl puteți salva oriunde în siguranță, dar asigurați-vă că faceți acest lucru în mai multe locații.",
|
||||||
"savewallet": "Salveaza copia de siguranta a Portofelului",
|
"savewallet": "Salvați fișierul de rezervă Qortal",
|
||||||
"created1": "Contul tau este acum creat",
|
"created1": "Contul tau este acum creat",
|
||||||
"created2": "si va fi salvat in acest browser.",
|
"created2": " și salvat în această interfață de utilizare în formă criptată.",
|
||||||
"downloadbackup": "Descarca copia de siguranta a Portofelului",
|
"downloadbackup": "Salvați fișierul Qortal BackUp",
|
||||||
"passwordhint": "O parola trebuie sa aiba cel putin 5 caractere.",
|
"passwordhint": "O parola trebuie sa aiba cel putin 5 caractere.",
|
||||||
"lp1": "Ecran de blocare",
|
"lp1": "Ecran de blocare",
|
||||||
"lp2": "Nu este setată nicio parolă pentru ecranul de blocare!",
|
"lp2": "Nu este setată nicio parolă pentru ecranul de blocare!",
|
||||||
@ -163,8 +163,8 @@
|
|||||||
"confirmlogout": "Esti sigur ca vrei sa te deconectezi?"
|
"confirmlogout": "Esti sigur ca vrei sa te deconectezi?"
|
||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "Selecteaza fisier",
|
"selectfile": "Selectați fișierul de rezervă",
|
||||||
"dragfile": "Trage si elibereaza fisierul de backup aici"
|
"dragfile": "Trageți și plasați sau faceți clic aici pentru a selecta fișierul de rezervă"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "Informatii generale despre cont",
|
"generalinfo": "Informatii generale despre cont",
|
||||||
@ -181,7 +181,7 @@
|
|||||||
"notifications": "Notificari",
|
"notifications": "Notificari",
|
||||||
"accountsecurity": "Securitatea contului",
|
"accountsecurity": "Securitatea contului",
|
||||||
"password": "Parola",
|
"password": "Parola",
|
||||||
"download": "Descarca copia de siguranta",
|
"download": "Exportați/Salvați fișierul de rezervă Qortal",
|
||||||
"choose": "Va rugam sa alegeti o parola cu care sa va criptati copia de rezerva. (Aceasta poate fi aceeasi cu cea cu care v-ati logat sau diferita)",
|
"choose": "Va rugam sa alegeti o parola cu care sa va criptati copia de rezerva. (Aceasta poate fi aceeasi cu cea cu care v-ati logat sau diferita)",
|
||||||
"playsound": "Redare sunet",
|
"playsound": "Redare sunet",
|
||||||
"shownotifications": "Arata notificarile",
|
"shownotifications": "Arata notificarile",
|
||||||
@ -192,8 +192,8 @@
|
|||||||
"protocol": "Protocol",
|
"protocol": "Protocol",
|
||||||
"domain": "Domeniu",
|
"domain": "Domeniu",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
"import": "Import Noduri",
|
"import": "Import Noduri salvate",
|
||||||
"export": "Export Noduri",
|
"export": "Export Noduri salvate",
|
||||||
"deletecustomnode": "Eliminati toate nodurile personalizate",
|
"deletecustomnode": "Eliminati toate nodurile personalizate",
|
||||||
"warning": "Nodurile dvs. existente vor fi sterse si din backup vor fi create noi.",
|
"warning": "Nodurile dvs. existente vor fi sterse si din backup vor fi create noi.",
|
||||||
"snack1": "Noduri standard au fost sterse si adaugate cu succes",
|
"snack1": "Noduri standard au fost sterse si adaugate cu succes",
|
||||||
@ -203,17 +203,17 @@
|
|||||||
"snack5": "Nodurile au fost importate cu succes",
|
"snack5": "Nodurile au fost importate cu succes",
|
||||||
"snack6": "Nodul personalizat a fost eliminat cu succes",
|
"snack6": "Nodul personalizat a fost eliminat cu succes",
|
||||||
"snack7": "Nodul personalizat a fost editat cu succes",
|
"snack7": "Nodul personalizat a fost editat cu succes",
|
||||||
"exp1": "Exportați cheia principală privată",
|
"exp1": "Exportați cheia privată principală (xpriv)",
|
||||||
"exp2": "Exportați cheia principală",
|
"exp2": "Exportați cheia principală",
|
||||||
"exp3": "Export",
|
"exp3": "Export",
|
||||||
"exp4": "Vă rugăm să alegeți un portofel pentru a face backup cheii master private.",
|
"exp4": "Vă rugăm să alegeți un portofel pentru a face backup cheii master private.",
|
||||||
"core": "Porniți setările de bază",
|
"core": "Setări Qortal de pornire automată",
|
||||||
"qappNotification1": "Notificări Q-App",
|
"qappNotification1": "Notificări Q-App",
|
||||||
"selectnode": "Vă rugăm să selectați o opțiune",
|
"selectnode": "Vă rugăm să selectați o opțiune",
|
||||||
"arrr1": "Portoletul ARRR nu este inițializat !",
|
"arrr1": "Portoletul ARRR nu este inițializat !",
|
||||||
"arrr2": "Vă rugăm să accesați fila Portofel și să inițializați mai întâi portofelul arrr.",
|
"arrr2": "Accesați „Portofele” și accesați portofelul ARRR pentru a inițializa mai întâi portofelul",
|
||||||
"arrr3": "Am nevoie de actualizare de bază !",
|
"arrr3": "Am nevoie de actualizare de bază !",
|
||||||
"arrr4": "Pentru a salva cheia privată a portofelului dvs. arrr, aveți nevoie mai întâi de o actualizare de bază !",
|
"arrr4": "Pentru a salva cheia privată a portofelului dvs. ARRR, trebuie mai întâi să actualizați Qortal Core!",
|
||||||
"sync_indicator": "Dezactivați fereastra pop-up indicator de sincronizare"
|
"sync_indicator": "Dezactivați fereastra pop-up indicator de sincronizare"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "Credit",
|
"balance": "Credit",
|
||||||
"balances": "SOLDELE PORTOTELULUI DVS",
|
"balances": "SOLDELE PORTOTELULUI DVS",
|
||||||
"update": "ACTUALIZAȚI SOLDELE PORTOTELULUI",
|
"update": "ACTUALIZAȚI SOLDELE PORTOTELULUI",
|
||||||
"view": "Vedere"
|
"view": "Vedere",
|
||||||
|
"all": "Toate",
|
||||||
|
"page": "Pagină"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Explorator GIF",
|
"gchange1": "Explorator GIF",
|
||||||
@ -283,8 +285,8 @@
|
|||||||
},
|
},
|
||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "Nu se pot prelua conturile de batere",
|
"smchange1": "Nu se pot prelua conturile de batere",
|
||||||
"smchange2": "Cheia nu a fost eliminata",
|
"smchange2": "Nu s-a putut elimina cheia Minting",
|
||||||
"smchange3": "Nu s-a putut adauga cheia de batere",
|
"smchange3": "Nu s-a putut adăuga cheia de batere, dacă cheia tocmai a fost creată, încercați să așteptați câteva blocuri și să adăugați din nou",
|
||||||
"smchange4": "Nu se poate crea cheia de sponsorizare",
|
"smchange4": "Nu se poate crea cheia de sponsorizare",
|
||||||
"smchange5": "Crearea unei relatii",
|
"smchange5": "Crearea unei relatii",
|
||||||
"smchange6": "Se asteapta confirmarea pe blockchain",
|
"smchange6": "Se asteapta confirmarea pe blockchain",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "Preț de vânzare",
|
"nchange23": "Preț de vânzare",
|
||||||
"nchange24": "Fără nume de vândut",
|
"nchange24": "Fără nume de vândut",
|
||||||
"nchange25": "Nume de vândut",
|
"nchange25": "Nume de vândut",
|
||||||
"nchange26": "Sunteți sigur că veți vinde acest nume?",
|
"nchange26": "Ești sigur că vrei să vinzi acest nume? Dacă un alt utilizator cumpără numele, toate datele publicate după nume nu vor putea fi editate de dvs.!",
|
||||||
"nchange27": "Pentru acest preț în QORT",
|
"nchange27": "Pentru acest preț în QORT",
|
||||||
"nchange28": "La apăsarea confirmării, cererea de nume de vânzare va fi trimisă!",
|
"nchange28": "La apăsarea confirmării, cererea de nume de vânzare va fi trimisă!",
|
||||||
"nchange29": "Nume de anulat",
|
"nchange29": "Nume de anulat",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "Numele grupului de căutat",
|
"gchange56": "Numele grupului de căutat",
|
||||||
"gchange57": "Numele grupului privat nu a fost găsit",
|
"gchange57": "Numele grupului privat nu a fost găsit",
|
||||||
"gchange58": "Rețineți că numele grupului trebuie să se potrivească exact.",
|
"gchange58": "Rețineți că numele grupului trebuie să se potrivească exact.",
|
||||||
"gchange59": "Afișează / Ascunde Ticker"
|
"gchange59": "Afișează / Ascunde Ticker",
|
||||||
|
"gchange60": "Vă rugăm să introduceți numele grupului",
|
||||||
|
"gchange61": "Vă rugăm să introduceți descrierea",
|
||||||
|
"gchange62": "Sunteți sigur că actualizați acest grup?",
|
||||||
|
"gchange63": "La apăsarea butonului CONFIRM, va fi trimisă solicitarea UPDATE_GROUP!",
|
||||||
|
"gchange64": "Proprietar actual / Proprietar nou",
|
||||||
|
"gchange65": "Înlocuiți această adresă la TRANSFERAȚI PROPRIETATEA grupului!",
|
||||||
|
"gchange66": "Adresa proprietarului / proprietarului nou nevalidă",
|
||||||
|
"gchange67": "UPDATE de grup Reușit!",
|
||||||
|
"gchange68": "Set Avatar grup"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Puzzle-uri",
|
"pchange1": "Puzzle-uri",
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
"tm32": "Ovaj nalog ne prati nijednog korisnika",
|
"tm32": "Ovaj nalog ne prati nijednog korisnika",
|
||||||
"tm33": "Meni kartice za uvoz",
|
"tm33": "Meni kartice za uvoz",
|
||||||
"tm34": "Izvoz meni kartice",
|
"tm34": "Izvoz meni kartice",
|
||||||
"tm35": "Vaš postojeći meni kartica će biti obrisan i postavljen na meni za otpremljene kartice.",
|
"tm35": "Vaš postojeći meni kartica će biti izbrisan i postavljen na uvezeni meni kartica.",
|
||||||
"tm36": "Meni kartice je uspešno vraćen",
|
"tm36": "Meni kartice je uspešno vraćen",
|
||||||
"tm37": "Meni kartice je uspešno sačuvan kao",
|
"tm37": "Meni kartice je uspešno sačuvan kao",
|
||||||
"tm38": "DEV MODE",
|
"tm38": "DEV MODE",
|
||||||
@ -98,26 +98,26 @@
|
|||||||
"youraccounts": "Tvoji nalozi",
|
"youraccounts": "Tvoji nalozi",
|
||||||
"clickto": "Kliknite na nalog sa kojim želite da se prijavite",
|
"clickto": "Kliknite na nalog sa kojim želite da se prijavite",
|
||||||
"needcreate": "Morate napraviti ili sačuvati nalog pre mogućnosti prijavljivanja!",
|
"needcreate": "Morate napraviti ili sačuvati nalog pre mogućnosti prijavljivanja!",
|
||||||
"upload": "Ubacite vašu rezervnu kopiju Qortala",
|
"upload": "Uvezite Qortal datoteku rezervne kopije",
|
||||||
"howlogin": "Kako bi ste želeli da se prijavite?",
|
"howlogin": "Kako bi ste želeli da se prijavite?",
|
||||||
"seed": "Semenska fraza",
|
"seed": "Semenska fraza",
|
||||||
"seedphrase": "semenskafraza",
|
"seedphrase": "semenskafraza",
|
||||||
"saved": "Sačuvani nalog",
|
"saved": "Sačuvani nalog",
|
||||||
"qora": "Seme Qora adrese",
|
"qora": "Seme QORA adrese",
|
||||||
"backup": "Rezervna kopija Qortal novčanika",
|
"backup": "Rezervna kopija Qortal novčanika",
|
||||||
"decrypt": "Dešifrovanje rezervne kopije",
|
"decrypt": "Dešifrovanje rezervne kopije",
|
||||||
"save": "Sačuvajte u ovom pretraživaču.",
|
"save": "Sačuvajte u ovom pretraživaču.",
|
||||||
"prepare": "Vaš Nalog se priprema",
|
"prepare": "Vaš Nalog se priprema",
|
||||||
"areyousure": "Da li ste sigurni da želite da izbrišete ovaj novčanik sa liste sačuvanih novčanika?",
|
"areyousure": "Da li ste sigurni da želite da uklonite ovaj nalog sa sačuvanih naloga? (Ako se ukloni i ne postoji datoteka rezervne kopije, nalog bi mogao biti izgubljen zauvek! Uverite se da imate rezervnu datoteku pre nego što to uradite!)",
|
||||||
"error1": "Rezervna kopija mora biti ispravan JSON",
|
"error1": "Rezervna kopija mora biti ispravan JSON",
|
||||||
"error2": "Opcija za prijavljivanje nije izabrana",
|
"error2": "Opcija za prijavljivanje nije izabrana",
|
||||||
"createwelcome": "Dobrodošli u Qortal, koji možete posmatrati kao RPG igru, gde ćete vi, kao minter na Qortal mreži (ako odlučite to postati) imati priliku da unapredite (izlevelujete) vaš nalog, i time steknete priliku da dobijate sve veću QORT nagradu po bloku, kao i veći uticaj na samoj platformi, kroz glasanje o raznim odlukama.",
|
"createwelcome": "Dobrodošli u Qortal! Vaša decentralizovana digitalna budućnost vas čeka! Na Qortal-u vi i samo vi imate apsolutnu kontrolu nad svojim podacima. Qortal obezbeđuje infrastrukturu novog i potpuno individualno kontrolisanog digitalnog sveta!",
|
||||||
"createa": "A",
|
"createa": "A",
|
||||||
"click": "Kliknite ovde da biste videli semensku frazu",
|
"click": "Kliknite ovde da biste videli semensku frazu",
|
||||||
"confirmpass": "Potvrdite Lozinku",
|
"confirmpass": "Potvrdite Lozinku",
|
||||||
"willbe": "Biće nasumično generisano u pozadini. Ovo je generator ličnog ključa za vaš blockchain nalog u Qortalu.",
|
"willbe": "će se nasumično generisati u pozadini. Ako želite da POGLEDATE početnu frazu, kliknite na označenu 'seedphrase' u ovom tekstu. Ovo se koristi kao generator privatnih ključeva za vaš blockchain nalog u Kortalu. Zbog bezbednosti se podrazumevano, seedphrase ne prikazuju osim ako nije posebno izabrano",
|
||||||
"clicknext": "Napravite vaš Qortal nalog klikom na dugme DALJE ispod.",
|
"clicknext": "Napravite vaš Qortal nalog klikom na dugme DALJE ispod.",
|
||||||
"ready": "Pravljenje vašeg naloga je spremno. Biće sačuvano u ovom pretraživaču. Ako ne želite da se vaš nov nalog sačuva u ovom pretraživaču, odčekirajte polje ispod. I dalje ćete moći da se prijavite sa vašim novim nalogom (posle odjavljivanja), korišćenjem datoteke sa rezervnom kopijom, koju MORATE skinuti čim napravite nalog.",
|
"ready": "Vaš nalog je sada spreman za kreiranje. Podrazumevano će biti sačuvan u ovoj kopiji Qortal korisničkog interfejsa, u šifrovanom obliku. Ako ne želite da vaš novi nalog bude sačuvan ovde, možete da opozovete izbor u polju za potvrdu ispod. I dalje ćete moći da se prijavite sa svojim novim nalogom (nakon odjavljivanja), koristeći rezervnu datoteku novčanika koju MORATE da preuzmete kada kreirate nalog.",
|
||||||
"welmessage": "Dobrodošli u Qortal",
|
"welmessage": "Dobrodošli u Qortal",
|
||||||
"pleaseenter": "Molim vas ukucajte lozinku!",
|
"pleaseenter": "Molim vas ukucajte lozinku!",
|
||||||
"notmatch": "Lozinke se ne podudaraju!",
|
"notmatch": "Lozinke se ne podudaraju!",
|
||||||
@ -181,7 +181,7 @@
|
|||||||
"notifications": "Notifikacije",
|
"notifications": "Notifikacije",
|
||||||
"accountsecurity": "Bezbednost Naloga",
|
"accountsecurity": "Bezbednost Naloga",
|
||||||
"password": "Lozinka",
|
"password": "Lozinka",
|
||||||
"download": "Skinite Datoteku Rezervne kopije",
|
"download": "Izvezi/Sačuvaj datoteku rezervne kopije",
|
||||||
"choose": "Molim vas izaberite lozinku sa kojom ćete šifrovati rezervnu kopiju. (Ovo može biti ista lozinka sa kojom se prijavljujete, a može biti i različita)",
|
"choose": "Molim vas izaberite lozinku sa kojom ćete šifrovati rezervnu kopiju. (Ovo može biti ista lozinka sa kojom se prijavljujete, a može biti i različita)",
|
||||||
"playsound": "Pustite Zvuk",
|
"playsound": "Pustite Zvuk",
|
||||||
"shownotifications": "Prikažite notifikacije",
|
"shownotifications": "Prikažite notifikacije",
|
||||||
@ -192,8 +192,8 @@
|
|||||||
"protocol": "Protokol",
|
"protocol": "Protokol",
|
||||||
"domain": "Domena",
|
"domain": "Domena",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
"import": "Uvoz Čvorova",
|
"import": "Uvoz sačuvane Čvorova",
|
||||||
"export": "Izvoz Čvorova",
|
"export": "Izvoz sačuvane Čvorova",
|
||||||
"deletecustomnode": "Uklonite sve prilagođene čvorove",
|
"deletecustomnode": "Uklonite sve prilagođene čvorove",
|
||||||
"warning": "Vaši postojeći čvorovi će biti izbrisani, a iz rezervne kopije biće stvoreni novi.",
|
"warning": "Vaši postojeći čvorovi će biti izbrisani, a iz rezervne kopije biće stvoreni novi.",
|
||||||
"snack1": "Uspešno su izbrisani i dodati standardni čvorovi",
|
"snack1": "Uspešno su izbrisani i dodati standardni čvorovi",
|
||||||
@ -207,11 +207,11 @@
|
|||||||
"exp2": "Izvezi glavni ključ",
|
"exp2": "Izvezi glavni ključ",
|
||||||
"exp3": "Izvoz",
|
"exp3": "Izvoz",
|
||||||
"exp4": "Molimo izaberite novčanik za rezervnu kopiju privatnog glavnog ključa.",
|
"exp4": "Molimo izaberite novčanik za rezervnu kopiju privatnog glavnog ključa.",
|
||||||
"core": "Pokreni podešavanja jezgra",
|
"core": "Qortal podešavanja automatskog pokretanja",
|
||||||
"qappNotification1": "Obaveštenja o Q-App",
|
"qappNotification1": "Obaveštenja o Q-App",
|
||||||
"selectnode": "Izaberite opciju",
|
"selectnode": "Izaberite opciju",
|
||||||
"arrr1": "ARRR novčanik nije inicijalizovan!",
|
"arrr1": "ARRR novčanik nije inicijalizovan!",
|
||||||
"arrr2": "Molim vas idite na karticu Novčanik i prvo inicijalizujte svoj arrr novčanik.",
|
"arrr2": "Idite na karticu 'Vallets' i pristupite ARRR novčaniku da biste prvo inicijalizovali novčanik.",
|
||||||
"arrr3": "Potrebno je ažuriranje jezgra!",
|
"arrr3": "Potrebno je ažuriranje jezgra!",
|
||||||
"arrr4": "Da biste sačuvali privatni ključ vašeg arrr novčanika, prvo vam je potrebno ažuriranje jezgra!",
|
"arrr4": "Da biste sačuvali privatni ključ vašeg arrr novčanika, prvo vam je potrebno ažuriranje jezgra!",
|
||||||
"sync_indicator": "Onemogući iskačući prozor indikatora sinhronizacije"
|
"sync_indicator": "Onemogući iskačući prozor indikatora sinhronizacije"
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "Kredit",
|
"balance": "Kredit",
|
||||||
"balances": "VAŠI STANJE U NOVČANIKU",
|
"balances": "VAŠI STANJE U NOVČANIKU",
|
||||||
"update": "AŽURIRAJTE STANJE NOVČANIKA",
|
"update": "AŽURIRAJTE STANJE NOVČANIKA",
|
||||||
"view": "Pogled"
|
"view": "Pogled",
|
||||||
|
"all": "Sve",
|
||||||
|
"page": "Strana"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Gif Ekplorer",
|
"gchange1": "Gif Ekplorer",
|
||||||
@ -283,8 +285,8 @@
|
|||||||
},
|
},
|
||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "Nije moguće preuzeti naloge za kovanje",
|
"smchange1": "Nije moguće preuzeti naloge za kovanje",
|
||||||
"smchange2": "Uklanjanje ključa nije uspelo",
|
"smchange2": "Nije uspelo uklanjanje ključa za kovanje",
|
||||||
"smchange3": "Dodavanje ključa za kovanje nije uspelo",
|
"smchange3": "ako je ključ upravo kreiran, pokušajte da sačekate nekoliko blokova i ponovo dodate",
|
||||||
"smchange4": "Nije moguće kreirati sponzorski ključ",
|
"smchange4": "Nije moguće kreirati sponzorski ključ",
|
||||||
"smchange5": "Stvaranje odnosa",
|
"smchange5": "Stvaranje odnosa",
|
||||||
"smchange6": "Čeka se potvrda na blokčejnu",
|
"smchange6": "Čeka se potvrda na blokčejnu",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "Cena prodaje",
|
"nchange23": "Cena prodaje",
|
||||||
"nchange24": "Nema imena za prodaju",
|
"nchange24": "Nema imena za prodaju",
|
||||||
"nchange25": "Ime za prodaju",
|
"nchange25": "Ime za prodaju",
|
||||||
"nchange26": "Da li ste sigurni da prodajete ovo ime?",
|
"nchange26": "Da li ste sigurni da želite da prodate ovo ime? Ako ime kupi drugi nalog, ono će biti van vaše kontrole!",
|
||||||
"nchange27": "Za ovu cenu u KORT",
|
"nchange27": "Za ovu cenu u KORT",
|
||||||
"nchange28": "Pritiskom na potvrdu, zahtev za ime prodaje će biti poslat!",
|
"nchange28": "Pritiskom na potvrdu, zahtev za ime prodaje će biti poslat!",
|
||||||
"nchange29": "Ime za otkazivanje",
|
"nchange29": "Ime za otkazivanje",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "Ime grupe za pretragu",
|
"gchange56": "Ime grupe za pretragu",
|
||||||
"gchange57": "Ime privatne grupe nije pronađeno",
|
"gchange57": "Ime privatne grupe nije pronađeno",
|
||||||
"gchange58": "Imajte na umu da ime grupe mora potpuno da se podudara.",
|
"gchange58": "Imajte na umu da ime grupe mora potpuno da se podudara.",
|
||||||
"gchange59": "Prikaži / Sakrij Oznaku"
|
"gchange59": "Prikaži / Sakrij Oznaku",
|
||||||
|
"gchange60": "Unesite ime grupe",
|
||||||
|
"gchange61": "Unesite opis",
|
||||||
|
"gchange62": "Želite li zaista da ažurirate ovu grupu?",
|
||||||
|
"gchange63": "Na pritisku POTVRDITE, UPDATE_GROUP će biti poslat!",
|
||||||
|
"gchange64": "Trenutni vlasnik / novi vlasnik",
|
||||||
|
"gchange65": "Zameni ovu adresu NA PRENOS VLASNIŠTVA GRUPE!",
|
||||||
|
"gchange66": "Nevažeći vlasnik / adresa novog vlasnika",
|
||||||
|
"gchange67": "Grupni UPDATE je uspešan!",
|
||||||
|
"gchange68": "Postavi grupni avatar"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Slagalice",
|
"pchange1": "Slagalice",
|
||||||
|
@ -108,14 +108,14 @@
|
|||||||
"decrypt": "Расшифровать резервную копию",
|
"decrypt": "Расшифровать резервную копию",
|
||||||
"save": "Сохранить в приложении",
|
"save": "Сохранить в приложении",
|
||||||
"prepare": "Подготовка вашей учетной записи",
|
"prepare": "Подготовка вашей учетной записи",
|
||||||
"areyousure": "Вы уверены, что хотите удалить этот кошелек из сохраненных кошельков?",
|
"areyousure": "Вы уверены, что хотите удалить эту учетную запись из сохраненных учетных записей? (Если удалить и файл резервной копии не существует, учетная запись может быть потеряна навсегда! Прежде чем делать это, убедитесь, что у вас есть файл резервной копии!)",
|
||||||
"error1": "Резервная копия должна быть в формате JSON",
|
"error1": "Резервная копия должна быть в формате JSON",
|
||||||
"error2": "Вариант входа не выбран",
|
"error2": "Вариант входа не выбран",
|
||||||
"createwelcome": "Добро пожаловать в Qortal! Это чем-то похоже на ролевую игру, в которой вы, как минтер в сети Qortal (если вы решите им стать), будете иметь возможность повысить уровень учетной записи, что повысит долю вашего вознаграждения за каждый блок QORT, а также даст вам больше влияния на сеть, посредством голосования по предложениям для платформы.",
|
"createwelcome": "Добро пожаловать в Qortal! Ваше децентрализованное цифровое будущее ждет вас! Только на Qortal вы имеете абсолютный контроль над своими данными. Qortal обеспечивает базовый уровень нового, полностью контролируемого пользователем цифрового мира.",
|
||||||
"createa": "A",
|
"createa": "A",
|
||||||
"click": "Нажмите, чтобы просмотреть seed-фразу",
|
"click": "Нажмите, чтобы просмотреть seed-фразу",
|
||||||
"confirmpass": "Подтвердите пароль",
|
"confirmpass": "Подтвердите пароль",
|
||||||
"willbe": "Будет генерироваться случайным образом в фоновом режиме для использования в качестве генератора приватного ключа от вашей учетной записи в блокчейне Qortal.",
|
"willbe": "будет генерироваться случайным образом в фоновом режиме. Если вы хотите ПРОСМОТРЕТЬ исходную фразу, щелкните выделенную «начальную фразу» в этом тексте. Он используется в качестве генератора закрытых ключей для вашей учетной записи блокчейна в Qortal. В целях безопасности по умолчанию начальные фразы не отображаются, если это специально не выбрано.",
|
||||||
"clicknext": "Создайте учетную запись Qortal, нажав кнопку ДАЛЕЕ ниже.",
|
"clicknext": "Создайте учетную запись Qortal, нажав кнопку ДАЛЕЕ ниже.",
|
||||||
"ready": "Теперь ваша учетная запись готова к созданию. Она будет сохранена в этом приложении. Если вы не хотите, чтобы ваша новая учетная запись сохранялась в приложении, вы можете снять флажок ниже. Вы по-прежнему сможете войти в свою новую учетную запись (после выхода), используя файл резервной копии вашего кошелька, который вам НЕООБХОДИМО скачать после создания учетной записи.",
|
"ready": "Теперь ваша учетная запись готова к созданию. Она будет сохранена в этом приложении. Если вы не хотите, чтобы ваша новая учетная запись сохранялась в приложении, вы можете снять флажок ниже. Вы по-прежнему сможете войти в свою новую учетную запись (после выхода), используя файл резервной копии вашего кошелька, который вам НЕООБХОДИМО скачать после создания учетной записи.",
|
||||||
"welmessage": "Добро пожаловать в Qortal",
|
"welmessage": "Добро пожаловать в Qortal",
|
||||||
@ -132,8 +132,8 @@
|
|||||||
"backup2": "Этот файл является ЕДИНСТВЕННЫМ способом доступа к вашей учетной записи в системе, в которой он не сохранен в приложении/браузере. ОБЯЗАТЕЛЬНО СДЕЛАЙТЕ РЕЗЕРВНУЮ КОПИЮ ЭТОГО ФАЙЛА В НЕСКОЛЬКИХ МЕСТАХ. Файл очень надежно зашифрован и расшифровывается с помощью вашего локального пароля, который вы создали на предыдущем шаге. Вы можете безопасно сохранить его в любом месте, но не забудьте сделать это в нескольких местах.",
|
"backup2": "Этот файл является ЕДИНСТВЕННЫМ способом доступа к вашей учетной записи в системе, в которой он не сохранен в приложении/браузере. ОБЯЗАТЕЛЬНО СДЕЛАЙТЕ РЕЗЕРВНУЮ КОПИЮ ЭТОГО ФАЙЛА В НЕСКОЛЬКИХ МЕСТАХ. Файл очень надежно зашифрован и расшифровывается с помощью вашего локального пароля, который вы создали на предыдущем шаге. Вы можете безопасно сохранить его в любом месте, но не забудьте сделать это в нескольких местах.",
|
||||||
"savewallet": "Сохранить файл резервной копии кошелька",
|
"savewallet": "Сохранить файл резервной копии кошелька",
|
||||||
"created1": "Ваша учетная запись создана",
|
"created1": "Ваша учетная запись создана",
|
||||||
"created2": "и будет сохранено в этом приложении.",
|
"created2": " и сохраняется в этом интерфейсе в зашифрованном виде",
|
||||||
"downloadbackup": "Скачать файл резервной копии кошелька",
|
"downloadbackup": "Сохранить файл резервной копии Qortal",
|
||||||
"passwordhint": "Пароль должен быть не менее 5 символов.",
|
"passwordhint": "Пароль должен быть не менее 5 символов.",
|
||||||
"lp1": "Экран блокировки",
|
"lp1": "Экран блокировки",
|
||||||
"lp2": "Пароль блокировки экрана не установлен!",
|
"lp2": "Пароль блокировки экрана не установлен!",
|
||||||
@ -181,7 +181,7 @@
|
|||||||
"notifications": "Уведомления",
|
"notifications": "Уведомления",
|
||||||
"accountsecurity": "Сгенерировать QR-код для входа",
|
"accountsecurity": "Сгенерировать QR-код для входа",
|
||||||
"password": "Пароль",
|
"password": "Пароль",
|
||||||
"download": "Загрузить файл резервной копии",
|
"download": "Экспортировать/сохранить файл резервной копии Qortal",
|
||||||
"choose": "Пожалуйста, выберите пароль для шифрования вашей резервной копии. (Это может быть тот же пароль, с которым вы вошли в систему, или другой)",
|
"choose": "Пожалуйста, выберите пароль для шифрования вашей резервной копии. (Это может быть тот же пароль, с которым вы вошли в систему, или другой)",
|
||||||
"playsound": "Воспроизвести звук",
|
"playsound": "Воспроизвести звук",
|
||||||
"shownotifications": "Показать уведомления",
|
"shownotifications": "Показать уведомления",
|
||||||
@ -207,13 +207,13 @@
|
|||||||
"exp2": "Экспорт мастер-ключа",
|
"exp2": "Экспорт мастер-ключа",
|
||||||
"exp3": "Экспорт",
|
"exp3": "Экспорт",
|
||||||
"exp4": "Пожалуйста, выберите кошелек для резервного копирования приватного главного ключа.",
|
"exp4": "Пожалуйста, выберите кошелек для резервного копирования приватного главного ключа.",
|
||||||
"core": "Начать основные настройки",
|
"core": "Настройки автозапуска Qortal",
|
||||||
"qappNotification1": "Уведомления Q-App",
|
"qappNotification1": "Уведомления Q-App",
|
||||||
"selectnode": "Пожалуйста, выберите вариант",
|
"selectnode": "Пожалуйста, выберите вариант",
|
||||||
"arrr1": "Кошелек ARRR не инициализирован!",
|
"arrr1": "Кошелек ARRR не инициализирован!",
|
||||||
"arrr2": "Пожалуйста, перейдите на вкладку кошелька и сначала инициализируйте свой кошелек arrr.",
|
"arrr2": "Пожалуйста, перейдите на вкладку кошелька и получите доступ к кошельку ARRR, чтобы сначала инициализировать кошелек.",
|
||||||
"arrr3": "Требуется обновление ядра!",
|
"arrr3": "Требуется обновление ядра!",
|
||||||
"arrr4": "Чтобы сохранить закрытый ключ вашего кошелька arrr, вам сначала необходимо обновить ядро!",
|
"arrr4": "Чтобы сохранить закрытый ключ вашего ARRR-кошелька, вам необходимо сначала обновить Qortal Core!",
|
||||||
"sync_indicator": "Отключить всплывающее окно индикатора синхронизации"
|
"sync_indicator": "Отключить всплывающее окно индикатора синхронизации"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "кредит",
|
"balance": "кредит",
|
||||||
"balances": "БАЛАНС ВАШЕГО КОШЕЛЬКА",
|
"balances": "БАЛАНС ВАШЕГО КОШЕЛЬКА",
|
||||||
"update": "ОБНОВИТЬ БАЛАНС КОШЕЛЬКА",
|
"update": "ОБНОВИТЬ БАЛАНС КОШЕЛЬКА",
|
||||||
"view": "Вид"
|
"view": "Вид",
|
||||||
|
"all": "Все",
|
||||||
|
"page": "Страница"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Проводник гифок",
|
"gchange1": "Проводник гифок",
|
||||||
@ -284,7 +286,7 @@
|
|||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "Не удается получить учетные записи минтинга",
|
"smchange1": "Не удается получить учетные записи минтинга",
|
||||||
"smchange2": "Не удалось удалить ключ",
|
"smchange2": "Не удалось удалить ключ",
|
||||||
"smchange3": "Не удалось добавить ключ минтинга",
|
"smchange3": "Не удалось добавить ключ минтинга, если ключ был только что создан, попробуйте подождать несколько блоков и добавить еще раз.",
|
||||||
"smchange4": "Не удается создать спонсорский ключ",
|
"smchange4": "Не удается создать спонсорский ключ",
|
||||||
"smchange5": "Создание отношений",
|
"smchange5": "Создание отношений",
|
||||||
"smchange6": "Ожидание подтверждения на блокчейне",
|
"smchange6": "Ожидание подтверждения на блокчейне",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "Цена продажи",
|
"nchange23": "Цена продажи",
|
||||||
"nchange24": "Нет имен для продажи",
|
"nchange24": "Нет имен для продажи",
|
||||||
"nchange25": "Имя для продажи",
|
"nchange25": "Имя для продажи",
|
||||||
"nchange26": "Вы уверены, что продаете это имя?",
|
"nchange26": "Вы уверены, что хотите продать это имя? Если имя будет куплено другой учетной записью, это будет вне вашего контроля!",
|
||||||
"nchange27": "По этой цене в QORT",
|
"nchange27": "По этой цене в QORT",
|
||||||
"nchange28": "При нажатии подтверждения будет отправлен запрос на продажу имени!",
|
"nchange28": "При нажатии подтверждения будет отправлен запрос на продажу имени!",
|
||||||
"nchange29": "Имя для отмены",
|
"nchange29": "Имя для отмены",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "Имя группы для поиска",
|
"gchange56": "Имя группы для поиска",
|
||||||
"gchange57": "Имя частной группы не найдено",
|
"gchange57": "Имя частной группы не найдено",
|
||||||
"gchange58": "Обратите внимание, что название группы должно точно совпадать.",
|
"gchange58": "Обратите внимание, что название группы должно точно совпадать.",
|
||||||
"gchange59": "Показать/скрыть бегущую строку"
|
"gchange59": "Показать/скрыть бегущую строку",
|
||||||
|
"gchange60": "Пожалуйста, введите название группы",
|
||||||
|
"gchange61": "Пожалуйста, введите описание",
|
||||||
|
"gchange62": "Вы обязательно ОБНОВИТЕ эту группу?",
|
||||||
|
"gchange63": "При нажатии кнопки ПОДТВЕРДИТЬ будет отправлен UPDATE_GROUP запрос!",
|
||||||
|
"gchange64": "Текущий владелец / Новый владелец",
|
||||||
|
"gchange65": "Замените этот адрес на TRANSFER OWNERSHIP of group!",
|
||||||
|
"gchange66": "Неверный адрес владельца / нового владельца",
|
||||||
|
"gchange67": "Групповое ОБНОВЛЕНИЕ выполнено успешно!",
|
||||||
|
"gchange68": "Установить групповой аватар"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Головоломки",
|
"pchange1": "Головоломки",
|
||||||
|
@ -46,48 +46,48 @@
|
|||||||
"sm3": "NAMES MARKET"
|
"sm3": "NAMES MARKET"
|
||||||
},
|
},
|
||||||
"tabmenu": {
|
"tabmenu": {
|
||||||
"tm1": "Minting Details",
|
"tm1": "MINTING DETAILS",
|
||||||
"tm2": "Become a Minter",
|
"tm2": "BECOME A MINTER",
|
||||||
"tm3": "Sponsorship List",
|
"tm3": "SPONSORSHIP",
|
||||||
"tm4": "Wallets",
|
"tm4": "WALLETS",
|
||||||
"tm5": "Trade Portal",
|
"tm5": "TRADE PORTAL",
|
||||||
"tm6": "Auto Buy",
|
"tm6": "AUTO-BUY",
|
||||||
"tm7": "Reward Share",
|
"tm7": "REWARD SHARE",
|
||||||
"tm8": "Q-Chat",
|
"tm8": "Q-CHAT",
|
||||||
"tm9": "Name Registration",
|
"tm9": "NAME REGISTRATION",
|
||||||
"tm10": "Names Market",
|
"tm10": "NAMES MARKET",
|
||||||
"tm11": "Websites",
|
"tm11": "WEBSITES",
|
||||||
"tm12": "Q-Apps",
|
"tm12": "Q-APPS",
|
||||||
"tm13": "Group Management",
|
"tm13": "GROUP MANAGEMENT",
|
||||||
"tm14": "Data Management",
|
"tm14": "DATA MANAGEMENT",
|
||||||
"tm15": "Puzzles",
|
"tm15": "PUZZLES",
|
||||||
"tm16": "Node Management",
|
"tm16": "NODE MANAGEMENT",
|
||||||
"tm17": "New Tab",
|
"tm17": "NEW TAB",
|
||||||
"tm18": "Add New Tab",
|
"tm18": "OPEN NEW TAB",
|
||||||
"tm19": "Add New Plugin",
|
"tm19": "ADD CUSTOM LINK",
|
||||||
"tm20": "Q-App",
|
"tm20": "Q-App (input name)",
|
||||||
"tm21": "Website",
|
"tm21": "Website (input name)",
|
||||||
"tm22": "Remove Plugin",
|
"tm22": "REMOVE LINK",
|
||||||
"tm23": "Are you sure to remove this plugin ?",
|
"tm23": "Are you sure to REMOVE this link?",
|
||||||
"tm24": "Plugin Type:",
|
"tm24": "Choose LINK TYPE:",
|
||||||
"tm25": "Please select a plugin type !",
|
"tm25": "Please SELECT a LINK TYPE!",
|
||||||
"tm26": "Add New Plugin To Menu",
|
"tm26": "ADD LINK TO NEW TAB PAGE",
|
||||||
"tm27": "Remove Plugin From Menu",
|
"tm27": "REMOVE LINK FROM NEW TAB PAGE",
|
||||||
"tm28": "Overview Page",
|
"tm28": "OVERVIEW PAGE",
|
||||||
"tm29": "Reset Tab Menu",
|
"tm29": "RESET New Tab Page",
|
||||||
"tm30": "Search Qortal Name",
|
"tm30": "SEARCH For Qortal NAMES",
|
||||||
"tm31": "My Followed Names",
|
"tm31": "My FOLLOWED Names",
|
||||||
"tm32": "This account does not follow any user",
|
"tm32": "This Node is NOT Following Any Names",
|
||||||
"tm33": "Import Tab Menu",
|
"tm33": "IMPORT Saved New Tab LINKS",
|
||||||
"tm34": "Export Tab Menu",
|
"tm34": "EXPORT Saved New Tab LINKS",
|
||||||
"tm35": "Your existing tab menu will be deleted and set to uploaded tab menu.",
|
"tm35": "Your existing New Tab Page Links will be DELETED and REPLACED with IMPORTED New Tab Links.",
|
||||||
"tm36": "Tab Menu Successfully Restored",
|
"tm36": "New Tab Page SUCCESSFULLY RESTORED!",
|
||||||
"tm37": "Tab Menu Successfully Saved As",
|
"tm37": "New Tab Links SUCCESSFULLY SAVED as:",
|
||||||
"tm38": "DEV MODE",
|
"tm38": "DEV MODE",
|
||||||
"tm39": "Add Custom Framework",
|
"tm39": "Add Custom Framework",
|
||||||
"tm40": "Add and Open",
|
"tm40": "Add and Open",
|
||||||
"tm41": "Error: Invalid data please try again!",
|
"tm41": "ERROR: Invalid data please try again!",
|
||||||
"tm42": "Qortal Lottery"
|
"tm42": "LOTTERY"
|
||||||
},
|
},
|
||||||
"login": {
|
"login": {
|
||||||
"login": "Log In",
|
"login": "Log In",
|
||||||
@ -96,45 +96,45 @@
|
|||||||
"address": "Address",
|
"address": "Address",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"youraccounts": "Your accounts",
|
"youraccounts": "Your accounts",
|
||||||
"clickto": "Click your account to log in with it",
|
"clickto": "Click account to login",
|
||||||
"needcreate": "You need to create or save an account before you can log in!",
|
"needcreate": "You need to create or save an account before you can log in!",
|
||||||
"upload": "Upload your Qortal backup",
|
"upload": "Import your Qortal backup file",
|
||||||
"howlogin": "How would you like to log in?",
|
"howlogin": "How would you like to log in?",
|
||||||
"seed": "Seedphrase",
|
"seed": "Seedphrase",
|
||||||
"seedphrase": "seedphrase",
|
"seedphrase": "SEEDPHRASE",
|
||||||
"saved": "Saved account",
|
"saved": "Saved account",
|
||||||
"qora": "Qora address seed",
|
"qora": "QORA address seed",
|
||||||
"backup": "Qortal wallet backup",
|
"backup": "Qortal backup file",
|
||||||
"decrypt": "Decrypt backup",
|
"decrypt": "Decrypt backup file",
|
||||||
"save": "Save in this browser.",
|
"save": "Save in this browser.",
|
||||||
"prepare": "Preparing Your Account",
|
"prepare": "Preparing Your Account...",
|
||||||
"areyousure": "Are you sure you want to remove this wallet from saved wallets?",
|
"areyousure": "Are you sure you want to REMOVE this ACCOUNT from SAVED ACCOUNTS? (If removed and no backup file exists, account could be lost forever! ENSURE YOU HAVE A BACKUP FILE FOR THIS ACCOUNT BEFORE DOING THIS!)",
|
||||||
"error1": "Backup must be valid JSON",
|
"error1": "Backup file must be valid JSON",
|
||||||
"error2": "Login option not selected",
|
"error2": "Login option not selected",
|
||||||
"createwelcome": "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.",
|
"createwelcome": "Welcome to Qortal! Your decentralized digital future awaits you! On Qortal, you and ONLY you have absolute control over your data. Qortal provides the base level of a new, and fully user-controlled digital world!",
|
||||||
"createa": "A",
|
"createa": "A",
|
||||||
"click": "Click to view seedphrase",
|
"click": "CLICK to VIEW SEEDPHRASE",
|
||||||
"confirmpass": "Confirm Password",
|
"confirmpass": "Confirm Password",
|
||||||
"willbe": "will be randomly generated in the background. This is used as your private key generator for your blockchain account in Qortal.",
|
"willbe": "will be randomly generated in the background. If you wish to VIEW THE SEEDPHRASE, click the word 'SEEDPHRASE' in this text. Seedphrases are used to generate the private key for your Qortal account. For security by default, seedphrases are NOT displayed unless specifically chosen.",
|
||||||
"clicknext": "Create your Qortal account by clicking NEXT below.",
|
"clicknext": "Create your Qortal account by clicking NEXT below.",
|
||||||
"ready": "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 log in with your new account (after logging out), using your wallet backup file that you MUST download once you create your account.",
|
"ready": "Your account is now ready to be created. It will be SAVED AND ENCRYPTED within THIS Qortal UI only, by default. If you DO NOT wish for it to be saved, UNCHECK THE BOX BELOW. You are always able to access your new account using the Qortal BACKUP FILE that MUST be SAVED upon account creation.",
|
||||||
"welmessage": "Welcome to Qortal",
|
"welmessage": "Welcome to Qortal",
|
||||||
"pleaseenter": "Please enter a Password!",
|
"pleaseenter": "Please enter a Password!",
|
||||||
"notmatch": "Passwords do not match!",
|
"notmatch": "Oops! Passwords do NOT match! Try again!",
|
||||||
"lessthen8": "Your password is less than 5 characters! This is not recommended. You can continue to ignore this warning.",
|
"lessthen8": "Your password is LESS THAN 5 characters! This is NOT recommended. To continue anyway, click CONTINUE.",
|
||||||
"lessthen8-2": "Your password is less than 5 characters!",
|
"lessthen8-2": "Your password is LESS THAN 5 characters!",
|
||||||
"entername": "Please enter a Name!",
|
"entername": "Please enter a Display Name!",
|
||||||
"downloaded": "Your Wallet BackUp file was downloaded!",
|
"downloaded": "Your Qortal Backup File was SAVED!",
|
||||||
"loading": "Loading, Please wait...",
|
"loading": "LOADING, Please wait...",
|
||||||
"createdseed": "Your created Seedphrase",
|
"createdseed": "Your Generated Seedphrase:",
|
||||||
"saveseed": "Save Seedphrase",
|
"saveseed": "SAVE SEEDPHRASE",
|
||||||
"savein": "Save in browser",
|
"savein": "SAVE in THIS UI",
|
||||||
"backup2": "This file is the ONLY way to access your account on a system that doesn't have it saved to the app/browser. BE SURE TO BACKUP THIS FILE IN MULTIPLE PLACES. 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.",
|
"backup2": "This file is the ONLY WAY (by default) to ACCESS YOUR ACCOUNT (unless saved to the UI). BE SURE TO BACKUP THIS FILE IN MULTIPLE LOCATIONS. The file is ENCRYPTED very securely (and decrypted) with your local PASSWORD created in the previous step. You can save the Qortal Backup File anywhere securely, but be sure to do so in MULTIPLE PLACES.",
|
||||||
"savewallet": "Save Wallet BackUp File",
|
"savewallet": "SAVE Qortal Backup File",
|
||||||
"created1": "Your account is now created",
|
"created1": "Your account is now created",
|
||||||
"created2": " and will be saved in this browser.",
|
"created2": " and saved in THIS UI in ENCRYPTED form.",
|
||||||
"downloadbackup": "Download Wallet BackUp File",
|
"downloadbackup": "SAVE Qortal Backup File",
|
||||||
"passwordhint": "A password must be at least 5 characters.",
|
"passwordhint": "Encryption password is suggested to be at least 5 characters.",
|
||||||
"lp1": "Lock Screen",
|
"lp1": "Lock Screen",
|
||||||
"lp2": "No screen lock password is set!",
|
"lp2": "No screen lock password is set!",
|
||||||
"lp3": "Please set one",
|
"lp3": "Please set one",
|
||||||
@ -163,8 +163,8 @@
|
|||||||
"confirmlogout": "Are you sure you want to log out?"
|
"confirmlogout": "Are you sure you want to log out?"
|
||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "Select file",
|
"selectfile": "Select Backup File",
|
||||||
"dragfile": "Drag and drop backup here"
|
"dragfile": "Drag and drop or CLICK HERE to select Backup File"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "General Account Info",
|
"generalinfo": "General Account Info",
|
||||||
@ -174,46 +174,46 @@
|
|||||||
"account": "Account",
|
"account": "Account",
|
||||||
"security": "Security",
|
"security": "Security",
|
||||||
"qr_login_menu_item": "QR Login",
|
"qr_login_menu_item": "QR Login",
|
||||||
"qr_login_description_1": "Scan this code to unlock your wallet on another device using the same password which you logged in with.",
|
"qr_login_description_1": "Scan this code to save your wallet on another device using the same password currently logged in with.",
|
||||||
"qr_login_description_2": "Choose a password which you will use to unlock your wallet on another device after scanning the QR code.",
|
"qr_login_description_2": "Choose a password to unlock your wallet on another device after scanning QR code.",
|
||||||
"qr_login_button_1": "Show login QR code",
|
"qr_login_button_1": "Show login QR code",
|
||||||
"qr_login_button_2": "Generate login QR code",
|
"qr_login_button_2": "Generate login QR code",
|
||||||
"notifications": "Notifications",
|
"notifications": "Notifications",
|
||||||
"accountsecurity": "Account Security",
|
"accountsecurity": "Account Security",
|
||||||
"password": "Password",
|
"password": "Password",
|
||||||
"download": "Download Backup File",
|
"download": "Export/Save Backup File",
|
||||||
"choose": "Please choose a password to encrypt your backup with. (This can be the same as the one you logged in with, or different)",
|
"choose": "Please input a password to encrypt your backup file. (This can be the same as the one you logged in with, or a new one.)",
|
||||||
"playsound": "Play Sound",
|
"playsound": "Play Sound",
|
||||||
"shownotifications": "Show Notifications",
|
"shownotifications": "Show Notifications",
|
||||||
"nodeurl": "Node Url",
|
"nodeurl": "Node Url",
|
||||||
"nodehint": "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",
|
"nodehint": "Select a Node from the default list, or add a custom Node to the list by clicking on the button below",
|
||||||
"addcustomnode": "Add Custom Node",
|
"addcustomnode": "Add Custom Node",
|
||||||
"addandsave": "Add and Save",
|
"addandsave": "Add and Save",
|
||||||
"protocol": "Protocol",
|
"protocol": "Protocol",
|
||||||
"domain": "Domain",
|
"domain": "Domain",
|
||||||
"port": "Port",
|
"port": "Port",
|
||||||
"import": "Import Nodes",
|
"import": "Import Saved Nodes",
|
||||||
"export": "Export Nodes",
|
"export": "Export Saved Nodes",
|
||||||
"deletecustomnode": "Remove All Custom Nodes",
|
"deletecustomnode": "REMOVE ALL Custom Nodes",
|
||||||
"warning": "Your existing nodes will be deleted and reset to default.",
|
"warning": "Your Custom Nodes will be deleted and reset to default.",
|
||||||
"snack1": "Successfully deleted and added default nodes",
|
"snack1": "Successfully deleted and added default Nodes",
|
||||||
"snack2": "UI conected to node",
|
"snack2": "UI conected to Node",
|
||||||
"snack3": "Successfully added and saved custom node",
|
"snack3": "Successfully ADDED and saved Custom Node (select from drop-down to use)",
|
||||||
"snack4": "Nodes successfully saved as",
|
"snack4": "Nodes successfully exported as:",
|
||||||
"snack5": "Nodes successfully imported",
|
"snack5": "Nodes successfully imported",
|
||||||
"snack6": "Successfully removed custom node",
|
"snack6": "Successfully removed Custom Node",
|
||||||
"snack7": "Successfully edited custom node",
|
"snack7": "Successfully edited Custom Node",
|
||||||
"exp1": "Export Private Master Key",
|
"exp1": "Export Master Private Key (xpriv)",
|
||||||
"exp2": "Export Master Key",
|
"exp2": "Export Master Key",
|
||||||
"exp3": "Export",
|
"exp3": "Export",
|
||||||
"exp4": "Please choose a wallet to backup the private master key.",
|
"exp4": "Please select a wallet to backup/export master private key.",
|
||||||
"core": "Start Core Settings",
|
"core": "Core auto-start settings",
|
||||||
"qappNotification1": "Q-App Notifications",
|
"qappNotification1": "Q-App Notifications",
|
||||||
"selectnode": "Please select an option",
|
"selectnode": "Please select an option",
|
||||||
"arrr1": "ARRR Wallet Not Initialized !",
|
"arrr1": "ARRR Wallet Not Initialized!",
|
||||||
"arrr2": "Please go to wallet tab and initialize your arrr wallet first.",
|
"arrr2": "Please go to wallet tab and access ARRR wallet to initialize wallet first.",
|
||||||
"arrr3": "Need Core Update !",
|
"arrr3": "Need Core Update !",
|
||||||
"arrr4": "To save the private key of your arrr wallet you need a core update first !",
|
"arrr4": "To save the private key of your ARRR wallet you must first update the Qortal Core!",
|
||||||
"sync_indicator": "Disable sync indicator popup"
|
"sync_indicator": "Disable sync indicator popup"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "Balance",
|
"balance": "Balance",
|
||||||
"balances": "YOUR WALLET BALANCES",
|
"balances": "YOUR WALLET BALANCES",
|
||||||
"update": "UPDATE WALLET BALANCES",
|
"update": "UPDATE WALLET BALANCES",
|
||||||
"view": "View"
|
"view": "View",
|
||||||
|
"all": "All",
|
||||||
|
"page": "Page"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Gif Explorer",
|
"gchange1": "Gif Explorer",
|
||||||
@ -276,22 +278,22 @@
|
|||||||
"gchange23": "Your gif collection cannot contain two gifs with the same name!",
|
"gchange23": "Your gif collection cannot contain two gifs with the same name!",
|
||||||
"gchange24": "This collection name is already taken. Try another name!",
|
"gchange24": "This collection name is already taken. Try another name!",
|
||||||
"gchange25": "GIF (click to view)",
|
"gchange25": "GIF (click to view)",
|
||||||
"gchange26": "A name is needed to access and send GIF files",
|
"gchange26": "Registered Name required to access and send GIF files",
|
||||||
"gchange27": "The gif collection size is over 25mb! Please try again!",
|
"gchange27": "The gif collection size is over 25mb! Please try again!",
|
||||||
"gchange28": "Each gif in the collection cannot be over 0.7mb! Please try again!",
|
"gchange28": "Each gif in the collection cannot be over 0.7mb! Please try again!",
|
||||||
"gchange29": "Filename"
|
"gchange29": "Filename"
|
||||||
},
|
},
|
||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "Cannot fetch minting accounts",
|
"smchange1": "Cannot fetch Minting Accounts",
|
||||||
"smchange2": "Failed to remove key",
|
"smchange2": "Failed to remove Minting Key",
|
||||||
"smchange3": "Failed to add minting key",
|
"smchange3": "Failed to add Minting Key, if key was just created try waiting a few blocks and adding again",
|
||||||
"smchange4": "Cannot create sponsorship key",
|
"smchange4": "Cannot create Key (Keys can only be created once!)",
|
||||||
"smchange5": "Creating relationship",
|
"smchange5": "Creating relationship",
|
||||||
"smchange6": "Awaiting confirmation on blockchain",
|
"smchange6": "Awaiting confirmation on blockchain",
|
||||||
"smchange7": "Finishing up relationship",
|
"smchange7": "Finishing up...",
|
||||||
"smchange8": "Adding minting key to node",
|
"smchange8": "Adding Minting Key to Node",
|
||||||
"smchange9": "Complete",
|
"smchange9": "Complete",
|
||||||
"smchange10": "Only 2 minting keys are allowed per node, you are attempting to assign 3 keys, please go to Management - Node Management, and remove the key you do not want to assign to this node, thank you!"
|
"smchange10": "Only 2 Minting Keys are allowed per Node, you are attempting to assign 3 keys, please go to Node Management, and remove any unnecessary keys, thank you!"
|
||||||
},
|
},
|
||||||
"mintingpage": {
|
"mintingpage": {
|
||||||
"mchange1": "General Minting Details",
|
"mchange1": "General Minting Details",
|
||||||
@ -311,7 +313,7 @@
|
|||||||
"mchange15": "Current Status",
|
"mchange15": "Current Status",
|
||||||
"mchange16": "Current Level",
|
"mchange16": "Current Level",
|
||||||
"mchange17": "Blocks To Next Level",
|
"mchange17": "Blocks To Next Level",
|
||||||
"mchange18": "If you continue minting 24/7 you will reach level",
|
"mchange18": "If you continue Minting 24/7 you will reach level",
|
||||||
"mchange19": "Minting Rewards Info",
|
"mchange19": "Minting Rewards Info",
|
||||||
"mchange20": "Current Tier",
|
"mchange20": "Current Tier",
|
||||||
"mchange21": "Total Minters in The Tier",
|
"mchange21": "Total Minters in The Tier",
|
||||||
@ -327,17 +329,17 @@
|
|||||||
"mchange31": "Press for help",
|
"mchange31": "Press for help",
|
||||||
"mchange32": "Become A Minter",
|
"mchange32": "Become A Minter",
|
||||||
"mchange33": "Introduction",
|
"mchange33": "Introduction",
|
||||||
"mchange34": "In Qortal, in order to become a minter and begin earning QORT rewards with your increase in Minter Level, you must first become ‘sponsored’. A sponsor in Qortal is any other minter of level 5 or higher, or a Qortal Founder. You will obtain a minting key from the sponsor, and use that key to get to level 1. Once you have reached level 1, you will be able to create your own minting key and start earning rewards for helping secure the Qortal Blockchain.",
|
"mchange34": "In Qortal, in order to become a Minter and begin earning QORT rewards with your increase in Minter Level, you must first obtain a tamporary Key called a 'Sponsorship Key'. A Sponsor in Qortal is any other minter of level 5 or higher, or a Qortal Founder. You will obtain a Minting Key from the Sponsor, and use that key to get to level 1. Once you have reached level 1, you will be able to create your own Minting Key and start earning rewards for helping secure the Qortal Blockchain.",
|
||||||
"mchange35": "Sponsorship",
|
"mchange35": "Sponsorship",
|
||||||
"mchange36": "Your sponsor will issue you a ‘Minting Key’ which you will use to add to your node, and begin minting (for no rewards until reaching level 1.) Once you reach level 1, you create/assign your own ‘Minting Key’ and begin earning rewards.",
|
"mchange36": "Your Sponsor will issue you a ‘Sponsorship Key’ which you will use to add to your Node, and begin minting for no rewards (until reaching level 1.) Once you reach level 1, you create/assign your own ‘Minting Key’ and begin earning rewards.",
|
||||||
"mchange37": "Simply reach out to a minter in Qortal who is high enough level to issue a minting key, obtain that key, then come back here and input the key to begin your minting journey!",
|
"mchange37": "Simply reach out to a Minter in Qortal who is high enough level to issue a Minting Key, obtain that key, then come back here and input the key to begin your minting journey!",
|
||||||
"mchange38": "in"
|
"mchange38": "in"
|
||||||
},
|
},
|
||||||
"becomeMinterPage": {
|
"becomeMinterPage": {
|
||||||
"bchange7": "Enter Minting Key",
|
"bchange7": "Enter Minting Key",
|
||||||
"bchange8": "Input key from your sponsor here",
|
"bchange8": "Input key from your sponsor here",
|
||||||
"bchange10": "Current Sponsorship Status",
|
"bchange10": "Current Sponsorship Status",
|
||||||
"bchange12": "Minting with sponsor's key",
|
"bchange12": "Minting with Sponsorship Key",
|
||||||
"bchange13": "Blocks Remaining in Sponsorship Period",
|
"bchange13": "Blocks Remaining in Sponsorship Period",
|
||||||
"bchange15": "Sponsorship Relationship",
|
"bchange15": "Sponsorship Relationship",
|
||||||
"bchange16": "Sponsor Account",
|
"bchange16": "Sponsor Account",
|
||||||
@ -440,17 +442,17 @@
|
|||||||
"tchange31": "SOLD",
|
"tchange31": "SOLD",
|
||||||
"tchange32": "BOUGHT",
|
"tchange32": "BOUGHT",
|
||||||
"tchange33": "Average",
|
"tchange33": "Average",
|
||||||
"tchange34": "Amount can not be 0",
|
"tchange34": "Amount cannot be 0",
|
||||||
"tchange35": "Price can not be 0",
|
"tchange35": "Price cannot be 0",
|
||||||
"tchange36": "PENDING AUTO BUY",
|
"tchange36": "PENDING AUTO BUY",
|
||||||
"tchange37": "No auto buy order found!",
|
"tchange37": "No Auto Buy order found!",
|
||||||
"tchange38": "ADD",
|
"tchange38": "ADD",
|
||||||
"tchange39": "AUTO BUY ORDER",
|
"tchange39": "AUTO BUY ORDER",
|
||||||
"tchange40": "Price",
|
"tchange40": "Price",
|
||||||
"tchange41": "Successfully removed auto buy order!",
|
"tchange41": "Successfully removed Auto Buy order!",
|
||||||
"tchange42": "MARKET OPEN SELL ORDERS",
|
"tchange42": "MARKET OPEN SELL ORDERS",
|
||||||
"tchange43": "MY BUY HISTORY",
|
"tchange43": "MY BUY HISTORY",
|
||||||
"tchange44": "Successfully added auto buy order!",
|
"tchange44": "Successfully added Auto Buy order!",
|
||||||
"tchange45": "AUTO BUY WITH",
|
"tchange45": "AUTO BUY WITH",
|
||||||
"tchange46": "AUTO BUY",
|
"tchange46": "AUTO BUY",
|
||||||
"tchange47": "Sell for this price",
|
"tchange47": "Sell for this price",
|
||||||
@ -458,22 +460,22 @@
|
|||||||
"tchange49": "Price Chart"
|
"tchange49": "Price Chart"
|
||||||
},
|
},
|
||||||
"rewardsharepage": {
|
"rewardsharepage": {
|
||||||
"rchange1": "Rewardshares",
|
"rchange1": "Reward Shares",
|
||||||
"rchange2": "Create reward share",
|
"rchange2": "Create Reward Share",
|
||||||
"rchange3": "Rewardshares Involving This Account",
|
"rchange3": "Rewardshares Involving This Account",
|
||||||
"rchange4": "Minting Account",
|
"rchange4": "Minting Account",
|
||||||
"rchange5": "Share Percent",
|
"rchange5": "Share Percent",
|
||||||
"rchange6": "Recipient",
|
"rchange6": "Recipient",
|
||||||
"rchange7": "Action",
|
"rchange7": "Action",
|
||||||
"rchange8": "Type",
|
"rchange8": "Type",
|
||||||
"rchange9": "Level 1 - 4 can create a Self Share and Level 5 or above can create a Reward Share!",
|
"rchange9": "Levels 1 - 4 can only create a Self-Share (minting) keys. Only Level 5 or above can create a Reward Share!",
|
||||||
"rchange10": "Recipient Public Key",
|
"rchange10": "Recipient's Public Key",
|
||||||
"rchange11": "Reward share percentage",
|
"rchange11": "Reward Share percentage",
|
||||||
"rchange12": "Doing something delicious",
|
"rchange12": "Executing Requested Command...",
|
||||||
"rchange13": "Adding minting account",
|
"rchange13": "Adding Minting Account",
|
||||||
"rchange14": "Add",
|
"rchange14": "Add",
|
||||||
"rchange15": "Account is not involved in any reward shares",
|
"rchange15": "Account is not involved in any Reward Shares",
|
||||||
"rchange16": "Own Rewardshare",
|
"rchange16": "Create Minting Key",
|
||||||
"rchange17": "Remove",
|
"rchange17": "Remove",
|
||||||
"rchange18": "Cannot Create Multiple Reward Shares!",
|
"rchange18": "Cannot Create Multiple Reward Shares!",
|
||||||
"rchange19": "Cannot Create Multiple Self Shares!",
|
"rchange19": "Cannot Create Multiple Self Shares!",
|
||||||
@ -507,29 +509,29 @@
|
|||||||
"nchange23": "Sell Price",
|
"nchange23": "Sell Price",
|
||||||
"nchange24": "No Names To Sell",
|
"nchange24": "No Names To Sell",
|
||||||
"nchange25": "Name To Sell",
|
"nchange25": "Name To Sell",
|
||||||
"nchange26": "Are you sure to sell this name?",
|
"nchange26": "Are you sure you want to sell this name? If Name is purchased by another account, all data Published by this Name will be out of your control!",
|
||||||
"nchange27": "For this price in QORT",
|
"nchange27": "For this price in QORT",
|
||||||
"nchange28": "On pressing confirm, the sell name request will be sent!",
|
"nchange28": "On pressing confirm, your Name will be listed for sale!",
|
||||||
"nchange29": "Name To Cancel",
|
"nchange29": "Name To Cancel",
|
||||||
"nchange30": "Are you sure to cancel the sell for this name?",
|
"nchange30": "Are you sure to cancel the sell for this Name?",
|
||||||
"nchange31": "On pressing confirm, the cancel sell name request will be sent!",
|
"nchange31": "On pressing confirm, the Name Sale will be canceled!",
|
||||||
"nchange32": "Sell Name Request Successful!",
|
"nchange32": "Sell Name Request Successful!",
|
||||||
"nchange33": "Cancel Sell Name Request Successful!",
|
"nchange33": "Cancel Sell Name Request Successful!",
|
||||||
"nchange34": "Buy Name Request Successful!",
|
"nchange34": "Buy Name Request Successful!",
|
||||||
"nchange35": "YOU HAVE A NAME!",
|
"nchange35": "YOU HAVE A NAME!",
|
||||||
"nchange36": "Only accounts with no registered name can buy a name.",
|
"nchange36": "Only accounts with no Registered Name can buy a Name.",
|
||||||
"nchange37": "ATTENTION!",
|
"nchange37": "ATTENTION!",
|
||||||
"nchange38": "You not have enough QORT to buy this name.",
|
"nchange38": "You not have enough QORT to buy this Name.",
|
||||||
"nchange39": "Are you sure to buy this name?",
|
"nchange39": "Are you sure to buy this Name?",
|
||||||
"nchange40": "On pressing confirm, the buy name request will be sent!",
|
"nchange40": "On pressing confirm, the Buy Name request will be sent!",
|
||||||
"nchange41": "Old Name",
|
"nchange41": "Old Name",
|
||||||
"nchange42": "New Name",
|
"nchange42": "New Name",
|
||||||
"nchange43": "Are you sure to change this name?",
|
"nchange43": "Are you sure to change this name?",
|
||||||
"nchange44": "To the new name",
|
"nchange44": "To the new name",
|
||||||
"nchange45": "On pressing confirm, the name update request will be sent!",
|
"nchange45": "On pressing confirm, the Update Name request will be sent!",
|
||||||
"nchange46": "Name Sale History",
|
"nchange46": "Name Sale History",
|
||||||
"nchange47": "Name Update Successful!",
|
"nchange47": "Name Update Successful!",
|
||||||
"nchange48": "Warning! If you update your name, you will forfeit the resources associated with the original name. In other words, you will lose ownership of the content under the original name in the QDN. Proceed with caution!"
|
"nchange48": "Warning! If you update your Name, you will forfeit the resources associated with the original Name. In other words, you will lose ownership of the content under the original Name on QDN. Proceed with caution!"
|
||||||
},
|
},
|
||||||
"websitespage": {
|
"websitespage": {
|
||||||
"schange1": "Browse Websites",
|
"schange1": "Browse Websites",
|
||||||
@ -538,7 +540,7 @@
|
|||||||
"schange4": "Search Websites",
|
"schange4": "Search Websites",
|
||||||
"schange5": "Avatar",
|
"schange5": "Avatar",
|
||||||
"schange6": "Details",
|
"schange6": "Details",
|
||||||
"schange7": "Published by",
|
"schange7": "Published by:",
|
||||||
"schange8": "Actions",
|
"schange8": "Actions",
|
||||||
"schange9": "Websites",
|
"schange9": "Websites",
|
||||||
"schange10": "No websites available",
|
"schange10": "No websites available",
|
||||||
@ -549,14 +551,14 @@
|
|||||||
"schange15": "Blocked Websites",
|
"schange15": "Blocked Websites",
|
||||||
"schange16": "You have not blocked any websites",
|
"schange16": "You have not blocked any websites",
|
||||||
"schange17": "Name Not Found!",
|
"schange17": "Name Not Found!",
|
||||||
"schange18": "Relay mode is enabled. This means that your node will help to transport encrypted data around the network when a peer requests it. You can opt out by setting",
|
"schange18": "Relay Mode is ENABLED. This means that your Node will help to transport ENCRYPTED/CHUNKED data around the network when a peer requests it. You can opt out by setting:",
|
||||||
"schange19": "in",
|
"schange19": "in",
|
||||||
"schange20": "Relay mode is disabled. You can enable it by setting",
|
"schange20": "Relay mode is DISABLED. You can enable it by setting:",
|
||||||
"schange21": "Publish Website",
|
"schange21": "Publish Website",
|
||||||
"schange22": "Error occurred when trying to follow this registered name. Please try again!",
|
"schange22": "Error occurred when trying to follow this Registered Name. Please try again!",
|
||||||
"schange23": "Error occurred when trying to unfollow this registered name. Please try again!",
|
"schange23": "Error occurred when trying to unfollow this Registered Name. Please try again!",
|
||||||
"schange24": "Error occurred when trying to block this registered name. Please try again!",
|
"schange24": "Error occurred when trying to block this Registered Name. Please try again!",
|
||||||
"schange25": "Error occurred when trying to unblock this registered name. Please try again!",
|
"schange25": "Error occurred when trying to unblock this Registered Name. Please try again!",
|
||||||
"schange26": "Uncategorized",
|
"schange26": "Uncategorized",
|
||||||
"schange27": "Size",
|
"schange27": "Size",
|
||||||
"schange28": "Status",
|
"schange28": "Status",
|
||||||
@ -586,14 +588,14 @@
|
|||||||
"schange15": "Blocked Q-Apps",
|
"schange15": "Blocked Q-Apps",
|
||||||
"schange16": "You have not blocked any Q-Apps",
|
"schange16": "You have not blocked any Q-Apps",
|
||||||
"schange17": "Name Not Found!",
|
"schange17": "Name Not Found!",
|
||||||
"schange18": "Relay mode is enabled. This means that your node will help to transport encrypted data around the network when a peer requests it. You can opt out by setting",
|
"schange18": "Relay mode is enabled. This means that your Node will help to transport ENCRYPTED/CHUNKED data around the network when a peer requests it. You can opt out by setting",
|
||||||
"schange19": "in",
|
"schange19": "in",
|
||||||
"schange20": "Relay mode is disabled. You can enable it by setting",
|
"schange20": "Relay mode is disabled. You can enable it by setting",
|
||||||
"schange21": "Publish Q-App",
|
"schange21": "Publish Q-App",
|
||||||
"schange22": "Error occurred when trying to follow this registered name. Please try again!",
|
"schange22": "Error occurred when trying to follow this Registered Name. Please try again!",
|
||||||
"schange23": "Error occurred when trying to unfollow this registered name. Please try again!",
|
"schange23": "Error occurred when trying to unfollow this Registered Name. Please try again!",
|
||||||
"schange24": "Error occurred when trying to block this registered name. Please try again!",
|
"schange24": "Error occurred when trying to block this Registered Name. Please try again!",
|
||||||
"schange25": "Error occurred when trying to unblock this registered name. Please try again!",
|
"schange25": "Error occurred when trying to unblock this Registered Name. Please try again!",
|
||||||
"schange26": "Uncategorized",
|
"schange26": "Uncategorized",
|
||||||
"schange27": "Size",
|
"schange27": "Size",
|
||||||
"schange28": "Status",
|
"schange28": "Status",
|
||||||
@ -602,7 +604,7 @@
|
|||||||
"schange31": "Block",
|
"schange31": "Block",
|
||||||
"schange32": "Unblock",
|
"schange32": "Unblock",
|
||||||
"schange33": "Name to search",
|
"schange33": "Name to search",
|
||||||
"schange34": "Name can not be empty!",
|
"schange34": "Name cannot be empty!",
|
||||||
"schange35": "Search",
|
"schange35": "Search",
|
||||||
"schange36": "Download",
|
"schange36": "Download",
|
||||||
"schange37": "Downloaded",
|
"schange37": "Downloaded",
|
||||||
@ -631,14 +633,14 @@
|
|||||||
"schange15": "Blocked Q-Tubes",
|
"schange15": "Blocked Q-Tubes",
|
||||||
"schange16": "You have not blocked any Q-Tubes",
|
"schange16": "You have not blocked any Q-Tubes",
|
||||||
"schange17": "Name Not Found!",
|
"schange17": "Name Not Found!",
|
||||||
"schange18": "Relay mode is enabled. This means that your node will help to transport encrypted data around the network when a peer requests it. You can opt out by setting",
|
"schange18": "Relay Mode is ENABLED. This means that your Node will help to transport ENCRYPTED/CHUNKED data around the network when a peer requests it. You can opt out by setting:",
|
||||||
"schange19": "in",
|
"schange19": "in",
|
||||||
"schange20": "Relay mode is disabled. You can enable it by setting",
|
"schange20": "Relay mode is DISABLED. You can enable it by setting:",
|
||||||
"schange21": "Publish Video",
|
"schange21": "Publish Video",
|
||||||
"schange22": "Error occurred when trying to follow this registered name. Please try again!",
|
"schange22": "Error occurred when trying to follow this Registered Name. Please try again!",
|
||||||
"schange23": "Error occurred when trying to unfollow this registered name. Please try again!",
|
"schange23": "Error occurred when trying to unfollow this Registered Name. Please try again!",
|
||||||
"schange24": "Error occurred when trying to block this registered name. Please try again!",
|
"schange24": "Error occurred when trying to block this Registered Name. Please try again!",
|
||||||
"schange25": "Error occurred when trying to unblock this registered name. Please try again!",
|
"schange25": "Error occurred when trying to unblock this Registered Name. Please try again!",
|
||||||
"schange26": "Uncategorized",
|
"schange26": "Uncategorized",
|
||||||
"schange27": "Size",
|
"schange27": "Size",
|
||||||
"schange28": "Status",
|
"schange28": "Status",
|
||||||
@ -661,7 +663,7 @@
|
|||||||
"publishpage": {
|
"publishpage": {
|
||||||
"pchange1": "Publish",
|
"pchange1": "Publish",
|
||||||
"pchange2": "Update",
|
"pchange2": "Update",
|
||||||
"pchange3": "Note: it is recommended that you set up port forwarding before hosting data, so that it can more easily be accessed by peers on the network.",
|
"pchange3": "Note: it is recommended that you set up Port Forwarding before hosting data, so that it can more easily be accessed by peers on the network.",
|
||||||
"pchange4": "Select Name",
|
"pchange4": "Select Name",
|
||||||
"pchange5": "Title",
|
"pchange5": "Title",
|
||||||
"pchange6": "Description",
|
"pchange6": "Description",
|
||||||
@ -672,11 +674,11 @@
|
|||||||
"pchange11": "Publish",
|
"pchange11": "Publish",
|
||||||
"pchange12": "Select zip file containing static content",
|
"pchange12": "Select zip file containing static content",
|
||||||
"pchange13": "Local path to static files",
|
"pchange13": "Local path to static files",
|
||||||
"pchange14": "Please select a registered name to publish data for",
|
"pchange14": "Please select a Registered Name to publish data for",
|
||||||
"pchange15": "Please select a file to host",
|
"pchange15": "Please select a file to host",
|
||||||
"pchange16": "Please select a zip file to host",
|
"pchange16": "Please select a zip file to host",
|
||||||
"pchange17": "Please enter the directory path containing the static content",
|
"pchange17": "Please enter the directory path containing the static content",
|
||||||
"pchange18": "Please enter a service name",
|
"pchange18": "Please enter a Service Name",
|
||||||
"pchange19": "Processing data... this can take some time...",
|
"pchange19": "Processing data... this can take some time...",
|
||||||
"pchange20": "Error:",
|
"pchange20": "Error:",
|
||||||
"pchange21": "Internal Server Error when publishing data",
|
"pchange21": "Internal Server Error when publishing data",
|
||||||
@ -691,16 +693,16 @@
|
|||||||
"bchange2": "Reload",
|
"bchange2": "Reload",
|
||||||
"bchange3": "Back to list",
|
"bchange3": "Back to list",
|
||||||
"bchange4": "Delete",
|
"bchange4": "Delete",
|
||||||
"bchange5": "from node",
|
"bchange5": "From Node",
|
||||||
"bchange6": "Your browser doesn't support iframes",
|
"bchange6": "Your browser doesn't support iframes",
|
||||||
"bchange7": "Follow",
|
"bchange7": "Follow",
|
||||||
"bchange8": "Unfollow",
|
"bchange8": "Unfollow",
|
||||||
"bchange9": "Block",
|
"bchange9": "Block",
|
||||||
"bchange10": "Unblock",
|
"bchange10": "Unblock",
|
||||||
"bchange11": "Error occurred when trying to follow this registered name. Please try again!",
|
"bchange11": "Error occurred when trying to follow this Registered Name. Please try again!",
|
||||||
"bchange12": "Error occurred when trying to unfollow this registered name. Please try again!",
|
"bchange12": "Error occurred when trying to unfollow this Registered Name. Please try again!",
|
||||||
"bchange13": "Error occurred when trying to block this registered name. Please try again!",
|
"bchange13": "Error occurred when trying to block this Registered Name. Please try again!",
|
||||||
"bchange14": "Error occurred when trying to unblock this registered name. Please try again!",
|
"bchange14": "Error occurred when trying to unblock this Registered Name. Please try again!",
|
||||||
"bchange15": "Can't delete data from followed names. Please unfollow first.",
|
"bchange15": "Can't delete data from followed names. Please unfollow first.",
|
||||||
"bchange16": "Error occurred when trying to delete this resource. Please try again!",
|
"bchange16": "Error occurred when trying to delete this resource. Please try again!",
|
||||||
"bchange17": "User declined to share account details",
|
"bchange17": "User declined to share account details",
|
||||||
@ -744,25 +746,25 @@
|
|||||||
},
|
},
|
||||||
"datapage": {
|
"datapage": {
|
||||||
"dchange1": "Data Management",
|
"dchange1": "Data Management",
|
||||||
"dchange2": "Search in hosted data by this node",
|
"dchange2": "Search in hosted data by this Node",
|
||||||
"dchange3": "Data to search",
|
"dchange3": "Data to search",
|
||||||
"dchange4": "Search",
|
"dchange4": "Search",
|
||||||
"dchange5": "Registered Name",
|
"dchange5": "Registered Name",
|
||||||
"dchange6": "Service",
|
"dchange6": "Service",
|
||||||
"dchange7": "Identifier",
|
"dchange7": "Identifier",
|
||||||
"dchange8": "Actions",
|
"dchange8": "Actions",
|
||||||
"dchange9": "Data hosted by this node",
|
"dchange9": "Data hosted by this Node",
|
||||||
"dchange10": "Data name can not be empty!",
|
"dchange10": "Data name can not be empty!",
|
||||||
"dchange11": "Data not found!",
|
"dchange11": "Data not found!",
|
||||||
"dchange12": "Couldn't fetch hosted data list from node",
|
"dchange12": "Couldn't fetch hosted data list from Node",
|
||||||
"dchange13": "This node isn't hosting any data",
|
"dchange13": "This Node isn't hosting any data",
|
||||||
"dchange14": "Unfollow",
|
"dchange14": "Unfollow",
|
||||||
"dchange15": "Delete",
|
"dchange15": "Delete",
|
||||||
"dchange16": "Block",
|
"dchange16": "Block",
|
||||||
"dchange17": "Unblock",
|
"dchange17": "Unblock",
|
||||||
"dchange18": "Error occurred when trying to block this registered name. Please try again!",
|
"dchange18": "Error occurred when trying to block this Registered Name. Please try again!",
|
||||||
"dchange19": "Error occurred when trying to unfollow this registered name. Please try again!",
|
"dchange19": "Error occurred when trying to unfollow this Registered Name. Please try again!",
|
||||||
"dchange20": "Error occurred when trying to unblock this registered name. Please try again!",
|
"dchange20": "Error occurred when trying to unblock this Registered Name. Please try again!",
|
||||||
"dchange21": "Error occurred when trying to delete this resource. Please try again!"
|
"dchange21": "Error occurred when trying to delete this resource. Please try again!"
|
||||||
},
|
},
|
||||||
"chatpage": {
|
"chatpage": {
|
||||||
@ -780,7 +782,7 @@
|
|||||||
"cchange12": "Owner",
|
"cchange12": "Owner",
|
||||||
"cchange13": "Action",
|
"cchange13": "Action",
|
||||||
"cchange14": "This account has not blocked any users.",
|
"cchange14": "This account has not blocked any users.",
|
||||||
"cchange15": "No registered name",
|
"cchange15": "No Registered Name",
|
||||||
"cchange16": "Successfully unblocked this user.",
|
"cchange16": "Successfully unblocked this user.",
|
||||||
"cchange17": "Error occurred when trying to unblock this user. Please try again!",
|
"cchange17": "Error occurred when trying to unblock this user. Please try again!",
|
||||||
"cchange18": "unblock",
|
"cchange18": "unblock",
|
||||||
@ -792,7 +794,7 @@
|
|||||||
"cchange24": "Maximum Characters per message is 255",
|
"cchange24": "Maximum Characters per message is 255",
|
||||||
"cchange25": "Edit Message",
|
"cchange25": "Edit Message",
|
||||||
"cchange26": "File size exceeds 0.5 MB",
|
"cchange26": "File size exceeds 0.5 MB",
|
||||||
"cchange27": "A registered name is required to send images",
|
"cchange27": "A Registered Name is required to send images",
|
||||||
"cchange28": "This file is not an image",
|
"cchange28": "This file is not an image",
|
||||||
"cchange29": "Maximum message size is 1000 bytes",
|
"cchange29": "Maximum message size is 1000 bytes",
|
||||||
"cchange30": "Uploading image. This may take up to one minute.",
|
"cchange30": "Uploading image. This may take up to one minute.",
|
||||||
@ -806,7 +808,7 @@
|
|||||||
"cchange39": "Cannot send an encrypted message to this user since they do not have their publickey on chain.",
|
"cchange39": "Cannot send an encrypted message to this user since they do not have their publickey on chain.",
|
||||||
"cchange40": "IMAGE (click to view)",
|
"cchange40": "IMAGE (click to view)",
|
||||||
"cchange41": "Your Balance Is Under 4 QORT",
|
"cchange41": "Your Balance Is Under 4 QORT",
|
||||||
"cchange42": "Out of the need to combat spam, accounts with under 4 QORT balance will take a long time to SEND messages in Q-Chat. If you wish to immediately increase the send speed for Q-Chat messages, obtain over 4 QORT to your address. This can be done with trades in the Trade Portal, or by way of another Qortian giving you the QORT. Once you have over 4 QORT in your account, Q-Chat messages will be instant and this dialog will no more show. Thank you for your understanding of this necessary spam prevention method, and we hope you enjoy Qortal!",
|
"cchange42": "Out of the need to combat spam, accounts with UNDER 4 QORT BALANCE will take a long time to SEND messages in Q-Chat. If you wish to immediately increase the send speed for Q-Chat messages, obtain over 4 QORT to your address. This can be done with trades in the Trade Portal, or by way of another Qortian giving you the QORT. Once you have over 4 QORT in your account, Q-Chat messages will be instant and this dialog will not show. It does NOT cost QORT to send messages. Thank you for your understanding of this necessary spam prevention method, and we hope you enjoy Qortal!",
|
||||||
"cchange43": "Tip QORT to",
|
"cchange43": "Tip QORT to",
|
||||||
"cchange44": "SEND MESSAGE",
|
"cchange44": "SEND MESSAGE",
|
||||||
"cchange45": "TIP USER",
|
"cchange45": "TIP USER",
|
||||||
@ -870,7 +872,7 @@
|
|||||||
"bcchange1": "Block User",
|
"bcchange1": "Block User",
|
||||||
"bcchange2": "Successfully blocked this user!",
|
"bcchange2": "Successfully blocked this user!",
|
||||||
"bcchange3": "Error occurred when trying to block this user. Please try again!",
|
"bcchange3": "Error occurred when trying to block this user. Please try again!",
|
||||||
"bcchange4": "No registered name",
|
"bcchange4": "No Registered Name",
|
||||||
"bcchange5": "Block User Request",
|
"bcchange5": "Block User Request",
|
||||||
"bcchange6": "Are you sure to block this user?",
|
"bcchange6": "Are you sure to block this user?",
|
||||||
"bcchange7": "MENU",
|
"bcchange7": "MENU",
|
||||||
@ -901,7 +903,7 @@
|
|||||||
"gchange12": "Create a New Group",
|
"gchange12": "Create a New Group",
|
||||||
"gchange13": "Group Type",
|
"gchange13": "Group Type",
|
||||||
"gchange14": "This Field is Required",
|
"gchange14": "This Field is Required",
|
||||||
"gchange15": "Select an option",
|
"gchange15": "--SELECT AN OPTION--",
|
||||||
"gchange16": "Public",
|
"gchange16": "Public",
|
||||||
"gchange17": "Private",
|
"gchange17": "Private",
|
||||||
"gchange18": "Group Approval Threshold (number / percentage of Admins that must approve a transaction):",
|
"gchange18": "Group Approval Threshold (number / percentage of Admins that must approve a transaction):",
|
||||||
@ -930,7 +932,7 @@
|
|||||||
"gchange41": "Group Creation Successful!",
|
"gchange41": "Group Creation Successful!",
|
||||||
"gchange42": "Invalid Group Name",
|
"gchange42": "Invalid Group Name",
|
||||||
"gchange43": "Invalid Group Description",
|
"gchange43": "Invalid Group Description",
|
||||||
"gchange44": "Select a Group Type",
|
"gchange44": "Select Group Type",
|
||||||
"gchange45": "Select a Group Approval Threshold",
|
"gchange45": "Select a Group Approval Threshold",
|
||||||
"gchange46": "Select a Minimum Block delay for Group Transaction Approvals",
|
"gchange46": "Select a Minimum Block delay for Group Transaction Approvals",
|
||||||
"gchange47": "Select a Maximum Block delay for Group Transaction Approvals",
|
"gchange47": "Select a Maximum Block delay for Group Transaction Approvals",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "Group Name To Search",
|
"gchange56": "Group Name To Search",
|
||||||
"gchange57": "Private Group Name Not Found",
|
"gchange57": "Private Group Name Not Found",
|
||||||
"gchange58": "Note that group name must be an exact match.",
|
"gchange58": "Note that group name must be an exact match.",
|
||||||
"gchange59": "Show / Hide Ticker"
|
"gchange59": "Show / Hide Ticker",
|
||||||
|
"gchange60": "Please enter group name",
|
||||||
|
"gchange61": "Please enter description",
|
||||||
|
"gchange62": "Are you sure to UPDATE this group?",
|
||||||
|
"gchange63": "On pressing CONFIRM, the UPDATE_GROUP request will be sent!",
|
||||||
|
"gchange64": "Current Owner / New Owner",
|
||||||
|
"gchange65": "Only replace this address if you want to transfer the group!",
|
||||||
|
"gchange66": "Invalid Owner / New Owner Address",
|
||||||
|
"gchange67": "Group Update Successful!",
|
||||||
|
"gchange68": "Set Group Avatar"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "Puzzles",
|
"pchange1": "Puzzles",
|
||||||
@ -979,8 +990,8 @@
|
|||||||
"nchange10": "Recipient Account",
|
"nchange10": "Recipient Account",
|
||||||
"nchange11": "Action",
|
"nchange11": "Action",
|
||||||
"nchange12": "Remove",
|
"nchange12": "Remove",
|
||||||
"nchange13": "No minting accounts found for this node",
|
"nchange13": "No minting accounts found for this Node",
|
||||||
"nchange14": "Peers connected to this node",
|
"nchange14": "Peers connected to this Node",
|
||||||
"nchange15": "Add peer",
|
"nchange15": "Add peer",
|
||||||
"nchange16": "Type the peer you wish to add's address below",
|
"nchange16": "Type the peer you wish to add's address below",
|
||||||
"nchange17": "Peer Address",
|
"nchange17": "Peer Address",
|
||||||
@ -1003,7 +1014,7 @@
|
|||||||
"nchange34": "Successfully Sent Restart Request!",
|
"nchange34": "Successfully Sent Restart Request!",
|
||||||
"nchange35": "Start Node",
|
"nchange35": "Start Node",
|
||||||
"nchange36": "Successfully Started Node!",
|
"nchange36": "Successfully Started Node!",
|
||||||
"nchange37": "Clicking on continue will refresh your Qortal Core, your db will be removed, and you will downoad a new copy of the db, called “bootstrapping“.",
|
"nchange37": "Clicking on continue will refresh your Qortal Core, your db will be removed, and you will download a new copy of the db, called “bootstrapping“.",
|
||||||
"nchange38": "Repair LTC Wallet",
|
"nchange38": "Repair LTC Wallet",
|
||||||
"nchange39": "This will repair LTC wallets that show a balance that cannot be spent. It requires a single transaction to be made on the Litecoin network, after confirmation the wallet balance will be functional and the issue will not happen again.",
|
"nchange39": "This will repair LTC wallets that show a balance that cannot be spent. It requires a single transaction to be made on the Litecoin network, after confirmation the wallet balance will be functional and the issue will not happen again.",
|
||||||
"nchange40": "This transaction will consume a small LTC fee. Continue?",
|
"nchange40": "This transaction will consume a small LTC fee. Continue?",
|
||||||
@ -1021,7 +1032,7 @@
|
|||||||
"apipage": {
|
"apipage": {
|
||||||
"achange1": "Add API key",
|
"achange1": "Add API key",
|
||||||
"achange2": "API key",
|
"achange2": "API key",
|
||||||
"achange3": "Please enter the API key for this node. It can be found in a file called “apikey.txt“ in the directory where the core is installed. Alternatively, click Cancel to use the core with reduced functionality.",
|
"achange3": "Please enter the API key for this Node. It can be found in a file called “apikey.txt“ in the directory where the core is installed. Alternatively, click Cancel to use the core with reduced functionality.",
|
||||||
"achange4": "Cancel",
|
"achange4": "Cancel",
|
||||||
"achange5": "Add",
|
"achange5": "Add",
|
||||||
"achange6": "Successfully added API Key",
|
"achange6": "Successfully added API Key",
|
||||||
@ -1041,8 +1052,8 @@
|
|||||||
"groupdialog6": "On pressing confirm, the group creating request will be sent!",
|
"groupdialog6": "On pressing confirm, the group creating request will be sent!",
|
||||||
"rewarddialog1": "Would you like to create a reward share transaction, sharing",
|
"rewarddialog1": "Would you like to create a reward share transaction, sharing",
|
||||||
"rewarddialog2": "of your minting rewards with",
|
"rewarddialog2": "of your minting rewards with",
|
||||||
"rewarddialog3": "If yes, you will need to save the key below in order to mint. It can be supplied to any node in order to allow it to mint on your behalf.",
|
"rewarddialog3": "If yes, you will need to save the key below in order to mint. It can be supplied to any Node in order to allow it to mint on your behalf.",
|
||||||
"rewarddialog4": "On pressing confirm, the reward share will be created, but you will still need to supply the above key to a node in order to mint with the account.",
|
"rewarddialog4": "On pressing confirm, the reward share will be created, but you will still need to supply the above key to a Node in order to mint with the account.",
|
||||||
"rewarddialog5": "You are removing a reward share transaction associated with account:",
|
"rewarddialog5": "You are removing a reward share transaction associated with account:",
|
||||||
"rewarddialog6": "On pressing confirm, the reward share will be removed and the minting key will become invalid.",
|
"rewarddialog6": "On pressing confirm, the reward share will be removed and the minting key will become invalid.",
|
||||||
"deployAtdialog1": "You are deploying the AT",
|
"deployAtdialog1": "You are deploying the AT",
|
||||||
@ -1083,7 +1094,7 @@
|
|||||||
"exp2": "Account Balance",
|
"exp2": "Account Balance",
|
||||||
"exp3": "More Info",
|
"exp3": "More Info",
|
||||||
"exp4": "Address or Name not found!",
|
"exp4": "Address or Name not found!",
|
||||||
"exp5": "Note that registered names are case-sensitive.",
|
"exp5": "Note that Registered Names are case-sensitive.",
|
||||||
"exp6": "Founder",
|
"exp6": "Founder",
|
||||||
"exp7": "Info",
|
"exp7": "Info",
|
||||||
"exp8": "Show all buy trades",
|
"exp8": "Show all buy trades",
|
||||||
@ -1176,7 +1187,7 @@
|
|||||||
"inf7": "Auto Buy Information",
|
"inf7": "Auto Buy Information",
|
||||||
"inf8": "Close Auto Buy Info",
|
"inf8": "Close Auto Buy Info",
|
||||||
"inf9": "'Auto Buy' is a feature that allows 'buy orders' to be placed on the Trade Portal. These 'buy orders' are only visible by the person placing them. They are not 'public' buy orders like the 'open market sells' are, and are NOT stored on the Qortal blockchain. Auto Buy is a UI feature, and as such requires that the UI is RUNNING.",
|
"inf9": "'Auto Buy' is a feature that allows 'buy orders' to be placed on the Trade Portal. These 'buy orders' are only visible by the person placing them. They are not 'public' buy orders like the 'open market sells' are, and are NOT stored on the Qortal blockchain. Auto Buy is a UI feature, and as such requires that the UI is RUNNING.",
|
||||||
"inf10": "To place an Auto Buy order click 'Add Auto Buy Order' button and fill out the box that comes up. Input the AMOUNT OF QORT you wish to BUY, and the PRICE you are willing to BUY UP TO. Once the order is active, Auto Buy will buy UP TO that amount of QORT for you, at UP TO the price you set (starting at the lowest order and moving up the books.)",
|
"inf10": "To place an Auto Buy order click 'Add Auto Buy Order' button and fill out the box that comes up. Input the AMOUNT OF QORT you wish to BUY or the amount of LTC you wish to use, and the PRICE you are willing to BUY UP TO. Once the order is active, Auto Buy will buy UP TO that amount of QORT for you, at UP TO the price you set (starting at the lowest order and moving up the books.)",
|
||||||
"inf11": "Simply LEAVE YOUR UI RUNNING and Auto Buy does the rest, automatically!",
|
"inf11": "Simply LEAVE YOUR UI RUNNING and Auto Buy does the rest, automatically!",
|
||||||
"inf12": "You CAN browse other plugins in the UI (Q-Chat, wallets, etc.) but you CANNOT CLOSE THE UI if you want your Auto Buy to complete. Leaving the UI 'minimized' on the 'taskbar' or 'panel' is just fine, as long as the UI remains OPEN Auto Buy will function.",
|
"inf12": "You CAN browse other plugins in the UI (Q-Chat, wallets, etc.) but you CANNOT CLOSE THE UI if you want your Auto Buy to complete. Leaving the UI 'minimized' on the 'taskbar' or 'panel' is just fine, as long as the UI remains OPEN Auto Buy will function.",
|
||||||
"inf13": "Automatically buy",
|
"inf13": "Automatically buy",
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
"tm32": "该帐户没有关注任何用户",
|
"tm32": "该帐户没有关注任何用户",
|
||||||
"tm33": "导入选项卡菜单",
|
"tm33": "导入选项卡菜单",
|
||||||
"tm34": "导出选项卡菜单",
|
"tm34": "导出选项卡菜单",
|
||||||
"tm35": "您现有的选项卡菜单将被删除并设置为上传的选项卡菜单。",
|
"tm35": "您现有的选项卡菜单将被删除并设置为导入的选项卡菜单。",
|
||||||
"tm36": "选项卡菜单恢复成功",
|
"tm36": "选项卡菜单恢复成功",
|
||||||
"tm37": "选项卡菜单成功另存为",
|
"tm37": "选项卡菜单成功另存为",
|
||||||
"tm38": "开发模式",
|
"tm38": "开发模式",
|
||||||
@ -108,32 +108,32 @@
|
|||||||
"decrypt": "正在解密钱包备份文件",
|
"decrypt": "正在解密钱包备份文件",
|
||||||
"save": "保存钱包,以便下次登入.",
|
"save": "保存钱包,以便下次登入.",
|
||||||
"prepare": "正在加载你的钱包",
|
"prepare": "正在加载你的钱包",
|
||||||
"areyousure": "你确定将此钱包在已保存钱包列表中删除吗?",
|
"areyousure": "您确定要从已保存的帐户中删除此帐户吗? (如果删除并且不存在备份文件,帐户可能会永远丢失!在执行此操作之前确保您有备份文件!",
|
||||||
"error1": "备份文件必须为有效的JSON格式文件",
|
"error1": "备份文件必须为有效的JSON格式文件",
|
||||||
"error2": "请选择登入方式",
|
"error2": "请选择登入方式",
|
||||||
"createwelcome": "欢迎来到Qortal,您会发现它类似于RPG 游戏,作为Qortal 网络上的铸币者(如果您选择成为其中的铸币者),您将有机会升级您的帐户,并随着等级提高而获得更多QORT 区块奖励以及参与平台上各种决策投票。",
|
"createwelcome": "欢迎来到Qortal! 您的去中心化数字未来正等待着您! 在 Qortal 上,只有您对您的数据拥有绝对的控制权。 Qortal 提供了一个新的、完全由用户控制的数字世界的基础水平。",
|
||||||
"createa": "你的",
|
"createa": "你的",
|
||||||
"click": "点击查看助记词",
|
"click": "点击查看助记词",
|
||||||
"confirmpass": "确认密码",
|
"confirmpass": "确认密码",
|
||||||
"willbe": "将在后台随机生成。 这将用作您在Qortal 中的区块链帐户的私人密钥。",
|
"willbe": "将在后台随机生成。 如果您想查看种子短语,请单击本文中突出显示的“种子短语”。 这用作您在 Qortal 中的区块链帐户的私钥生成器。 为了安全起见,默认情况下,除非特别选择,否则不会显示助记词。",
|
||||||
"clicknext": " ▼▼▼点击下一步创建你的Qortal账号▼▼▼",
|
"clicknext": " ▼▼▼点击下一步创建你的Qortal账号▼▼▼",
|
||||||
"ready": "您的帐户即将创建成功, 它将保存在此浏览器中。 如果您不希望将新帐户保存在浏览器中,可以取消勾选下面的选项。 您仍可透过使用创建帐户时载的钱包备份文件进行的登入。",
|
"ready": "您的帐户现在已准备好创建。 默认情况下,它将以加密形式保存在 Qortal UI 的此副本中。 如果您不希望在此处保存您的新帐户,您可以取消选中下面的复选框。 您仍然可以使用新帐户登录(注销后),使用创建帐户后必须下载的钱包备份文件。",
|
||||||
"welmessage": "欢迎来到Qortal",
|
"welmessage": "欢迎来到Qortal",
|
||||||
"pleaseenter": "请密码!",
|
"pleaseenter": "请密码!",
|
||||||
"notmatch": "密码不一致!",
|
"notmatch": "密码不一致!",
|
||||||
"lessthen8": "你的密码长度少于5位! 我们不建议使用,但你仍可继续使用此密码。",
|
"lessthen8": "你的密码长度少于5位! 我们不建议使用,但你仍可继续使用此密码。",
|
||||||
"lessthen8-2": "你的密码长度少于5位!",
|
"lessthen8-2": "你的密码长度少于5位!",
|
||||||
"entername": "请输入一个代称",
|
"entername": "请输入显示名称!",
|
||||||
"downloaded": "你的钱包备份文件已顺利下载!",
|
"downloaded": "你的钱包备份文件已顺利下载!",
|
||||||
"loading": "加载中,请耐心等候...",
|
"loading": "加载中,请耐心等候...",
|
||||||
"createdseed": "你已创建的助记词",
|
"createdseed": "你已创建的助记词",
|
||||||
"saveseed": "保存助记词",
|
"saveseed": "保存助记词",
|
||||||
"savein": "保存在UI上",
|
"savein": "保存在UI上",
|
||||||
"backup2": "请小心保存钱包备份文件,并谨记之前设置好的密码。否则你将会失去这个钱包的所有控制权,请务必将备份文件放在不同的存储装置上",
|
"backup2": "除非保存到 UI,否则此文件是访问您帐户的唯一方式(默认情况下)。 请务必在多个位置备份此文件。 该文件经过非常安全的加密,并使用您在上一步中创建的本地密码进行解密。 您可以将其安全地保存在任何地方,但请务必在多个位置执行此操作。",
|
||||||
"savewallet": "下载并保存钱包备份文件",
|
"savewallet": "保存 Qortal 备份文件",
|
||||||
"created1": "你的账号已创建成功",
|
"created1": "你的账号已创建成功",
|
||||||
"created2": "并会储存在UI上.",
|
"created2": "并以加密形式保存在此 UI 中。",
|
||||||
"downloadbackup": "下载钱包备份文件",
|
"downloadbackup": "保存 Qortal 备份文件",
|
||||||
"passwordhint": "密码必须至少为5 个字符。",
|
"passwordhint": "密码必须至少为5 个字符。",
|
||||||
"lp1": "锁定屏幕",
|
"lp1": "锁定屏幕",
|
||||||
"lp2": "未设置锁屏密码!",
|
"lp2": "未设置锁屏密码!",
|
||||||
@ -164,7 +164,7 @@
|
|||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "选择文件",
|
"selectfile": "选择文件",
|
||||||
"dragfile": "将备份文件拖到此处"
|
"dragfile": "拖放或单击此处选择备份文件"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "一般钱包信息",
|
"generalinfo": "一般钱包信息",
|
||||||
@ -181,7 +181,7 @@
|
|||||||
"notifications": "通知",
|
"notifications": "通知",
|
||||||
"accountsecurity": "钱包安全性",
|
"accountsecurity": "钱包安全性",
|
||||||
"password": "密码",
|
"password": "密码",
|
||||||
"download": "下载备份文件",
|
"download": "导出/保存 Qortal 备份文件",
|
||||||
"choose": "请输入一组密码加密你的备份文件。(可使用你刚才登入时的相同密码或者不同的密码)",
|
"choose": "请输入一组密码加密你的备份文件。(可使用你刚才登入时的相同密码或者不同的密码)",
|
||||||
"playsound": "开启音效",
|
"playsound": "开启音效",
|
||||||
"shownotifications": "显示通知",
|
"shownotifications": "显示通知",
|
||||||
@ -192,8 +192,8 @@
|
|||||||
"protocol": "协议",
|
"protocol": "协议",
|
||||||
"domain": "域名",
|
"domain": "域名",
|
||||||
"port": "端口",
|
"port": "端口",
|
||||||
"import": "导入节点",
|
"import": "导入已保存的节点",
|
||||||
"export": "导出节点",
|
"export": "导出保存的节点",
|
||||||
"deletecustomnode": "删除所有自定义节点",
|
"deletecustomnode": "删除所有自定义节点",
|
||||||
"warning": "您现有的节点将被删除并从备份中创建新的。",
|
"warning": "您现有的节点将被删除并从备份中创建新的。",
|
||||||
"snack1": "成功删除和添加标准节点",
|
"snack1": "成功删除和添加标准节点",
|
||||||
@ -203,17 +203,17 @@
|
|||||||
"snack5": "节点成功导入",
|
"snack5": "节点成功导入",
|
||||||
"snack6": "成功删除自定义节点",
|
"snack6": "成功删除自定义节点",
|
||||||
"snack7": "自定义节点编辑成功",
|
"snack7": "自定义节点编辑成功",
|
||||||
"exp1": "导出主密钥",
|
"exp1": "导出主私钥 (xpriv)",
|
||||||
"exp2": "导出主密钥",
|
"exp2": "导出主密钥",
|
||||||
"exp3": "导出",
|
"exp3": "导出",
|
||||||
"exp4": "请选择一个钱包来备份私钥。",
|
"exp4": "请选择一个钱包来备份私钥。",
|
||||||
"core": "开始核心设置",
|
"core": "Qortal Core 自动启动设置",
|
||||||
"qappNotification1": "Q-App 通知",
|
"qappNotification1": "Q-App 通知",
|
||||||
"selectnode": "请选择一个选项",
|
"selectnode": "请选择一个选项",
|
||||||
"arrr1": "ARRR 钱包未初始化!",
|
"arrr1": "ARRR 钱包未初始化!",
|
||||||
"arrr2": "请先进入钱包选项卡并初始化您的arrr钱包。",
|
"arrr2": "请先进入“钱包”选项卡并访问 ARRR 钱包以初始化钱包。",
|
||||||
"arrr3": "需要核心更新!",
|
"arrr3": "需要核心更新!",
|
||||||
"arrr4": "要保存你的 arr 钱包的私钥,你需要先进行核心更新!",
|
"arrr4": "要保存 ARRR 钱包的私钥,您必须首先更新 Qortal Core!",
|
||||||
"sync_indicator": "禁用同步指示器弹出窗口"
|
"sync_indicator": "禁用同步指示器弹出窗口"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "余额",
|
"balance": "余额",
|
||||||
"balances": "您的钱包余额",
|
"balances": "您的钱包余额",
|
||||||
"update": "更新钱包余额",
|
"update": "更新钱包余额",
|
||||||
"view": "看法"
|
"view": "看法",
|
||||||
|
"all": "全部",
|
||||||
|
"page": "页"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Gif 浏览器",
|
"gchange1": "Gif 浏览器",
|
||||||
@ -283,8 +285,8 @@
|
|||||||
},
|
},
|
||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "无法获取铸币帐户",
|
"smchange1": "无法获取铸币帐户",
|
||||||
"smchange2": "无法移除密钥",
|
"smchange2": "无法删除 Minting 密钥",
|
||||||
"smchange3": "添加铸币密钥失败",
|
"smchange3": "无法添加 Minting key,如果刚刚创建 key,请尝试等待几个块并再次添加",
|
||||||
"smchange4": "无法创建赞助密钥",
|
"smchange4": "无法创建赞助密钥",
|
||||||
"smchange5": "建立关系",
|
"smchange5": "建立关系",
|
||||||
"smchange6": "等待区块链确认",
|
"smchange6": "等待区块链确认",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "卖出价",
|
"nchange23": "卖出价",
|
||||||
"nchange24": "没有名字可以卖",
|
"nchange24": "没有名字可以卖",
|
||||||
"nchange25": "出售名称",
|
"nchange25": "出售名称",
|
||||||
"nchange26": "你确定要卖这个名字吗?",
|
"nchange26": "您确定要出售这个名字吗? 如果名称被其他帐户购买,则将不受您的控制!",
|
||||||
"nchange27": "对于QORT 中的这个价格",
|
"nchange27": "对于QORT 中的这个价格",
|
||||||
"nchange28": "按下确认后,将发送销售名称请求!",
|
"nchange28": "按下确认后,将发送销售名称请求!",
|
||||||
"nchange29": "要取消的名称",
|
"nchange29": "要取消的名称",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "要搜索的群组名称",
|
"gchange56": "要搜索的群组名称",
|
||||||
"gchange57": "未找到私人群组名称",
|
"gchange57": "未找到私人群组名称",
|
||||||
"gchange58": "注意群组名称必须完全匹配。",
|
"gchange58": "注意群组名称必须完全匹配。",
|
||||||
"gchange59": "显示/隐藏代码"
|
"gchange59": "显示/隐藏代码",
|
||||||
|
"gchange60": "请输入组名",
|
||||||
|
"gchange61": "请输入描述",
|
||||||
|
"gchange62": "你确定要更新这个组吗?",
|
||||||
|
"gchange63": "按 CONFIRM 后,将发送UPDATE_GROUP请求!",
|
||||||
|
"gchange64": "当前所有者/新所有者",
|
||||||
|
"gchange65": "将此地址替换为组的 TRANSFER OWNERSHIP!",
|
||||||
|
"gchange66": "无效的所有者/新所有者地址",
|
||||||
|
"gchange67": "组更新成功!",
|
||||||
|
"gchange68": "设置组头像"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "益智游戏",
|
"pchange1": "益智游戏",
|
||||||
|
@ -80,7 +80,7 @@
|
|||||||
"tm32": "該帳戶沒有關注任何用戶",
|
"tm32": "該帳戶沒有關注任何用戶",
|
||||||
"tm33": "導入選項卡菜單",
|
"tm33": "導入選項卡菜單",
|
||||||
"tm34": "導出選項卡菜單",
|
"tm34": "導出選項卡菜單",
|
||||||
"tm35": "您現有的選項卡菜單將被刪除並設置為上傳的選項卡菜單。",
|
"tm35": "您现有的选项卡菜单将被删除并设置为导入的选项卡菜单。",
|
||||||
"tm36": "選項卡菜單恢復成功",
|
"tm36": "選項卡菜單恢復成功",
|
||||||
"tm37": "選項卡菜單成功另存為",
|
"tm37": "選項卡菜單成功另存為",
|
||||||
"tm38": "開發模式",
|
"tm38": "開發模式",
|
||||||
@ -98,7 +98,7 @@
|
|||||||
"youraccounts": "你的錢包",
|
"youraccounts": "你的錢包",
|
||||||
"clickto": "點擊你的錢包進行登錄",
|
"clickto": "點擊你的錢包進行登錄",
|
||||||
"needcreate": "你必須創建或保存錢包才能登入!",
|
"needcreate": "你必須創建或保存錢包才能登入!",
|
||||||
"upload": "上傳你的Qortal錢包備份文件",
|
"upload": "匯入您的 Qortal 備份文件",
|
||||||
"howlogin": "你想透過下列哪種方式登入?",
|
"howlogin": "你想透過下列哪種方式登入?",
|
||||||
"seed": "助記詞",
|
"seed": "助記詞",
|
||||||
"seedphrase": "助記詞",
|
"seedphrase": "助記詞",
|
||||||
@ -108,16 +108,16 @@
|
|||||||
"decrypt": "正在解密錢包備份文件",
|
"decrypt": "正在解密錢包備份文件",
|
||||||
"save": "保存錢包,以便下次登入.",
|
"save": "保存錢包,以便下次登入.",
|
||||||
"prepare": "正在加載你的錢包",
|
"prepare": "正在加載你的錢包",
|
||||||
"areyousure": "你確定將此錢包在已保存錢包列表中刪除嗎?",
|
"areyousure": "您確定要從已儲存的帳戶中刪除此帳戶嗎? (如果刪除並且不存在備份文件,帳戶可能會永遠丟失!在執行此操作之前確保您有備份文件!)",
|
||||||
"error1": "備份文件必須為有效的JSON格式文件",
|
"error1": "備份文件必須為有效的JSON格式文件",
|
||||||
"error2": "請選擇登入方式",
|
"error2": "請選擇登入方式",
|
||||||
"createwelcome": "歡迎來到 Qortal,您會發現它類似於 RPG 遊戲,作為 Qortal 網絡上的鑄幣者(如果您選擇成為其中的鑄幣者),您將有機會升級您的帳戶,並隨著等級提高而獲得更多 QORT 區塊獎勵以及參與平台上各種決策投票。",
|
"createwelcome": "歡迎來到Qortal! 您的去中心化數位未來正等著您! 在 Qortal 上,只有您對您的資料擁有絕對的控制權。 Qortal 提供了一個新的、完全由使用者控制的數位世界的基礎水準。",
|
||||||
"createa": "你的",
|
"createa": "你的",
|
||||||
"click": "點擊查看助記詞",
|
"click": "點擊查看助記詞",
|
||||||
"confirmpass": "確認密碼",
|
"confirmpass": "確認密碼",
|
||||||
"willbe": "將在後台隨機生成。 這將用作您在 Qortal 中的區塊鏈帳戶的私人密鑰。",
|
"willbe": "將在後台隨機產生。 如果您想查看種子短語,請點擊本文中突出顯示的「種子短語」。 這用作您在 Qortal 中的區塊鏈帳戶的私鑰產生器。 為了安全起見,預設情況下,除非特別選擇,否則不會顯示助記詞。",
|
||||||
"clicknext": "▼▼▼點擊下一步創建你的Qortal賬號▼▼▼",
|
"clicknext": "▼▼▼點擊下一步創建你的Qortal賬號▼▼▼",
|
||||||
"ready": "您的帳戶即將創建成功, 它將保存在此瀏覽器中。 如果您不希望將新帳戶保存在瀏覽器中,可以取消勾選下面的選項。 您仍可透過使用創建帳戶時載的錢包備份文件進行的登入。",
|
"ready": "您的帳戶現在已準備好建立。 預設情況下,它將以加密形式保存在 Qortal UI 的此副本中。 如果您不希望在此處儲存您的新帳戶,您可以取消選取下面的複選框。 您仍然可以使用新帳戶登入(登出後),使用建立帳戶後必須下載的錢包備份檔案。",
|
||||||
"welmessage": "歡迎來到 Qortal",
|
"welmessage": "歡迎來到 Qortal",
|
||||||
"pleaseenter": "請密碼!",
|
"pleaseenter": "請密碼!",
|
||||||
"notmatch": "密碼不一致!",
|
"notmatch": "密碼不一致!",
|
||||||
@ -129,11 +129,11 @@
|
|||||||
"createdseed": "你已創建的助記詞",
|
"createdseed": "你已創建的助記詞",
|
||||||
"saveseed": "保存助記詞",
|
"saveseed": "保存助記詞",
|
||||||
"savein": "保存在UI上",
|
"savein": "保存在UI上",
|
||||||
"backup2": "請小心保存錢包備份文件,並謹記之前設置好的密碼。否則你將會失去這個錢包的所有控制權,請務必將備份文件放在不同的存儲裝置上",
|
"backup2": "除非儲存到 UI,否則此文件是存取您帳戶的唯一方式(預設)。 請務必在多個位置備份此文件。 該檔案經過非常安全的加密,並使用您在上一個步驟中建立的本機密碼進行解密。 您可以將其安全地保存在任何地方,但請務必在多個位置執行此操作。",
|
||||||
"savewallet": "下載並保存錢包備份文件",
|
"savewallet": "下載並保存錢包備份文件",
|
||||||
"created1": "你的賬號已創建成功",
|
"created1": "你的賬號已創建成功",
|
||||||
"created2": " 並會儲存在UI上.",
|
"created2": "並以加密形式儲存在此 UI 中。",
|
||||||
"downloadbackup": "下載錢包備份文件",
|
"downloadbackup": "保存 Qortal 備份文件",
|
||||||
"passwordhint": "密碼必須至少為 5 個字符。",
|
"passwordhint": "密碼必須至少為 5 個字符。",
|
||||||
"lp1": "鎖定屏幕",
|
"lp1": "鎖定屏幕",
|
||||||
"lp2": "未設置鎖屏密碼!",
|
"lp2": "未設置鎖屏密碼!",
|
||||||
@ -163,8 +163,8 @@
|
|||||||
"confirmlogout": "你確定登出嗎?"
|
"confirmlogout": "你確定登出嗎?"
|
||||||
},
|
},
|
||||||
"fragfile": {
|
"fragfile": {
|
||||||
"selectfile": "選擇文件",
|
"selectfile": "選擇 Qortal 備份文件",
|
||||||
"dragfile": "將備份文件拖到此處"
|
"dragfile": "拖放或點擊此處選擇備份文件"
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"generalinfo": "一般錢包信息",
|
"generalinfo": "一般錢包信息",
|
||||||
@ -192,8 +192,8 @@
|
|||||||
"protocol": "協議",
|
"protocol": "協議",
|
||||||
"domain": "域名",
|
"domain": "域名",
|
||||||
"port": "端口",
|
"port": "端口",
|
||||||
"import": "導入節點",
|
"import": "導入已儲存的節點",
|
||||||
"export": "導出節點",
|
"export": "導出已儲存的節點",
|
||||||
"deletecustomnode": "刪除所有自定義節點",
|
"deletecustomnode": "刪除所有自定義節點",
|
||||||
"warning": "您現有的節點將被刪除並從備份中創建新的。",
|
"warning": "您現有的節點將被刪除並從備份中創建新的。",
|
||||||
"snack1": "成功刪除和添加標準節點",
|
"snack1": "成功刪除和添加標準節點",
|
||||||
@ -203,17 +203,17 @@
|
|||||||
"snack5": "節點成功導入",
|
"snack5": "節點成功導入",
|
||||||
"snack6": "成功刪除自訂節點",
|
"snack6": "成功刪除自訂節點",
|
||||||
"snack7": "自訂節點編輯成功",
|
"snack7": "自訂節點編輯成功",
|
||||||
"exp1": "導出主密鑰",
|
"exp1": "匯出主私鑰 (xpriv)",
|
||||||
"exp2": "導出主密鑰",
|
"exp2": "導出主密鑰",
|
||||||
"exp3": "導出",
|
"exp3": "導出",
|
||||||
"exp4": "請選擇一個錢包來備份私鑰。",
|
"exp4": "請選擇一個錢包來備份私鑰。",
|
||||||
"core": "開始核心設置",
|
"core": "Qortal Core 自動啟動設定",
|
||||||
"qappNotification1": "Q-App 通知",
|
"qappNotification1": "Q-App 通知",
|
||||||
"selectnode": "請選擇一個選項",
|
"selectnode": "請選擇一個選項",
|
||||||
"arrr1": "ARRR 錢包未初始化!",
|
"arrr1": "ARRR 錢包未初始化!",
|
||||||
"arrr2": "請先進入錢包標籤並初始化您的arrr錢包。",
|
"arrr2": "請先進入錢包並訪問 ARRR 錢包來初始化錢包",
|
||||||
"arrr3": "需要核心更新!",
|
"arrr3": "需要核心更新!",
|
||||||
"arrr4": "要儲存你的 arr 錢包的私鑰,你需要先進行核心更新!",
|
"arrr4": "要保存 ARRR 錢包的私鑰,您必須先更新 Qortal Core!",
|
||||||
"sync_indicator": "停用同步指示器彈出視窗"
|
"sync_indicator": "停用同步指示器彈出視窗"
|
||||||
},
|
},
|
||||||
"appinfo": {
|
"appinfo": {
|
||||||
@ -248,7 +248,9 @@
|
|||||||
"balance": "餘額",
|
"balance": "餘額",
|
||||||
"balances": "您的錢包餘額",
|
"balances": "您的錢包餘額",
|
||||||
"update": "更新錢包餘額",
|
"update": "更新錢包餘額",
|
||||||
"view": "看法"
|
"view": "看法",
|
||||||
|
"all": "全部",
|
||||||
|
"page": "頁"
|
||||||
},
|
},
|
||||||
"gifs": {
|
"gifs": {
|
||||||
"gchange1": "Gif 瀏覽器",
|
"gchange1": "Gif 瀏覽器",
|
||||||
@ -283,8 +285,8 @@
|
|||||||
},
|
},
|
||||||
"startminting": {
|
"startminting": {
|
||||||
"smchange1": "無法獲取鑄幣帳戶",
|
"smchange1": "無法獲取鑄幣帳戶",
|
||||||
"smchange2": "無法移除密鑰",
|
"smchange2": "無法刪除鑄造金鑰",
|
||||||
"smchange3": "添加鑄幣密鑰失敗",
|
"smchange3": "無法添加鑄造密鑰,如果剛剛創建密鑰,請嘗試等待幾個塊並再次添加",
|
||||||
"smchange4": "無法創建贊助密鑰",
|
"smchange4": "無法創建贊助密鑰",
|
||||||
"smchange5": "建立關係",
|
"smchange5": "建立關係",
|
||||||
"smchange6": "等待區塊鏈確認",
|
"smchange6": "等待區塊鏈確認",
|
||||||
@ -507,7 +509,7 @@
|
|||||||
"nchange23": "賣出價",
|
"nchange23": "賣出價",
|
||||||
"nchange24": "沒有名字可以賣",
|
"nchange24": "沒有名字可以賣",
|
||||||
"nchange25": "出售名稱",
|
"nchange25": "出售名稱",
|
||||||
"nchange26": "你確定要賣這個名字嗎?",
|
"nchange26": "您確定要出售這個名字嗎? 如果名稱被其他帳戶購買,則將不受您的控制!",
|
||||||
"nchange27": "對於 QORT 中的這個價格",
|
"nchange27": "對於 QORT 中的這個價格",
|
||||||
"nchange28": "按下確認後,將發送銷售名稱請求!",
|
"nchange28": "按下確認後,將發送銷售名稱請求!",
|
||||||
"nchange29": "要取消的名稱",
|
"nchange29": "要取消的名稱",
|
||||||
@ -945,7 +947,16 @@
|
|||||||
"gchange56": "要搜索的群組名稱",
|
"gchange56": "要搜索的群組名稱",
|
||||||
"gchange57": "未找到私人群組名稱",
|
"gchange57": "未找到私人群組名稱",
|
||||||
"gchange58": "注意群組名稱必須完全匹配。",
|
"gchange58": "注意群組名稱必須完全匹配。",
|
||||||
"gchange59": "顯示/隱藏代碼"
|
"gchange59": "顯示/隱藏代碼",
|
||||||
|
"gchange60": "請輸入組名",
|
||||||
|
"gchange61": "請輸入描述",
|
||||||
|
"gchange62": "你確定要更新這個組嗎?",
|
||||||
|
"gchange63": "按 CONFIRM 後,將發送UPDATE_GROUP請求!",
|
||||||
|
"gchange64": "當前擁有者/新擁有者",
|
||||||
|
"gchange65": "將此位址替換為組的 TRANSFER OWNERSHIP!",
|
||||||
|
"gchange66": "無效的擁有者/新擁有者位址",
|
||||||
|
"gchange67": "組更新成功!",
|
||||||
|
"gchange68": "設置組頭像"
|
||||||
},
|
},
|
||||||
"puzzlepage": {
|
"puzzlepage": {
|
||||||
"pchange1": "益智游戲",
|
"pchange1": "益智游戲",
|
||||||
|
@ -1,139 +1,121 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html lang="en-us">
|
<html lang="en-us">
|
||||||
|
<head>
|
||||||
<head>
|
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
||||||
<meta name="viewport" content="width=device-width, initial-scale=1, viewport-fit=cover">
|
<meta charset="UTF-8">
|
||||||
<meta charset="UTF-8">
|
<meta name="Description" content="Qortal Platform UI">
|
||||||
<meta name="Description" content="Qortal Platform UI">
|
<link rel="apple-touch-icon" sizes="57x57" href="/img/favicon/apple-icon-57x57.png">
|
||||||
|
<link rel="apple-touch-icon" sizes="60x60" href="/img/favicon/apple-icon-60x60.png">
|
||||||
<link rel="apple-touch-icon" sizes="57x57" href="/img/favicon/apple-icon-57x57.png">
|
<link rel="apple-touch-icon" sizes="72x72" href="/img/favicon/apple-icon-72x72.png">
|
||||||
<link rel="apple-touch-icon" sizes="60x60" href="/img/favicon/apple-icon-60x60.png">
|
<link rel="apple-touch-icon" sizes="76x76" href="/img/favicon/apple-icon-76x76.png">
|
||||||
<link rel="apple-touch-icon" sizes="72x72" href="/img/favicon/apple-icon-72x72.png">
|
<link rel="apple-touch-icon" sizes="114x114" href="/img/favicon/apple-icon-114x114.png">
|
||||||
<link rel="apple-touch-icon" sizes="76x76" href="/img/favicon/apple-icon-76x76.png">
|
<link rel="apple-touch-icon" sizes="120x120" href="/img/favicon/apple-icon-120x120.png">
|
||||||
<link rel="apple-touch-icon" sizes="114x114" href="/img/favicon/apple-icon-114x114.png">
|
<link rel="apple-touch-icon" sizes="144x144" href="/img/favicon/apple-icon-144x144.png">
|
||||||
<link rel="apple-touch-icon" sizes="120x120" href="/img/favicon/apple-icon-120x120.png">
|
<link rel="apple-touch-icon" sizes="152x152" href="/img/favicon/apple-icon-152x152.png">
|
||||||
<link rel="apple-touch-icon" sizes="144x144" href="/img/favicon/apple-icon-144x144.png">
|
<link rel="apple-touch-icon" sizes="180x180" href="/img/favicon/apple-icon-180x180.png">
|
||||||
<link rel="apple-touch-icon" sizes="152x152" href="/img/favicon/apple-icon-152x152.png">
|
<link rel="icon" type="image/png" sizes="192x192" href="/img/favicon/android-icon-192x192.png">
|
||||||
<link rel="apple-touch-icon" sizes="180x180" href="/img/favicon/apple-icon-180x180.png">
|
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon/favicon-32x32.png">
|
||||||
<link rel="icon" type="image/png" sizes="192x192" href="/img/favicon/android-icon-192x192.png">
|
<link rel="icon" type="image/png" sizes="96x96" href="/img/favicon/favicon-96x96.png">
|
||||||
<link rel="icon" type="image/png" sizes="32x32" href="/img/favicon/favicon-32x32.png">
|
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon/favicon-16x16.png">
|
||||||
<link rel="icon" type="image/png" sizes="96x96" href="/img/favicon/favicon-96x96.png">
|
<link rel="manifest" href="/img/favicon/manifest.json">
|
||||||
<link rel="icon" type="image/png" sizes="16x16" href="/img/favicon/favicon-16x16.png">
|
<meta name="msapplication-TileColor" content="var(--white)">
|
||||||
<link rel="manifest" href="/img/favicon/manifest.json">
|
<meta name="msapplication-TileImage" content="/img/favicon/ms-icon-144x144.png">
|
||||||
|
<meta name="theme-color" content="var(--white)">
|
||||||
<meta name="msapplication-TileColor" content="var(--white)">
|
<style>
|
||||||
<meta name="msapplication-TileImage" content="/img/favicon/ms-icon-144x144.png">
|
html {
|
||||||
<meta name="theme-color" content="var(--white)">
|
--scrollbarBG: #a1a1a1;
|
||||||
|
--thumbBG: #6a6c75;
|
||||||
<style>
|
overflow: hidden;
|
||||||
html {
|
}
|
||||||
--scrollbarBG: #a1a1a1;
|
*::-webkit-scrollbar {
|
||||||
--thumbBG: #6a6c75;
|
width: 11px;
|
||||||
overflow: hidden;
|
}
|
||||||
}
|
* {
|
||||||
|
scrollbar-width: thin;
|
||||||
*::-webkit-scrollbar {
|
scrollbar-color: var(--thumbBG) var(--scrollbarBG);
|
||||||
width: 11px;
|
}
|
||||||
}
|
*::-webkit-scrollbar-track {
|
||||||
|
background: var(--scrollbarBG);
|
||||||
* {
|
}
|
||||||
scrollbar-width: thin;
|
*::-webkit-scrollbar-thumb {
|
||||||
scrollbar-color: var(--thumbBG) var(--scrollbarBG);
|
background-color: var(--thumbBG);
|
||||||
}
|
border-radius: 6px;
|
||||||
|
border: 3px solid var(--scrollbarBG);
|
||||||
*::-webkit-scrollbar-track {
|
}
|
||||||
background: var(--scrollbarBG);
|
html,
|
||||||
}
|
body {
|
||||||
|
margin: 0;
|
||||||
*::-webkit-scrollbar-thumb {
|
padding: 0;
|
||||||
background-color: var(--thumbBG);
|
background: var(--plugback);
|
||||||
border-radius: 6px;
|
overflow: hidden;
|
||||||
border: 3px solid var(--scrollbarBG);
|
}
|
||||||
}
|
</style>
|
||||||
|
<link rel="stylesheet" href="/build/styles.bundle.css">
|
||||||
html,
|
<link rel="stylesheet" href="/font/material-icons.css">
|
||||||
body {
|
<link rel="stylesheet" href="/font/switch-theme.css">
|
||||||
margin: 0;
|
<title>Qortal UI</title>
|
||||||
padding: 0;
|
<script>
|
||||||
background: var(--plugback);
|
const checkTheme = localStorage.getItem('qortalTheme')
|
||||||
overflow: hidden;
|
if (checkTheme === 'dark') {
|
||||||
}
|
newtheme = 'dark';
|
||||||
</style>
|
} else {
|
||||||
<link rel="stylesheet" href="/build/styles.bundle.css">
|
newtheme = 'light';
|
||||||
<link rel="stylesheet" href="/font/material-icons.css">
|
}
|
||||||
<link rel="stylesheet" href="/font/switch-theme.css">
|
document.querySelector('html').setAttribute('theme', newtheme);
|
||||||
<title>Qortal UI</title>
|
|
||||||
|
const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 });
|
||||||
|
const heap = new Uint8Array(memory.buffer);
|
||||||
<script>
|
|
||||||
const checkTheme = localStorage.getItem('qortalTheme')
|
const sbrk = function (size, heap) {
|
||||||
if (checkTheme === 'dark') {
|
let brk = 512 * 1024; // stack top
|
||||||
newtheme = 'dark';
|
let old = brk;
|
||||||
} else {
|
brk += size;
|
||||||
newtheme = 'light';
|
|
||||||
}
|
if (brk > heap.length)
|
||||||
document.querySelector('html').setAttribute('theme', newtheme);
|
throw new Error("heap exhausted");
|
||||||
|
|
||||||
const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 });
|
return old;
|
||||||
const heap = new Uint8Array(memory.buffer);
|
};
|
||||||
|
|
||||||
const sbrk = function (size, heap) {
|
const importObject = {
|
||||||
let brk = 512 * 1024; // stack top
|
env: {
|
||||||
let old = brk;
|
memory: memory
|
||||||
brk += size;
|
},
|
||||||
|
};
|
||||||
if (brk > heap.length)
|
|
||||||
throw new Error("heap exhausted");
|
function loadWebAssembly(filename, imports) {
|
||||||
|
// Fetch the file and compile it
|
||||||
return old;
|
return fetch(filename)
|
||||||
};
|
.then(response => response.arrayBuffer())
|
||||||
|
.then(buffer => WebAssembly.compile(buffer))
|
||||||
const importObject = {
|
.then(module => {
|
||||||
env: {
|
|
||||||
memory: memory
|
// Create the instance.
|
||||||
},
|
return new WebAssembly.Instance(module, importObject);
|
||||||
};
|
});
|
||||||
|
}
|
||||||
function loadWebAssembly(filename, imports) {
|
|
||||||
// Fetch the file and compile it
|
const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full'
|
||||||
return fetch(filename)
|
|
||||||
.then(response => response.arrayBuffer())
|
loadWebAssembly(path)
|
||||||
.then(buffer => WebAssembly.compile(buffer))
|
.then(wasmModule => {
|
||||||
.then(module => {
|
window.sbrk = sbrk
|
||||||
|
window.memory = memory
|
||||||
// Create the instance.
|
window.heap = heap
|
||||||
return new WebAssembly.Instance(module, importObject);
|
window.powInstance = wasmModule.instance;
|
||||||
});
|
window.computePow = wasmModule.exports.compute2;
|
||||||
}
|
});
|
||||||
|
|
||||||
const path = window.parent.location.origin + '/memory-pow/memory-pow.wasm.full'
|
</script>
|
||||||
|
</head>
|
||||||
loadWebAssembly(path)
|
<body>
|
||||||
.then(wasmModule => {
|
<app-styles></app-styles>
|
||||||
window.sbrk = sbrk
|
<main>
|
||||||
window.memory = memory
|
<noscript>
|
||||||
window.heap = heap
|
You need to enable JavaScript to run this app. 😞
|
||||||
window.powInstance = wasmModule.instance;
|
</noscript>
|
||||||
window.computePow = wasmModule.exports.compute2;
|
<main-app id="main-app"></main-app>
|
||||||
});
|
</main>
|
||||||
|
<script type="module" src="/build/es6/main.js"></script>
|
||||||
</script>
|
</body>
|
||||||
</head>
|
|
||||||
|
|
||||||
<body>
|
|
||||||
<app-styles></app-styles>
|
|
||||||
<main>
|
|
||||||
|
|
||||||
<noscript>
|
|
||||||
You need to enable JavaScript to run this app. 😞
|
|
||||||
</noscript>
|
|
||||||
|
|
||||||
<main-app id="main-app"></main-app>
|
|
||||||
|
|
||||||
</main>
|
|
||||||
|
|
||||||
<script type="module" src="/build/es6/main.js"></script>
|
|
||||||
|
|
||||||
</body>
|
|
||||||
|
|
||||||
</html>
|
</html>
|
||||||
|
@ -3,32 +3,33 @@ const Hapi = require('@hapi/hapi')
|
|||||||
const Inert = require('@hapi/inert')
|
const Inert = require('@hapi/inert')
|
||||||
|
|
||||||
function serverFactory(routes, address, port, tls) {
|
function serverFactory(routes, address, port, tls) {
|
||||||
this.server = new Hapi.Server({
|
this.server = new Hapi.Server({
|
||||||
routes: {
|
routes: {
|
||||||
files: {
|
files: {
|
||||||
relativeTo: Path.join(__dirname, '../')
|
relativeTo: Path.join(__dirname, '../')
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
address: address,
|
address: address,
|
||||||
port: port,
|
port: port,
|
||||||
tls: tls
|
tls: tls
|
||||||
})
|
})
|
||||||
|
|
||||||
this.startServer = async () => {
|
this.startServer = async () => {
|
||||||
try {
|
try {
|
||||||
await this.server.register([Inert])
|
await this.server.register([Inert])
|
||||||
|
|
||||||
this.server.route(routes)
|
this.server.route(routes)
|
||||||
|
|
||||||
await this.server.start()
|
await this.server.start()
|
||||||
|
|
||||||
delete this.startServer
|
delete this.startServer
|
||||||
return this.server
|
|
||||||
} catch (e) {
|
return this.server
|
||||||
console.error(e)
|
} catch (e) {
|
||||||
throw e
|
console.error(e)
|
||||||
}
|
throw e
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = serverFactory
|
module.exports = serverFactory
|
@ -1,106 +1,106 @@
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
||||||
const routesOptions = {
|
const routesOptions = {
|
||||||
security: {
|
security: {
|
||||||
hsts: {
|
hsts: {
|
||||||
maxAge: 15768000,
|
maxAge: 15768000,
|
||||||
includeSubDomains: true,
|
includeSubDomains: true,
|
||||||
preload: true
|
preload: true
|
||||||
},
|
},
|
||||||
xframe: 'sameorigin'
|
xframe: 'sameorigin'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const createRoutes = config => [
|
const createRoutes = config => [
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
path: '/img/{param*}',
|
||||||
|
handler: {
|
||||||
|
directory: {
|
||||||
|
path: config.build.options.imgDir,
|
||||||
|
redirectToSlash: true,
|
||||||
|
index: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: routesOptions
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
path: '/language/{param*}',
|
||||||
|
handler: {
|
||||||
|
directory: {
|
||||||
|
path: path.join(__dirname, '../../language'),
|
||||||
|
redirectToSlash: true,
|
||||||
|
index: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: routesOptions
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
path: '/font/{param*}',
|
||||||
|
handler: {
|
||||||
|
directory: {
|
||||||
|
path: path.join(__dirname, '../../font'),
|
||||||
|
redirectToSlash: true,
|
||||||
|
index: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: routesOptions
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
path: '/sound/{param*}',
|
||||||
|
handler: {
|
||||||
|
directory: {
|
||||||
|
path: path.join(__dirname, '../../sound/'),
|
||||||
|
redirectToSlash: true,
|
||||||
|
index: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: routesOptions
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
path: '/emoji/{param*}',
|
||||||
|
handler: {
|
||||||
|
directory: {
|
||||||
|
path: path.join(__dirname, '../../emoji/'),
|
||||||
|
redirectToSlash: true,
|
||||||
|
index: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: routesOptions
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
path: '/memory-pow/{param*}',
|
||||||
|
handler: {
|
||||||
|
directory: {
|
||||||
|
path: path.join(__dirname, '../../memory-pow/'),
|
||||||
|
redirectToSlash: true,
|
||||||
|
index: true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
options: routesOptions
|
||||||
|
},
|
||||||
|
{
|
||||||
|
method: 'GET',
|
||||||
|
path: '/getConfig',
|
||||||
|
handler: (request, h) => {
|
||||||
|
const response = {
|
||||||
|
config: {
|
||||||
|
...config
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
{
|
delete response.config.user.tls
|
||||||
method: 'GET',
|
delete response.config.build
|
||||||
path: '/img/{param*}',
|
|
||||||
handler: {
|
|
||||||
directory: {
|
|
||||||
path: config.build.options.imgDir,
|
|
||||||
redirectToSlash: true,
|
|
||||||
index: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
options: routesOptions
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: 'GET',
|
|
||||||
path: '/language/{param*}',
|
|
||||||
handler: {
|
|
||||||
directory: {
|
|
||||||
path: path.join(__dirname, '../../language'),
|
|
||||||
redirectToSlash: true,
|
|
||||||
index: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
options: routesOptions
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: 'GET',
|
|
||||||
path: '/font/{param*}',
|
|
||||||
handler: {
|
|
||||||
directory: {
|
|
||||||
path: path.join(__dirname, '../../font'),
|
|
||||||
redirectToSlash: true,
|
|
||||||
index: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
options: routesOptions
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: 'GET',
|
|
||||||
path: '/sound/{param*}',
|
|
||||||
handler: {
|
|
||||||
directory: {
|
|
||||||
path: path.join(__dirname, '../../sound/'),
|
|
||||||
redirectToSlash: true,
|
|
||||||
index: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
options: routesOptions
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: 'GET',
|
|
||||||
path: '/emoji/{param*}',
|
|
||||||
handler: {
|
|
||||||
directory: {
|
|
||||||
path: path.join(__dirname, '../../emoji/'),
|
|
||||||
redirectToSlash: true,
|
|
||||||
index: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
options: routesOptions
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: 'GET',
|
|
||||||
path: '/memory-pow/{param*}',
|
|
||||||
handler: {
|
|
||||||
directory: {
|
|
||||||
path: path.join(__dirname, '../../memory-pow/'),
|
|
||||||
redirectToSlash: true,
|
|
||||||
index: true
|
|
||||||
}
|
|
||||||
},
|
|
||||||
options: routesOptions
|
|
||||||
},
|
|
||||||
{
|
|
||||||
method: 'GET',
|
|
||||||
path: '/getConfig',
|
|
||||||
handler: (request, h) => {
|
|
||||||
const response = {
|
|
||||||
config: {
|
|
||||||
...config
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
delete response.config.user.tls
|
return JSON.stringify(response)
|
||||||
delete response.config.build
|
},
|
||||||
return JSON.stringify(response)
|
options: routesOptions
|
||||||
},
|
}
|
||||||
options: routesOptions
|
|
||||||
}
|
|
||||||
]
|
]
|
||||||
|
|
||||||
module.exports = createRoutes
|
module.exports = createRoutes
|
@ -1,141 +1,140 @@
|
|||||||
const path = require('path')
|
const path = require('path')
|
||||||
|
|
||||||
const createCommonRoutes = require('./createCommonRoutes.js')
|
const createCommonRoutes = require('./createCommonRoutes.js')
|
||||||
|
|
||||||
const createPrimaryRoutes = (config, plugins) => {
|
const createPrimaryRoutes = (config, plugins) => {
|
||||||
const routes = createCommonRoutes(config)
|
const routes = createCommonRoutes(config)
|
||||||
|
|
||||||
let myPlugins = plugins
|
let myPlugins = plugins
|
||||||
|
|
||||||
const pluginFolders = {}
|
const pluginFolders = {}
|
||||||
|
|
||||||
const routesOptions = {
|
const routesOptions = {
|
||||||
security: {
|
security: {
|
||||||
hsts: {
|
hsts: {
|
||||||
maxAge: 15768000,
|
maxAge: 15768000,
|
||||||
includeSubDomains: true,
|
includeSubDomains: true,
|
||||||
preload: true
|
preload: true
|
||||||
},
|
},
|
||||||
xframe: 'sameorigin'
|
xframe: 'sameorigin'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins.reduce((obj, plugin) => {
|
plugins.reduce((obj, plugin) => {
|
||||||
obj[plugin.name] = plugin.folder
|
obj[plugin.name] = plugin.folder
|
||||||
return obj
|
return obj
|
||||||
}, pluginFolders)
|
}, pluginFolders)
|
||||||
|
|
||||||
|
|
||||||
routes.push(
|
routes.push(
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: '/',
|
path: '/',
|
||||||
handler: (request, reply) => {
|
handler: (request, reply) => {
|
||||||
return reply.redirect('/app')
|
return reply.redirect('/app')
|
||||||
},
|
},
|
||||||
options: routesOptions
|
options: routesOptions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: '/{path*}',
|
path: '/{path*}',
|
||||||
handler: (request, h) => {
|
handler: (request, h) => {
|
||||||
const filePath = path.join(__dirname, '../../public/index.html')
|
const filePath = path.join(__dirname, '../../public/index.html')
|
||||||
const response = h.file(filePath, {
|
const response = h.file(filePath, {
|
||||||
confine: true
|
confine: true
|
||||||
})
|
})
|
||||||
response.header('Access-Control-Allow-Origin', request.info.host)
|
response.header('Access-Control-Allow-Origin', request.info.host)
|
||||||
return response
|
return response
|
||||||
},
|
},
|
||||||
options: routesOptions
|
options: routesOptions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: '/getPlugins',
|
path: '/getPlugins',
|
||||||
handler: (request, h) => {
|
handler: (request, h) => {
|
||||||
return { plugins: myPlugins.map(p => p.name) }
|
return { plugins: myPlugins.map(p => p.name) }
|
||||||
},
|
},
|
||||||
options: routesOptions
|
options: routesOptions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: '/build/{param*}',
|
path: '/build/{param*}',
|
||||||
handler: {
|
handler: {
|
||||||
directory: {
|
directory: {
|
||||||
path: config.build.options.outputDir,
|
path: config.build.options.outputDir,
|
||||||
redirectToSlash: true,
|
redirectToSlash: true,
|
||||||
index: true
|
index: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
options: routesOptions
|
options: routesOptions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: '/src/{param*}',
|
path: '/src/{param*}',
|
||||||
handler: {
|
handler: {
|
||||||
directory: {
|
directory: {
|
||||||
path: path.join(__dirname, '../../src'),
|
path: path.join(__dirname, '../../src'),
|
||||||
redirectToSlash: true,
|
redirectToSlash: true,
|
||||||
index: true
|
index: true
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
options: routesOptions
|
options: routesOptions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: '/plugin/{path*}',
|
path: '/plugin/{path*}',
|
||||||
handler: (request, h) => {
|
handler: (request, h) => {
|
||||||
|
|
||||||
const plugin = request.params.path.split('/')[0]
|
const plugin = request.params.path.split('/')[0]
|
||||||
const filePath = path.join(pluginFolders[plugin], '../', request.params.path)
|
const filePath = path.join(pluginFolders[plugin], '../', request.params.path)
|
||||||
|
|
||||||
const response = h.file(filePath, {
|
const response = h.file(filePath, {
|
||||||
confine: false
|
confine: false
|
||||||
})
|
})
|
||||||
response.header('Access-Control-Allow-Origin', request.info.host)
|
response.header('Access-Control-Allow-Origin', request.info.host)
|
||||||
return response
|
return response
|
||||||
},
|
},
|
||||||
options: routesOptions
|
options: routesOptions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: '/plugin/404',
|
path: '/plugin/404',
|
||||||
handler: (request, h) => {
|
handler: (request, h) => {
|
||||||
const response = h.file(path.join(config.server.primary.page404))
|
const response = h.file(path.join(config.server.primary.page404))
|
||||||
response.header('Access-Control-Allow-Origin', request.info.host)
|
response.header('Access-Control-Allow-Origin', request.info.host)
|
||||||
return response
|
return response
|
||||||
},
|
},
|
||||||
options: routesOptions
|
options: routesOptions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: '/qortal-components/plugin-mainjs-loader.html',
|
path: '/qortal-components/plugin-mainjs-loader.html',
|
||||||
handler: (request, h) => {
|
handler: (request, h) => {
|
||||||
const response = h.file(path.join(__dirname, '../../src/plugins/plugin-mainjs-loader.html'), {
|
const response = h.file(path.join(__dirname, '../../src/plugins/plugin-mainjs-loader.html'), {
|
||||||
confine: false
|
confine: false
|
||||||
})
|
})
|
||||||
response.header('Access-Control-Allow-Origin', request.info.host)
|
response.header('Access-Control-Allow-Origin', request.info.host)
|
||||||
return response
|
return response
|
||||||
},
|
},
|
||||||
options: routesOptions
|
options: routesOptions
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
method: 'GET',
|
method: 'GET',
|
||||||
path: '/qortal-components/plugin-mainjs-loader.js',
|
path: '/qortal-components/plugin-mainjs-loader.js',
|
||||||
handler: (request, h) => {
|
handler: (request, h) => {
|
||||||
const file = path.join(config.build.options.outputDir, '/plugins/plugin-mainjs-loader.js')
|
const file = path.join(config.build.options.outputDir, '/plugins/plugin-mainjs-loader.js')
|
||||||
|
|
||||||
const response = h.file(file, {
|
const response = h.file(file, {
|
||||||
confine: false
|
confine: false
|
||||||
})
|
})
|
||||||
response.header('Access-Control-Allow-Origin', request.info.host)
|
response.header('Access-Control-Allow-Origin', request.info.host)
|
||||||
return response
|
return response
|
||||||
},
|
},
|
||||||
options: routesOptions
|
options: routesOptions
|
||||||
},
|
}
|
||||||
|
|
||||||
)
|
)
|
||||||
|
|
||||||
return routes
|
return routes
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = createPrimaryRoutes
|
module.exports = createPrimaryRoutes
|
@ -3,22 +3,20 @@ const ServerFactory = require('./ServerFactory.js')
|
|||||||
const createPrimaryRoutes = require('./routes/createPrimaryRoutes.js')
|
const createPrimaryRoutes = require('./routes/createPrimaryRoutes.js')
|
||||||
|
|
||||||
const createServer = (config, plugins) => {
|
const createServer = (config, plugins) => {
|
||||||
this.start = async function () {
|
this.start = async function () {
|
||||||
const primaryServer = new ServerFactory(createPrimaryRoutes(config, plugins), config.user.server.primary.host, config.user.server.primary.port, config.user.tls.enabled ? config.user.tls.options : void 0)
|
const primaryServer = new ServerFactory(createPrimaryRoutes(config, plugins), config.user.server.primary.host, config.user.server.primary.port, config.user.tls.enabled ? config.user.tls.options : void 0)
|
||||||
primaryServer.startServer()
|
primaryServer.startServer().then(server => {
|
||||||
.then(server => {
|
console.log(`Qortal UI Server started at ${server.info.uri} and listening on ${server.info.address}`)
|
||||||
console.log(`Qortal UI Server started at ${server.info.uri} and listening on ${server.info.address}`)
|
}).catch(e => {
|
||||||
})
|
console.error(e)
|
||||||
.catch(e => {
|
})
|
||||||
console.error(e)
|
}
|
||||||
})
|
|
||||||
}
|
|
||||||
return this
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return this
|
||||||
|
}
|
||||||
|
|
||||||
const serverExports = {
|
const serverExports = {
|
||||||
createServer
|
createServer
|
||||||
}
|
}
|
||||||
|
|
||||||
module.exports = serverExports
|
module.exports = serverExports
|
@ -1,54 +1,55 @@
|
|||||||
import * as api from 'qortal-ui-crypto'
|
import * as api from 'qortal-ui-crypto'
|
||||||
import mykey from './functional-components/mykey-page.js'
|
import mykey from './functional-components/mykey-page'
|
||||||
|
|
||||||
'use strict'
|
|
||||||
|
|
||||||
export const checkApiKey = async (nodeConfig) => {
|
export const checkApiKey = async (nodeConfig) => {
|
||||||
|
let selectedNode = nodeConfig.knownNodes[nodeConfig.node]
|
||||||
|
let apiKey = selectedNode.apiKey
|
||||||
|
|
||||||
let selectedNode = nodeConfig.knownNodes[nodeConfig.node];
|
// Attempt to generate an API key
|
||||||
let apiKey = selectedNode.apiKey;
|
const generateUrl = '/admin/apikey/generate'
|
||||||
|
|
||||||
// Attempt to generate an API key
|
let generateRes = await api.request(generateUrl, {
|
||||||
const generateUrl = "/admin/apikey/generate";
|
method: 'POST'
|
||||||
let generateRes = await api.request(generateUrl, {
|
})
|
||||||
method: "POST"
|
|
||||||
});
|
|
||||||
|
|
||||||
if (generateRes != null && generateRes.error == null && generateRes.length >= 8) {
|
if (generateRes != null && generateRes.error == null && generateRes.length >= 8) {
|
||||||
console.log("Generated API key");
|
console.log('Generated API key')
|
||||||
apiKey = generateRes;
|
|
||||||
|
|
||||||
// Store the generated API key
|
apiKey = generateRes
|
||||||
selectedNode.apiKey = apiKey;
|
|
||||||
nodeConfig.knownNodes[nodeConfig.node] = selectedNode;
|
|
||||||
localStorage.setItem('myQortalNodes', JSON.stringify(nodeConfig.knownNodes));
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
console.log("Unable to generate API key");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Now test the API key
|
// Store the generated API key
|
||||||
let testResult = await testApiKey(apiKey);
|
selectedNode.apiKey = apiKey
|
||||||
if (testResult === true) {
|
nodeConfig.knownNodes[nodeConfig.node] = selectedNode
|
||||||
console.log("API key test passed");
|
localStorage.setItem('myQortalNodes', JSON.stringify(nodeConfig.knownNodes))
|
||||||
}
|
} else {
|
||||||
else {
|
console.log("Unable to generate API key")
|
||||||
console.log("API key test failed");
|
}
|
||||||
mykey.show();
|
|
||||||
this.dispatchEvent(
|
// Now test the API key
|
||||||
|
let testResult = await testApiKey(apiKey)
|
||||||
|
|
||||||
|
if (testResult === true) {
|
||||||
|
console.log('API key test passed')
|
||||||
|
} else {
|
||||||
|
console.log('API key test failed')
|
||||||
|
|
||||||
|
mykey.show()
|
||||||
|
|
||||||
|
this.dispatchEvent(
|
||||||
new CustomEvent('disable-tour', {
|
new CustomEvent('disable-tour', {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
composed: true
|
composed: true
|
||||||
}),
|
})
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export const testApiKey = async (apiKey) => {
|
export const testApiKey = async (apiKey) => {
|
||||||
const testUrl = "/admin/apikey/test?apiKey=" + apiKey;
|
const testUrl = '/admin/apikey/test?apiKey=' + apiKey
|
||||||
let testRes = await api.request(testUrl, {
|
|
||||||
method: "GET"
|
|
||||||
});
|
|
||||||
return testRes === true;
|
|
||||||
|
|
||||||
}
|
let testRes = await api.request(testUrl, {
|
||||||
|
method: 'GET'
|
||||||
|
})
|
||||||
|
|
||||||
|
return testRes === true
|
||||||
|
}
|
@ -1,5 +1,3 @@
|
|||||||
import WebWorker from 'web-worker:./computePowWorkerFile.js';
|
import WebWorker from 'web-worker:./computePowWorkerFile.js'
|
||||||
|
|
||||||
// You can add any initialization or configuration for the Web Worker here
|
export default WebWorker
|
||||||
|
|
||||||
export default WebWorker;
|
|
@ -1,147 +1,107 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers'
|
import { connect } from 'pwa-helpers'
|
||||||
import {store} from '../store.js'
|
import { store } from '../store'
|
||||||
import {translate} from '../../translate'
|
import { appInfoStyles } from '../styles/core-css'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { translate } from '../../translate'
|
||||||
|
|
||||||
class AppInfo extends connect(store)(LitElement) {
|
class AppInfo extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
nodeInfo: { type: Array },
|
nodeInfo: { type: Array },
|
||||||
coreInfo: { type: Array },
|
coreInfo: { type: Array },
|
||||||
nodeConfig: { type: Object },
|
nodeConfig: { type: Object },
|
||||||
theme: { type: String, reflect: true }
|
theme: { type: String, reflect: true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return css`
|
return [appInfoStyles]
|
||||||
* {
|
}
|
||||||
--mdc-theme-primary: rgb(3, 169, 244);
|
|
||||||
--paper-input-container-focus-color: var(--mdc-theme-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.normal {
|
constructor() {
|
||||||
--mdc-theme-primary: rgb(3, 169, 244);
|
super()
|
||||||
}
|
this.nodeInfo = []
|
||||||
|
this.coreInfo = []
|
||||||
|
this.nodeConfig = {}
|
||||||
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
|
}
|
||||||
|
|
||||||
#profileInMenu {
|
render() {
|
||||||
flex: 0 0 100px;
|
return html`
|
||||||
padding:12px;
|
<div id="profileInMenu">
|
||||||
border-top: 1px solid var(--border);
|
<span class="info">${translate("appinfo.uiversion")}: ${this.nodeConfig.version ? this.nodeConfig.version : ''}</span>
|
||||||
background: var(--sidetopbar);
|
${this._renderCoreVersion()}
|
||||||
}
|
<span class="info">${translate("appinfo.blockheight")}: ${this.nodeInfo.height ? this.nodeInfo.height : ''} <span class=${this.cssStatus}>${this._renderStatus()}</span></span>
|
||||||
|
<span class="info">${translate("appinfo.peers")}: ${this.nodeInfo.numberOfConnections ? this.nodeInfo.numberOfConnections : ''}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
.info {
|
firstUpdated() {
|
||||||
margin: 0;
|
this.getNodeInfo()
|
||||||
font-size: 14px;
|
this.getCoreInfo()
|
||||||
font-weight: 100;
|
|
||||||
display: inline-block;
|
|
||||||
width: 100%;
|
|
||||||
padding-bottom: 8px;
|
|
||||||
color: var(--black);
|
|
||||||
}
|
|
||||||
|
|
||||||
.blue {
|
setInterval(() => {
|
||||||
color: #03a9f4;
|
this.getNodeInfo()
|
||||||
margin: 0;
|
this.getCoreInfo()
|
||||||
font-size: 14px;
|
}, 60000)
|
||||||
font-weight: 200;
|
}
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
|
|
||||||
.black {
|
async getNodeInfo() {
|
||||||
color: var(--black);
|
const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
margin: 0;
|
const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port
|
||||||
font-size: 14px;
|
const url = `${appinfoUrl}/admin/status`
|
||||||
font-weight: 200;
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
await fetch(url).then(response => {
|
||||||
super()
|
return response.json()
|
||||||
this.nodeInfo = []
|
}).then(data => {
|
||||||
this.coreInfo = []
|
this.nodeInfo = data
|
||||||
this.nodeConfig = {}
|
}).catch(err => {
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
console.error('Request failed', err)
|
||||||
}
|
})
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
async getCoreInfo() {
|
||||||
return html`
|
const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
<div id="profileInMenu">
|
const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port
|
||||||
<span class="info">${translate("appinfo.uiversion")}: ${this.nodeConfig.version ? this.nodeConfig.version : ''}</span>
|
const url = `${appinfoUrl}/admin/info`
|
||||||
${this._renderCoreVersion()}
|
|
||||||
<span class="info">${translate("appinfo.blockheight")}: ${this.nodeInfo.height ? this.nodeInfo.height : ''} <span class=${this.cssStatus}>${this._renderStatus()}</span></span>
|
|
||||||
<span class="info">${translate("appinfo.peers")}: ${this.nodeInfo.numberOfConnections ? this.nodeInfo.numberOfConnections : ''}
|
|
||||||
<a id="pageLink"></a>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
firstUpdated() {
|
await fetch(url).then(response => {
|
||||||
this.getNodeInfo()
|
return response.json()
|
||||||
this.getCoreInfo()
|
}).then(data => {
|
||||||
|
this.coreInfo = data
|
||||||
|
}).catch(err => {
|
||||||
|
console.error('Request failed', err)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
setInterval(() => {
|
_renderStatus() {
|
||||||
this.getNodeInfo()
|
if (this.nodeInfo.isMintingPossible === true && this.nodeInfo.isSynchronizing === true) {
|
||||||
this.getCoreInfo()
|
this.cssStatus = 'blue'
|
||||||
}, 60000)
|
return html`${translate("appinfo.minting")}`
|
||||||
}
|
} else if (this.nodeInfo.isMintingPossible === true && this.nodeInfo.isSynchronizing === false) {
|
||||||
|
this.cssStatus = 'blue'
|
||||||
|
return html`${translate("appinfo.minting")}`
|
||||||
|
} else if (this.nodeInfo.isMintingPossible === false && this.nodeInfo.isSynchronizing === true) {
|
||||||
|
this.cssStatus = 'black'
|
||||||
|
return html`(${translate("appinfo.synchronizing")}... ${this.nodeInfo.syncPercent !== undefined ? this.nodeInfo.syncPercent + '%' : ''})`
|
||||||
|
} else if (this.nodeInfo.isMintingPossible === false && this.nodeInfo.isSynchronizing === false) {
|
||||||
|
this.cssStatus = 'black'
|
||||||
|
return ''
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async getNodeInfo() {
|
_renderCoreVersion() {
|
||||||
const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
return html`<span class="info">${translate("appinfo.coreversion")}: ${this.coreInfo.buildVersion ? this.coreInfo.buildVersion : ''}</span>`
|
||||||
const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port
|
}
|
||||||
const url = `${appinfoUrl}/admin/status`
|
|
||||||
|
|
||||||
await fetch(url).then(response => {
|
stateChanged(state) {
|
||||||
return response.json()
|
this.nodeConfig = state.app.nodeConfig
|
||||||
}).then(data => {
|
}
|
||||||
this.nodeInfo = data
|
|
||||||
}).catch(err => {
|
|
||||||
console.error('Request failed', err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async getCoreInfo() {
|
|
||||||
const appinfoNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
|
||||||
const appinfoUrl = appinfoNode.protocol + '://' + appinfoNode.domain + ':' + appinfoNode.port
|
|
||||||
const url = `${appinfoUrl}/admin/info`
|
|
||||||
|
|
||||||
await fetch(url).then(response => {
|
|
||||||
return response.json()
|
|
||||||
}).then(data => {
|
|
||||||
this.coreInfo = data
|
|
||||||
}).catch(err => {
|
|
||||||
console.error('Request failed', err)
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
_renderStatus() {
|
|
||||||
if (this.nodeInfo.isMintingPossible === true && this.nodeInfo.isSynchronizing === true) {
|
|
||||||
this.cssStatus = 'blue'
|
|
||||||
return html`${translate("appinfo.minting")}`
|
|
||||||
} else if (this.nodeInfo.isMintingPossible === true && this.nodeInfo.isSynchronizing === false) {
|
|
||||||
this.cssStatus = 'blue'
|
|
||||||
return html`${translate("appinfo.minting")}`
|
|
||||||
} else if (this.nodeInfo.isMintingPossible === false && this.nodeInfo.isSynchronizing === true) {
|
|
||||||
this.cssStatus = 'black'
|
|
||||||
return html`(${translate("appinfo.synchronizing")}... ${this.nodeInfo.syncPercent !== undefined ? this.nodeInfo.syncPercent + '%' : ''})`
|
|
||||||
} else if (this.nodeInfo.isMintingPossible === false && this.nodeInfo.isSynchronizing === false) {
|
|
||||||
this.cssStatus = 'black'
|
|
||||||
return ''
|
|
||||||
} else {
|
|
||||||
return ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_renderCoreVersion() {
|
|
||||||
return html`<span class="info">${translate("appinfo.coreversion")}: ${this.coreInfo.buildVersion ? this.coreInfo.buildVersion : ''}</span>`
|
|
||||||
}
|
|
||||||
|
|
||||||
stateChanged(state) {
|
|
||||||
this.nodeConfig = state.app.nodeConfig
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('app-info', AppInfo)
|
window.customElements.define('app-info', AppInfo)
|
File diff suppressed because it is too large
Load Diff
@ -1,26 +1,11 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers'
|
import { connect } from 'pwa-helpers'
|
||||||
import {store} from '../store.js'
|
import { store } from '../store'
|
||||||
|
|
||||||
class MyElement extends connect(store)(LitElement) {
|
class MyElement extends connect(store)(LitElement) {
|
||||||
static get properties () {
|
render () {
|
||||||
return {
|
return html`<style></style>`
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static get styles () {
|
|
||||||
return css``
|
|
||||||
}
|
|
||||||
|
|
||||||
render () {
|
|
||||||
return html`
|
|
||||||
<style>
|
|
||||||
</style>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
stateChanged (state) {
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('my-element', MyElement)
|
window.customElements.define('my-element', MyElement)
|
@ -1,11 +1,13 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {store} from '../../store'
|
import { connect } from 'pwa-helpers'
|
||||||
import {connect} from 'pwa-helpers'
|
import { store } from '../../store'
|
||||||
import {translate} from '../../../translate'
|
import { parentEpml } from '../show-plugin'
|
||||||
import {parentEpml} from '../show-plugin'
|
import { syncIndicator2Styles } from '../../styles/core-css'
|
||||||
|
|
||||||
import '@material/mwc-icon'
|
import '@material/mwc-icon'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import {translate} from '../../../translate'
|
||||||
|
|
||||||
class SyncIndicator extends connect(store)(LitElement) {
|
class SyncIndicator extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
@ -18,6 +20,10 @@ class SyncIndicator extends connect(store)(LitElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return [syncIndicator2Styles]
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
this.blocksBehind = 0
|
this.blocksBehind = 0
|
||||||
@ -32,64 +38,6 @@ class SyncIndicator extends connect(store)(LitElement) {
|
|||||||
this.hasOpened = false
|
this.hasOpened = false
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
|
||||||
return css`
|
|
||||||
* {
|
|
||||||
--mdc-theme-text-primary-on-background: var(--black);
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host {
|
|
||||||
box-sizing: border-box;
|
|
||||||
position: fixed;
|
|
||||||
bottom: 50px;
|
|
||||||
right: 25px;
|
|
||||||
z-index: 50000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.parent {
|
|
||||||
width: 360px;
|
|
||||||
padding: 10px;
|
|
||||||
border-radius: 8px;
|
|
||||||
border: 1px solid var(--black);
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
user-select: none;
|
|
||||||
background: var(--white);
|
|
||||||
}
|
|
||||||
|
|
||||||
.row {
|
|
||||||
display: flex;
|
|
||||||
gap: 10px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.column {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 10px;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-button {
|
|
||||||
font-family: Roboto, sans-serif;
|
|
||||||
font-size: 16px;
|
|
||||||
color: var(--mdc-theme-primary);
|
|
||||||
background-color: transparent;
|
|
||||||
padding: 8px 10px;
|
|
||||||
border-radius: 5px;
|
|
||||||
border: none;
|
|
||||||
transition: all 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.bootstrap-button:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: #03a8f475;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
${!this.hasCoreRunning ? html`
|
${!this.hasCoreRunning ? html`
|
||||||
@ -225,7 +173,7 @@ class SyncIndicator extends connect(store)(LitElement) {
|
|||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new CustomEvent('open-welcome-modal-sync', {
|
new CustomEvent('open-welcome-modal-sync', {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
composed: true,
|
composed: true
|
||||||
})
|
})
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -257,4 +205,4 @@ class SyncIndicator extends connect(store)(LitElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('sync-indicator', SyncIndicator)
|
window.customElements.define('sync-indicator', SyncIndicator)
|
@ -1,16 +1,19 @@
|
|||||||
import {css, html, LitElement} from 'lit';
|
import { html, LitElement } from 'lit'
|
||||||
import {driver} from 'driver.js';
|
import { connect } from 'pwa-helpers'
|
||||||
import 'driver.js/dist/driver.css';
|
import { store } from '../../store'
|
||||||
import '@material/mwc-icon';
|
import { setNewTab } from '../../redux/app/app-actions'
|
||||||
import '@polymer/paper-spinner/paper-spinner-lite.js';
|
import { tourComponentStyles } from '../../styles/core-css'
|
||||||
import '@vaadin/tooltip';
|
import { driver } from 'driver.js'
|
||||||
import '@material/mwc-button';
|
import 'driver.js/dist/driver.css'
|
||||||
import {get, translate} from '../../../translate';
|
import './tour.css'
|
||||||
import '@polymer/paper-dialog/paper-dialog.js';
|
import '@material/mwc-button'
|
||||||
import {setNewTab} from '../../redux/app/app-actions.js';
|
import '@material/mwc-icon'
|
||||||
import {store} from '../../store.js';
|
import '@polymer/paper-dialog/paper-dialog.js'
|
||||||
import {connect} from 'pwa-helpers';
|
import '@polymer/paper-spinner/paper-spinner-lite.js'
|
||||||
import './tour.css';
|
import '@vaadin/tooltip'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { get, translate } from '../../../translate'
|
||||||
|
|
||||||
class TourComponent extends connect(store)(LitElement) {
|
class TourComponent extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
@ -18,242 +21,112 @@ class TourComponent extends connect(store)(LitElement) {
|
|||||||
getElements: { attribute: false },
|
getElements: { attribute: false },
|
||||||
dialogOpenedCongrats: { type: Boolean },
|
dialogOpenedCongrats: { type: Boolean },
|
||||||
hasViewedTour: { type: Boolean },
|
hasViewedTour: { type: Boolean },
|
||||||
disableTour: {type: Boolean}
|
disableTour: { type: Boolean },
|
||||||
};
|
nodeUrl: { type: String },
|
||||||
|
address: { type: String }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return [tourComponentStyles]
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super()
|
||||||
this.dialogOpenedCongrats = false;
|
this.dialogOpenedCongrats = false
|
||||||
this._controlOpenWelcomeModal =
|
this._controlOpenWelcomeModal = this._controlOpenWelcomeModal.bind(this)
|
||||||
this._controlOpenWelcomeModal.bind(this);
|
this.hasName = false
|
||||||
this.hasName = false;
|
this.nodeUrl = ''
|
||||||
this.nodeUrl = this.getNodeUrl();
|
this.address = ''
|
||||||
this.myNode = this.getMyNode();
|
|
||||||
this._disableTour = this._disableTour.bind(this)
|
this._disableTour = this._disableTour.bind(this)
|
||||||
this.disableTour = false
|
this.disableTour = false
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
render() {
|
||||||
return css`
|
return html`
|
||||||
* {
|
<!-- Profile read-view -->
|
||||||
--mdc-theme-primary: rgb(3, 169, 244);
|
${this.dialogOpenedCongrats && this.hasViewedTour ? html`
|
||||||
--mdc-theme-secondary: var(--mdc-theme-primary);
|
<paper-dialog class="full-info-wrapper" ?opened="${this.dialogOpenedCongrats}">
|
||||||
--mdc-theme-surface: var(--white);
|
<h3>Congratulations!</h3>
|
||||||
--mdc-dialog-content-ink-color: var(--black);
|
<div style="display:flex;gap:15px;justify-content:center;margin-top:10px">
|
||||||
box-sizing: border-box;
|
${translate("tour.tour13")}
|
||||||
color: var(--black);
|
</div>
|
||||||
background: var(--white);
|
<div style="display:flex;gap:15px;justify-content:center;margin-top:10px">
|
||||||
}
|
${translate("tour.tour14")}
|
||||||
|
</div>
|
||||||
:host {
|
<div class="accept-button" @click=${this.visitQtube}>
|
||||||
box-sizing: border-box;
|
${translate("tour.tour15")}
|
||||||
position: fixed;
|
</div>
|
||||||
bottom: 25px;
|
<div style="width:100%;display:flex;justify-content:center;margin-top:10px">
|
||||||
right: 25px;
|
<div class="close-button" @click=${() => { this.onClose() }}>
|
||||||
z-index: 50000;
|
${translate("general.close")}
|
||||||
}
|
</div>
|
||||||
|
</div>
|
||||||
.full-info-wrapper {
|
</paper-dialog>
|
||||||
width: 100%;
|
` : ''}
|
||||||
min-width: 600px;
|
`
|
||||||
max-width: 600px;
|
|
||||||
text-align: center;
|
|
||||||
background: var(--white);
|
|
||||||
border: 1px solid var(--black);
|
|
||||||
border-radius: 15px;
|
|
||||||
padding: 25px;
|
|
||||||
box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
|
|
||||||
display: block !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.buttons {
|
|
||||||
display: inline;
|
|
||||||
}
|
|
||||||
.accept-button {
|
|
||||||
font-family: Roboto, sans-serif;
|
|
||||||
letter-spacing: 0.3px;
|
|
||||||
font-weight: 300;
|
|
||||||
padding: 8px 5px;
|
|
||||||
border-radius: 3px;
|
|
||||||
text-align: center;
|
|
||||||
color: var(--black);
|
|
||||||
transition: all 0.3s ease-in-out;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
font-size: 18px;
|
|
||||||
justify-content: center;
|
|
||||||
outline: 1px solid var(--black);
|
|
||||||
}
|
|
||||||
|
|
||||||
.accept-button:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: #03a8f485;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close-button {
|
|
||||||
font-family: Roboto, sans-serif;
|
|
||||||
letter-spacing: 0.3px;
|
|
||||||
font-weight: 300;
|
|
||||||
padding: 8px 5px;
|
|
||||||
border-radius: 3px;
|
|
||||||
text-align: center;
|
|
||||||
color: #f44336;
|
|
||||||
transition: all 0.3s ease-in-out;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
font-size: 18px;
|
|
||||||
width:auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close-button:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: #f4433663;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_controlOpenWelcomeModal() {
|
|
||||||
this.isSynced = true
|
|
||||||
|
|
||||||
const seenWelcomeSync = JSON.parse(
|
|
||||||
localStorage.getItem('welcome-sync') || 'false'
|
|
||||||
);
|
|
||||||
if (this.hasName) return;
|
|
||||||
if (seenWelcomeSync) return;
|
|
||||||
if(!this.hasViewedTour) return
|
|
||||||
this.dialogOpenedCongrats = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
openWelcomeModal() {
|
|
||||||
this.dispatchEvent(
|
|
||||||
new CustomEvent('send-tour-finished', {
|
|
||||||
bubbles: true,
|
|
||||||
composed: true,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
const seenWelcomeSync = JSON.parse(
|
|
||||||
localStorage.getItem('welcome-sync') || 'false'
|
|
||||||
);
|
|
||||||
if (this.hasName) return;
|
|
||||||
if (seenWelcomeSync) return;
|
|
||||||
if(!this.isSynced) return
|
|
||||||
this.dialogOpenedCongrats = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
_disableTour(){
|
|
||||||
this.disableTour = true
|
|
||||||
driver.reset()
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
|
||||||
super.connectedCallback();
|
|
||||||
window.addEventListener(
|
|
||||||
'open-welcome-modal-sync',
|
|
||||||
this._controlOpenWelcomeModal
|
|
||||||
);
|
|
||||||
window.addEventListener(
|
|
||||||
'disable-tour',
|
|
||||||
this._disableTour
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
disconnectedCallback() {
|
|
||||||
window.removeEventListener(
|
|
||||||
'open-welcome-modal-sync',
|
|
||||||
this._controlOpenWelcomeModal
|
|
||||||
);
|
|
||||||
window.addEventListener(
|
|
||||||
'disable-tour',
|
|
||||||
this._disableTour
|
|
||||||
);
|
|
||||||
super.disconnectedCallback();
|
|
||||||
}
|
|
||||||
|
|
||||||
getNodeUrl() {
|
|
||||||
const myNode =
|
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
|
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
]
|
|
||||||
|
|
||||||
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
|
||||||
}
|
|
||||||
getMyNode() {
|
|
||||||
return window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
|
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
async getName(recipient) {
|
|
||||||
try {
|
|
||||||
const endpoint = `${this.nodeUrl}/names/address/${recipient}`;
|
|
||||||
const res = await fetch(endpoint);
|
|
||||||
const getNames = await res.json();
|
|
||||||
|
|
||||||
if (Array.isArray(getNames) && getNames.length > 0) {
|
|
||||||
return getNames[0].name;
|
|
||||||
} else {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
async firstUpdated() {
|
async firstUpdated() {
|
||||||
|
this.getNodeUrl()
|
||||||
this.address = store.getState().app.selectedAddress.address
|
this.address = store.getState().app.selectedAddress.address
|
||||||
const hasViewedTour = JSON.parse(
|
|
||||||
localStorage.getItem(`hasViewedTour-${this.address}`) || 'false'
|
const hasViewedTour = JSON.parse(localStorage.getItem(`hasViewedTour-${this.address}`) || 'false')
|
||||||
);
|
const name = await this.getName(this.address)
|
||||||
const name = await this.getName(this.address);
|
|
||||||
if (name) {
|
if (name) {
|
||||||
this.hasName = true;
|
this.hasName = true
|
||||||
}
|
}
|
||||||
this.hasViewedTour = hasViewedTour;
|
|
||||||
|
this.hasViewedTour = hasViewedTour
|
||||||
|
|
||||||
if (!hasViewedTour) {
|
if (!hasViewedTour) {
|
||||||
try {
|
try {
|
||||||
if (name) {
|
if (name) {
|
||||||
this.hasViewedTour = true;
|
this.hasViewedTour = true
|
||||||
this.hasName = true;
|
this.hasName = true
|
||||||
localStorage.setItem(`hasViewedTour-${this.address}`, JSON.stringify(true))
|
localStorage.setItem(`hasViewedTour-${this.address}`, JSON.stringify(true))
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log({ error });
|
console.log({ error })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
await new Promise((res) => {
|
await new Promise((res) => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
res();
|
res()
|
||||||
}, 1000);
|
}, 1000)
|
||||||
});
|
})
|
||||||
|
|
||||||
if (!this.hasViewedTour && this.disableTour !== true) {
|
if (!this.hasViewedTour && this.disableTour !== true) {
|
||||||
const elements = this.getElements();
|
const elements = this.getElements()
|
||||||
let steps = [
|
|
||||||
{
|
let steps = [{
|
||||||
popover: {
|
popover: {
|
||||||
title: get("tour.tour6"),
|
title: get("tour.tour6"),
|
||||||
description: `
|
description: `
|
||||||
<div style="display:flex;justify-content:center;gap:15px">
|
<div style="display:flex;justify-content:center;gap:15px">
|
||||||
<img style="height:40px;width:auto;margin:15px 0px;" src="/img/qort.png" />
|
<img style="height:40px;width:auto;margin:15px 0px;" src="/img/qort.png" />
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;">
|
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;">
|
||||||
<div style="height:6px;width:6px;border-radius:50%;background:var(--black)"></div> <p style="margin:0px;padding:0px">${get("tour.tour7")}</p>
|
<div style="height:6px;width:6px;border-radius:50%;background:var(--black)"></div>
|
||||||
</div>
|
<p style="margin:0px;padding:0px">${get("tour.tour7")}</p>
|
||||||
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;">
|
</div>
|
||||||
<div style="height:6px;width:6px;border-radius:50%;background:var(--black)"></div> <p style="margin:0px;padding:0px">${get("tour.tour8")}</p>
|
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;">
|
||||||
</div>
|
<div style="height:6px;width:6px;border-radius:50%;background:var(--black)"></div>
|
||||||
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;margin-bottom:30px">
|
<p style="margin:0px;padding:0px">${get("tour.tour8")}</p>
|
||||||
<div style="height:6px;width:6px;border-radius:50%;background:var(--black)"></div> <p style="margin:0px;padding:0px">${get("tour.tour9")}</p>
|
</div>
|
||||||
</div>
|
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;margin-bottom:30px">
|
||||||
`,
|
<div style="height:6px;width:6px;border-radius:50%;background:var(--black)"></div>
|
||||||
// ... other options
|
<p style="margin:0px;padding:0px">${get("tour.tour9")}</p>
|
||||||
},
|
</div>
|
||||||
},
|
`
|
||||||
];
|
}
|
||||||
const step2 = elements['core-sync-status-id'];
|
}]
|
||||||
const step3 = elements['tab'];
|
|
||||||
const step4 = elements['checklist'];
|
const step2 = elements['core-sync-status-id']
|
||||||
|
const step3 = elements['tab']
|
||||||
|
const step4 = elements['checklist']
|
||||||
|
|
||||||
if (step2) {
|
if (step2) {
|
||||||
steps.push({
|
steps.push({
|
||||||
@ -261,58 +134,54 @@ class TourComponent extends connect(store)(LitElement) {
|
|||||||
popover: {
|
popover: {
|
||||||
title: get("tour.tour5"),
|
title: get("tour.tour5"),
|
||||||
description: `
|
description: `
|
||||||
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;margin-bottom:30px">
|
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;margin-bottom:30px">
|
||||||
<p style="margin:0px;padding:0px">${get("tour.tour1")}</p>
|
<p style="margin:0px;padding:0px">${get("tour.tour1")}</p>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;">
|
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;">
|
||||||
<span><img src="/img/synced.png" style="height: 24px; width: 24px; padding-top: 4px;" /></span>
|
<span><img src="/img/synced.png" style="height: 24px; width: 24px; padding-top: 4px;" /></span>
|
||||||
<p style="margin:0px;padding:0px">${get("tour.tour2")}</p>
|
<p style="margin:0px;padding:0px">${get("tour.tour2")}</p>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;">
|
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;">
|
||||||
<span><img src="/img/synced_minting.png" style="height: 24px; width: 24px; padding-top: 4px;" /></span>
|
<span><img src="/img/synced_minting.png" style="height: 24px; width: 24px; padding-top: 4px;" /></span>
|
||||||
<p style="margin:0px;padding:0px">${get("tour.tour3")}</p>
|
<p style="margin:0px;padding:0px">${get("tour.tour3")}</p>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;margin-bottom:30px">
|
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;margin-bottom:30px">
|
||||||
<span><img src="/img/syncing.png" style="height: 24px; width: 24px; padding-top: 4px;" /></span>
|
<span><img src="/img/syncing.png" style="height: 24px; width: 24px; padding-top: 4px;" /></span>
|
||||||
<p style="margin:0px;padding:0px">${get("tour.tour4")}</p>
|
<p style="margin:0px;padding:0px">${get("tour.tour4")}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
`,
|
`
|
||||||
},
|
}
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if (step3) {
|
if (step3) {
|
||||||
steps.push({
|
steps.push({
|
||||||
element: step3,
|
element: step3,
|
||||||
popover: {
|
popover: {
|
||||||
title: 'Tab View',
|
title: 'Tab View',
|
||||||
description: `
|
description: `
|
||||||
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;margin-bottom:30px">
|
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;margin-bottom:30px">
|
||||||
<p style="margin:0px;padding:0px">${get("tour.tour10")}
|
<p style="margin:0px;padding:0px">${get("tour.tour10")}</p>
|
||||||
</p>
|
</div>
|
||||||
</div>
|
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;">
|
||||||
<div style="display:flex;gap:15px;align-items:center;margin-top:15px;">
|
<span><img src="/img/addplugin.webp" style="height: 36px; width: 36px; padding-top: 4px;" /></span>
|
||||||
<span><img src="/img/addplugin.webp" style="height: 36px; width: 36px; padding-top: 4px;" /></span>
|
<p style="margin:0px;padding:0px">
|
||||||
<p style="margin:0px;padding:0px">You can also bookmark other Q-Apps and Plugins by clicking on the ${get(
|
You can also bookmark other Q-Apps and Plugins by clicking on the ${get('tabmenu.tm19')} button
|
||||||
'tabmenu.tm19'
|
</p>
|
||||||
)} button</p>
|
</div>
|
||||||
</div>
|
`
|
||||||
`,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
if (step4) {
|
|
||||||
steps.push(
|
|
||||||
{
|
|
||||||
element: step4,
|
|
||||||
popover: {
|
|
||||||
title: get("tour.tour11"),
|
|
||||||
description: get("tour.tour12"),
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
);this.hasViewedTour
|
})
|
||||||
}
|
}
|
||||||
let currentStepIndex = 0;
|
|
||||||
|
if (step4) {
|
||||||
|
steps.push({ element: step4, popover: { title: get("tour.tour11"), description: get("tour.tour12")}})
|
||||||
|
this.hasViewedTour
|
||||||
|
}
|
||||||
|
|
||||||
|
let currentStepIndex = 0
|
||||||
|
|
||||||
const driverObj = driver({
|
const driverObj = driver({
|
||||||
popoverClass: 'driverjs-theme',
|
popoverClass: 'driverjs-theme',
|
||||||
showProgress: true,
|
showProgress: true,
|
||||||
@ -321,25 +190,93 @@ class TourComponent extends connect(store)(LitElement) {
|
|||||||
allowClose: false,
|
allowClose: false,
|
||||||
onDestroyed: () => {
|
onDestroyed: () => {
|
||||||
localStorage.setItem(`hasViewedTour-${this.address}`, JSON.stringify(true))
|
localStorage.setItem(`hasViewedTour-${this.address}`, JSON.stringify(true))
|
||||||
this.hasViewedTour = true;
|
this.hasViewedTour = true
|
||||||
this.openWelcomeModal();
|
this.openWelcomeModal()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
driverObj.drive();
|
driverObj.drive()
|
||||||
} else {
|
} else {
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new CustomEvent('send-tour-finished', {
|
new CustomEvent('send-tour-finished', {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
composed: true,
|
composed: true
|
||||||
})
|
})
|
||||||
);
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_controlOpenWelcomeModal() {
|
||||||
|
this.isSynced = true
|
||||||
|
|
||||||
|
const seenWelcomeSync = JSON.parse(localStorage.getItem('welcome-sync') || 'false')
|
||||||
|
|
||||||
|
if (this.hasName) return
|
||||||
|
if (seenWelcomeSync) return
|
||||||
|
if (!this.hasViewedTour) return
|
||||||
|
|
||||||
|
this.dialogOpenedCongrats = true
|
||||||
|
}
|
||||||
|
|
||||||
|
openWelcomeModal() {
|
||||||
|
this.dispatchEvent(
|
||||||
|
new CustomEvent('send-tour-finished', {
|
||||||
|
bubbles: true,
|
||||||
|
composed: true
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
const seenWelcomeSync = JSON.parse(localStorage.getItem('welcome-sync') || 'false')
|
||||||
|
|
||||||
|
if (this.hasName) return
|
||||||
|
if (seenWelcomeSync) return
|
||||||
|
if (!this.isSynced) return
|
||||||
|
|
||||||
|
this.dialogOpenedCongrats = true
|
||||||
|
}
|
||||||
|
|
||||||
|
_disableTour() {
|
||||||
|
this.disableTour = true
|
||||||
|
driver.reset()
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
super.connectedCallback()
|
||||||
|
window.addEventListener('open-welcome-modal-sync', this._controlOpenWelcomeModal)
|
||||||
|
window.addEventListener('disable-tour', this._disableTour)
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
window.removeEventListener('open-welcome-modal-sync', this._controlOpenWelcomeModal)
|
||||||
|
window.addEventListener('disable-tour', this._disableTour)
|
||||||
|
super.disconnectedCallback()
|
||||||
|
}
|
||||||
|
|
||||||
|
getNodeUrl() {
|
||||||
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
const myNodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
|
this.nodeUrl = myNodeUrl
|
||||||
|
}
|
||||||
|
|
||||||
|
async getName(recipient) {
|
||||||
|
try {
|
||||||
|
const endpoint = `${this.nodeUrl}/names/address/${recipient}`
|
||||||
|
const res = await fetch(endpoint)
|
||||||
|
const getNames = await res.json()
|
||||||
|
|
||||||
|
if (Array.isArray(getNames) && getNames.length > 0) {
|
||||||
|
return getNames[0].name
|
||||||
|
} else {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
visitQtube() {
|
visitQtube() {
|
||||||
this.onClose();
|
this.onClose()
|
||||||
const query = `?service=APP&name=Q-Tube`;
|
const query = `?service=APP&name=Q-Tube`
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
setNewTab({
|
setNewTab({
|
||||||
url: `qdn/browser/index.html${query}`,
|
url: `qdn/browser/index.html${query}`,
|
||||||
@ -350,59 +287,16 @@ class TourComponent extends connect(store)(LitElement) {
|
|||||||
page: `qdn/browser/index.html${query}`,
|
page: `qdn/browser/index.html${query}`,
|
||||||
title: 'Q-Tube',
|
title: 'Q-Tube',
|
||||||
menus: [],
|
menus: [],
|
||||||
parent: false,
|
parent: false
|
||||||
},
|
}
|
||||||
})
|
})
|
||||||
);
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose() {
|
onClose() {
|
||||||
localStorage.setItem(`welcome-sync-${this.address}`, JSON.stringify(true))
|
localStorage.setItem(`welcome-sync-${this.address}`, JSON.stringify(true))
|
||||||
this.dialogOpenedCongrats = false;
|
this.dialogOpenedCongrats = false
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return html`
|
|
||||||
<!-- Profile read-view -->
|
|
||||||
${this.dialogOpenedCongrats && this.hasViewedTour
|
|
||||||
? html`
|
|
||||||
<paper-dialog
|
|
||||||
class="full-info-wrapper"
|
|
||||||
?opened="${this.dialogOpenedCongrats}"
|
|
||||||
>
|
|
||||||
<h3>Congratulations!</h3>
|
|
||||||
<div
|
|
||||||
style="display:flex;gap:15px;justify-content:center;margin-top:10px"
|
|
||||||
>
|
|
||||||
${translate("tour.tour13")}
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style="display:flex;gap:15px;justify-content:center;margin-top:10px"
|
|
||||||
>
|
|
||||||
${translate("tour.tour14")}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="accept-button"
|
|
||||||
@click=${this.visitQtube}
|
|
||||||
>
|
|
||||||
${translate("tour.tour15")}
|
|
||||||
</div>
|
|
||||||
<div style="width:100%;display:flex;justify-content:center;margin-top:10px">
|
|
||||||
<div
|
|
||||||
class="close-button"
|
|
||||||
@click=${()=> {
|
|
||||||
this.onClose()
|
|
||||||
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
${translate("general.close")}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</paper-dialog>
|
|
||||||
`
|
|
||||||
: ''}
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
customElements.define('tour-component', TourComponent);
|
|
||||||
|
window.customElements.define('tour-component', TourComponent)
|
@ -1,10 +1,11 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {translate} from '../../translate'
|
|
||||||
import isElectron from 'is-electron'
|
import isElectron from 'is-electron'
|
||||||
|
|
||||||
import '@polymer/paper-icon-button/paper-icon-button.js'
|
import '@polymer/paper-icon-button/paper-icon-button.js'
|
||||||
import '@polymer/iron-icons/iron-icons.js'
|
import '@polymer/iron-icons/iron-icons.js'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { translate } from '../../translate'
|
||||||
|
|
||||||
class CheckForUpdate extends LitElement {
|
class CheckForUpdate extends LitElement {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
@ -17,11 +18,6 @@ class CheckForUpdate extends LitElement {
|
|||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = [
|
|
||||||
css`
|
|
||||||
`
|
|
||||||
]
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
${this.renderUpdateButton()}
|
${this.renderUpdateButton()}
|
||||||
@ -29,6 +25,7 @@ class CheckForUpdate extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated() {
|
firstUpdated() {
|
||||||
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
renderUpdateButton() {
|
renderUpdateButton() {
|
||||||
@ -48,4 +45,4 @@ class CheckForUpdate extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('check-for-update', CheckForUpdate)
|
window.customElements.define('check-for-update', CheckForUpdate)
|
@ -1,82 +1,58 @@
|
|||||||
import {Sha256} from 'asmcrypto.js'
|
import { Sha256 } from 'asmcrypto.js'
|
||||||
|
|
||||||
|
function sbrk(size, heap) {
|
||||||
function sbrk(size, heap){
|
let brk = 512 * 1024 // stack top
|
||||||
let brk = 512 * 1024 // stack top
|
let old = brk
|
||||||
let old = brk
|
brk += size
|
||||||
brk += size
|
if (brk > heap.length) throw new Error('heap exhausted')
|
||||||
|
return old
|
||||||
if (brk > heap.length)
|
|
||||||
throw new Error('heap exhausted')
|
|
||||||
|
|
||||||
return old
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
self.addEventListener('message', async e => {
|
self.addEventListener('message', async e => {
|
||||||
const response = await computePow(e.data.chatBytes, e.data.path, e.data.difficulty)
|
const response = await computePow(e.data.chatBytes, e.data.path, e.data.difficulty)
|
||||||
postMessage(response)
|
postMessage(response)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 })
|
const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 })
|
||||||
const heap = new Uint8Array(memory.buffer)
|
const heap = new Uint8Array(memory.buffer)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const computePow = async (chatBytes, path, difficulty) => {
|
const computePow = async (chatBytes, path, difficulty) => {
|
||||||
|
let response = null
|
||||||
let response = null
|
await new Promise((resolve, reject) => {
|
||||||
|
const _chatBytesArray = Object.keys(chatBytes).map(function (key) { return chatBytes[key]; })
|
||||||
await new Promise((resolve, reject)=> {
|
const chatBytesArray = new Uint8Array(_chatBytesArray)
|
||||||
|
const chatBytesHash = new Sha256().process(chatBytesArray).finish().result
|
||||||
const _chatBytesArray = Object.keys(chatBytes).map(function (key) { return chatBytes[key]; });
|
const hashPtr = sbrk(32, heap)
|
||||||
const chatBytesArray = new Uint8Array(_chatBytesArray);
|
const hashAry = new Uint8Array(memory.buffer, hashPtr, 32)
|
||||||
const chatBytesHash = new Sha256().process(chatBytesArray).finish().result;
|
hashAry.set(chatBytesHash)
|
||||||
const hashPtr = sbrk(32, heap);
|
const workBufferLength = 8 * 1024 * 1024
|
||||||
const hashAry = new Uint8Array(memory.buffer, hashPtr, 32);
|
const workBufferPtr = sbrk(workBufferLength, heap)
|
||||||
hashAry.set(chatBytesHash);
|
const importObject = {
|
||||||
|
env: {
|
||||||
|
memory: memory
|
||||||
const workBufferLength = 8 * 1024 * 1024;
|
}
|
||||||
const workBufferPtr = sbrk(workBufferLength, heap);
|
}
|
||||||
|
function loadWebAssembly(filename, imports) {
|
||||||
|
// Fetch the file and compile it
|
||||||
|
return fetch(filename)
|
||||||
const importObject = {
|
.then(response => response.arrayBuffer())
|
||||||
env: {
|
.then(buffer => WebAssembly.compile(buffer))
|
||||||
memory: memory
|
.then(module => {
|
||||||
},
|
// Create the instance.
|
||||||
};
|
return new WebAssembly.Instance(module, importObject)
|
||||||
|
})
|
||||||
function loadWebAssembly(filename, imports) {
|
}
|
||||||
// Fetch the file and compile it
|
loadWebAssembly(path)
|
||||||
return fetch(filename)
|
.then(wasmModule => {
|
||||||
.then(response => response.arrayBuffer())
|
response = {
|
||||||
.then(buffer => WebAssembly.compile(buffer))
|
nonce: wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty),
|
||||||
.then(module => {
|
chatBytesArray
|
||||||
|
}
|
||||||
// Create the instance.
|
resolve()
|
||||||
return new WebAssembly.Instance(module, importObject);
|
})
|
||||||
});
|
})
|
||||||
}
|
return response
|
||||||
|
}
|
||||||
|
|
||||||
loadWebAssembly(path)
|
|
||||||
.then(wasmModule => {
|
|
||||||
response = {
|
|
||||||
nonce : wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty),
|
|
||||||
chatBytesArray
|
|
||||||
}
|
|
||||||
|
|
||||||
resolve()
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
return response
|
|
||||||
}
|
|
@ -1,92 +1,68 @@
|
|||||||
import { Sha256 } from 'asmcrypto.js'
|
import { Sha256 } from 'asmcrypto.js'
|
||||||
|
|
||||||
|
function sbrk(size, heap) {
|
||||||
|
let brk = 512 * 1024 // stack top
|
||||||
function sbrk(size, heap){
|
let old = brk
|
||||||
let brk = 512 * 1024 // stack top
|
brk += size
|
||||||
let old = brk
|
if (brk > heap.length) throw new Error('heap exhausted')
|
||||||
brk += size
|
return old
|
||||||
|
|
||||||
if (brk > heap.length)
|
|
||||||
throw new Error('heap exhausted')
|
|
||||||
|
|
||||||
return old
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
self.addEventListener('message', async e => {
|
self.addEventListener('message', async e => {
|
||||||
const response = await computePow(e.data.convertedBytes, e.data.path)
|
const response = await computePow(e.data.convertedBytes, e.data.path)
|
||||||
postMessage(response)
|
postMessage(response)
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
|
})
|
||||||
|
|
||||||
const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 })
|
const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 })
|
||||||
const heap = new Uint8Array(memory.buffer)
|
const heap = new Uint8Array(memory.buffer)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const computePow = async (convertedBytes, path) => {
|
const computePow = async (convertedBytes, path) => {
|
||||||
|
let response = null
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
const _convertedBytesArray = Object.keys(convertedBytes).map(
|
||||||
|
function (key) {
|
||||||
|
return convertedBytes[key]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const convertedBytesArray = new Uint8Array(_convertedBytesArray)
|
||||||
|
const convertedBytesHash = new Sha256()
|
||||||
|
.process(convertedBytesArray)
|
||||||
|
.finish().result
|
||||||
|
const hashPtr = sbrk(32, heap)
|
||||||
|
const hashAry = new Uint8Array(
|
||||||
|
memory.buffer,
|
||||||
|
hashPtr,
|
||||||
|
32
|
||||||
|
)
|
||||||
|
hashAry.set(convertedBytesHash)
|
||||||
|
const difficulty = 14
|
||||||
|
const workBufferLength = 8 * 1024 * 1024
|
||||||
|
const workBufferPtr = sbrk(
|
||||||
|
workBufferLength,
|
||||||
|
heap
|
||||||
|
)
|
||||||
|
const importObject = {
|
||||||
|
env: {
|
||||||
|
memory: memory
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function loadWebAssembly(filename, imports) {
|
||||||
|
return fetch(filename)
|
||||||
|
.then(response => response.arrayBuffer())
|
||||||
|
.then(buffer => WebAssembly.compile(buffer))
|
||||||
|
.then(module => {
|
||||||
|
return new WebAssembly.Instance(module, importObject)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
loadWebAssembly(path)
|
||||||
|
.then(wasmModule => {
|
||||||
|
response = {
|
||||||
|
nonce: wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty),
|
||||||
|
|
||||||
|
}
|
||||||
let response = null
|
resolve()
|
||||||
|
})
|
||||||
await new Promise((resolve, reject)=> {
|
})
|
||||||
|
return response
|
||||||
const _convertedBytesArray = Object.keys(convertedBytes).map(
|
|
||||||
function (key) {
|
|
||||||
return convertedBytes[key]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
const convertedBytesArray = new Uint8Array(_convertedBytesArray)
|
|
||||||
const convertedBytesHash = new Sha256()
|
|
||||||
.process(convertedBytesArray)
|
|
||||||
.finish().result
|
|
||||||
const hashPtr = sbrk(32, heap)
|
|
||||||
const hashAry = new Uint8Array(
|
|
||||||
memory.buffer,
|
|
||||||
hashPtr,
|
|
||||||
32
|
|
||||||
)
|
|
||||||
|
|
||||||
hashAry.set(convertedBytesHash)
|
|
||||||
const difficulty = 14
|
|
||||||
const workBufferLength = 8 * 1024 * 1024
|
|
||||||
const workBufferPtr = sbrk(
|
|
||||||
workBufferLength,
|
|
||||||
heap
|
|
||||||
)
|
|
||||||
|
|
||||||
const importObject = {
|
|
||||||
env: {
|
|
||||||
memory: memory
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function loadWebAssembly(filename, imports) {
|
|
||||||
return fetch(filename)
|
|
||||||
.then(response => response.arrayBuffer())
|
|
||||||
.then(buffer => WebAssembly.compile(buffer))
|
|
||||||
.then(module => {
|
|
||||||
return new WebAssembly.Instance(module, importObject);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
loadWebAssembly(path)
|
|
||||||
.then(wasmModule => {
|
|
||||||
response = {
|
|
||||||
nonce : wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty),
|
|
||||||
|
|
||||||
}
|
|
||||||
resolve()
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
return response
|
|
||||||
}
|
}
|
@ -1,320 +1,303 @@
|
|||||||
import {html, LitElement} from 'lit';
|
import { html, LitElement } from 'lit'
|
||||||
import '@material/mwc-icon';
|
import { connect } from 'pwa-helpers'
|
||||||
import {store} from '../../store';
|
import { store } from '../../store'
|
||||||
import {connect} from 'pwa-helpers';
|
import { parentEpml } from '../show-plugin'
|
||||||
import '@vaadin/tooltip';
|
import { setCoinBalances } from '../../redux/app/app-actions'
|
||||||
import {parentEpml} from '../show-plugin';
|
|
||||||
import {setCoinBalances} from '../../redux/app/app-actions';
|
|
||||||
|
|
||||||
class CoinBalancesController extends connect(store)(LitElement) {
|
class CoinBalancesController extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
coinList: { type: Object },
|
coinList: { type: Object }
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super();
|
||||||
this.coinList = {}
|
this.coinList = {}
|
||||||
this.nodeUrl = this.getNodeUrl();
|
this.nodeUrl = this.getNodeUrl()
|
||||||
this.myNode = this.getMyNode();
|
this.myNode = this.getMyNode()
|
||||||
this.fetchBalance = this.fetchBalance.bind(this)
|
this.fetchBalance = this.fetchBalance.bind(this)
|
||||||
this._updateCoinList = this._updateCoinList.bind(this)
|
this._updateCoinList = this._updateCoinList.bind(this)
|
||||||
this.stop = false
|
this.stop = false
|
||||||
}
|
}
|
||||||
|
|
||||||
getNodeUrl() {
|
render() {
|
||||||
const myNode =
|
return html``
|
||||||
store.getState().app.nodeConfig.knownNodes[
|
}
|
||||||
store.getState().app.nodeConfig.node
|
|
||||||
]
|
|
||||||
|
|
||||||
|
getNodeUrl() {
|
||||||
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
}
|
}
|
||||||
|
|
||||||
getMyNode() {
|
getMyNode() {
|
||||||
return store.getState().app.nodeConfig.knownNodes[
|
return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
store.getState().app.nodeConfig.node
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updateQortWalletBalance() {
|
||||||
|
let qortAddress = store.getState().app.selectedAddress.address
|
||||||
|
|
||||||
async updateArrrWalletBalance() {
|
await parentEpml.request('apiCall', {
|
||||||
let _url = `/crosschain/arrr/walletbalance?apiKey=${this.myNode.apiKey}`
|
url: `/addresses/balance/${qortAddress}?apiKey=${this.myNode.apiKey}`,
|
||||||
let _body = store.getState().app.selectedAddress.arrrWallet.seed58
|
}).then((res) => {
|
||||||
|
this.qortWalletBalance = res
|
||||||
await parentEpml.request('apiCall', {
|
store.dispatch(
|
||||||
url: _url,
|
setCoinBalances({
|
||||||
method: 'POST',
|
type: 'qort',
|
||||||
body: _body,
|
fullValue: Number(res)
|
||||||
}).then((res) => {
|
})
|
||||||
if (isNaN(Number(res))) {
|
)
|
||||||
//...
|
}).catch(() => {
|
||||||
} else {
|
console.log('error')
|
||||||
this.arrrWalletBalance = (Number(res) / 1e8).toFixed(8)
|
})
|
||||||
store.dispatch(
|
|
||||||
setCoinBalances({
|
|
||||||
type: 'arrr',
|
|
||||||
fullValue: Number(res)
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}).catch(()=> {
|
|
||||||
console.log('error')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
async updateQortWalletBalance() {
|
|
||||||
let qortAddress = store.getState().app.selectedAddress.address
|
|
||||||
|
|
||||||
await parentEpml.request('apiCall', {
|
|
||||||
url: `/addresses/balance/${qortAddress}?apiKey=${this.myNode.apiKey}`,
|
|
||||||
}).then((res) => {
|
|
||||||
this.qortWalletBalance = res
|
|
||||||
store.dispatch(
|
|
||||||
setCoinBalances({
|
|
||||||
type: 'qort',
|
|
||||||
fullValue: Number(res)
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}).catch(()=> {
|
|
||||||
console.log('error')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateRvnWalletBalance() {
|
|
||||||
let _url = `/crosschain/rvn/walletbalance?apiKey=${this.myNode.apiKey}`
|
|
||||||
let _body = store.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey
|
|
||||||
|
|
||||||
await parentEpml.request('apiCall', {
|
|
||||||
url: _url,
|
|
||||||
method: 'POST',
|
|
||||||
body: _body,
|
|
||||||
}).then((res) => {
|
|
||||||
if (isNaN(Number(res))) {
|
|
||||||
//...
|
|
||||||
} else {
|
|
||||||
this.rvnWalletBalance = (Number(res) / 1e8).toFixed(8)
|
|
||||||
store.dispatch(
|
|
||||||
setCoinBalances({
|
|
||||||
type: 'rvn',
|
|
||||||
fullValue: Number(res)
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}).catch(()=> {
|
|
||||||
console.log('error')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateDgbWalletBalance() {
|
|
||||||
let _url = `/crosschain/dgb/walletbalance?apiKey=${this.myNode.apiKey}`
|
|
||||||
let _body = store.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey
|
|
||||||
|
|
||||||
await parentEpml.request('apiCall', {
|
|
||||||
url: _url,
|
|
||||||
method: 'POST',
|
|
||||||
body: _body,
|
|
||||||
}).then((res) => {
|
|
||||||
if (isNaN(Number(res))) {
|
|
||||||
//...
|
|
||||||
} else {
|
|
||||||
this.dgbWalletBalance = (Number(res) / 1e8).toFixed(8)
|
|
||||||
store.dispatch(
|
|
||||||
setCoinBalances({
|
|
||||||
type: 'dgb',
|
|
||||||
fullValue: Number(res)
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}).catch(()=> {
|
|
||||||
console.log('error')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateDogeWalletBalance() {
|
|
||||||
let _url = `/crosschain/doge/walletbalance?apiKey=${this.myNode.apiKey}`
|
|
||||||
let _body = store.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey
|
|
||||||
|
|
||||||
await parentEpml.request('apiCall', {
|
|
||||||
url: _url,
|
|
||||||
method: 'POST',
|
|
||||||
body: _body,
|
|
||||||
}).then((res) => {
|
|
||||||
if (isNaN(Number(res))) {
|
|
||||||
//...
|
|
||||||
} else {
|
|
||||||
this.dogeWalletBalance = (Number(res) / 1e8).toFixed(8)
|
|
||||||
store.dispatch(
|
|
||||||
setCoinBalances({
|
|
||||||
type: 'doge',
|
|
||||||
fullValue: Number(res)
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}).catch(()=> {
|
|
||||||
console.log('error')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateBtcWalletBalance() {
|
|
||||||
let _url = `/crosschain/btc/walletbalance?apiKey=${this.myNode.apiKey}`
|
|
||||||
let _body = store.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey
|
|
||||||
|
|
||||||
await parentEpml.request('apiCall', {
|
|
||||||
url: _url,
|
|
||||||
method: 'POST',
|
|
||||||
body: _body,
|
|
||||||
}).then((res) => {
|
|
||||||
if (isNaN(Number(res))) {
|
|
||||||
//...
|
|
||||||
} else {
|
|
||||||
this.btcWalletBalance = (Number(res) / 1e8).toFixed(8)
|
|
||||||
store.dispatch(
|
|
||||||
setCoinBalances({
|
|
||||||
type: 'btc',
|
|
||||||
fullValue: Number(res)
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}).catch(()=> {
|
|
||||||
console.log('error')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async updateLtcWalletBalance() {
|
|
||||||
let _url = `/crosschain/ltc/walletbalance?apiKey=${this.myNode.apiKey}`
|
|
||||||
let _body = store.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey
|
|
||||||
|
|
||||||
await parentEpml.request('apiCall', {
|
|
||||||
url: _url,
|
|
||||||
method: 'POST',
|
|
||||||
body: _body,
|
|
||||||
}).then((res) => {
|
|
||||||
if (isNaN(Number(res))) {
|
|
||||||
//...
|
|
||||||
} else {
|
|
||||||
this.ltcWalletBalance = (Number(res) / 1e8).toFixed(8)
|
|
||||||
store.dispatch(
|
|
||||||
setCoinBalances({
|
|
||||||
type: 'ltc',
|
|
||||||
fullValue: Number(res)
|
|
||||||
})
|
|
||||||
);
|
|
||||||
|
|
||||||
}
|
|
||||||
}).catch(()=> {
|
|
||||||
console.log('error')
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateCoinList(event) {
|
|
||||||
const copyCoinList = {...this.coinList}
|
|
||||||
const coin = event.detail
|
|
||||||
if(!copyCoinList[coin]){
|
|
||||||
try {
|
|
||||||
if(coin === 'ltc'){
|
|
||||||
this.updateLtcWalletBalance()
|
|
||||||
} else if(coin === 'qort'){
|
|
||||||
this.updateQortWalletBalance()
|
|
||||||
} else if(coin === 'doge'){
|
|
||||||
this.updateDogeWalletBalance()
|
|
||||||
} else if(coin === 'btc'){
|
|
||||||
this.updateBtcWalletBalance()
|
|
||||||
} else if(coin === 'dgb'){
|
|
||||||
this.updateDgbWalletBalance()
|
|
||||||
} else if(coin === 'rvn'){
|
|
||||||
this.updateRvnWalletBalance()
|
|
||||||
}else if(coin === 'arrr'){
|
|
||||||
this.updateArrrWalletBalance()
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
copyCoinList[coin] = Date.now() + 120000;
|
|
||||||
this.coinList = copyCoinList
|
|
||||||
|
|
||||||
this.requestUpdate()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async updateBtcWalletBalance() {
|
||||||
|
let _url = `/crosschain/btc/walletbalance?apiKey=${this.myNode.apiKey}`
|
||||||
|
let _body = store.getState().app.selectedAddress.btcWallet.derivedMasterPublicKey
|
||||||
|
|
||||||
async fetchCoins(arrayOfCoins){
|
await parentEpml.request('apiCall', {
|
||||||
const getCoinBalances = (arrayOfCoins || []).map(
|
url: _url,
|
||||||
async (coin) => {
|
method: 'POST',
|
||||||
if(coin === 'ltc'){
|
body: _body
|
||||||
await this.updateLtcWalletBalance()
|
}).then((res) => {
|
||||||
} else if(coin === 'qort'){
|
if (isNaN(Number(res))) {
|
||||||
await this.updateQortWalletBalance()
|
//...
|
||||||
} else if(coin === 'doge'){
|
} else {
|
||||||
await this.updateDogeWalletBalance()
|
this.btcWalletBalance = (Number(res) / 1e8).toFixed(8)
|
||||||
} else if(coin === 'btc'){
|
store.dispatch(
|
||||||
await this.updateBtcWalletBalance()
|
setCoinBalances({
|
||||||
} else if(coin === 'dgb'){
|
type: 'btc',
|
||||||
await this.updateDgbWalletBalance()
|
fullValue: Number(res)
|
||||||
} else if(coin === 'rvn'){
|
})
|
||||||
await this.updateRvnWalletBalance()
|
)
|
||||||
}else if(coin === 'arrr'){
|
}
|
||||||
await this.updateArrrWalletBalance()
|
}).catch(() => {
|
||||||
}
|
console.log('error')
|
||||||
})
|
})
|
||||||
|
}
|
||||||
|
|
||||||
await Promise.all(getCoinBalances);
|
async updateLtcWalletBalance() {
|
||||||
|
let _url = `/crosschain/ltc/walletbalance?apiKey=${this.myNode.apiKey}`
|
||||||
|
let _body = store.getState().app.selectedAddress.ltcWallet.derivedMasterPublicKey
|
||||||
|
|
||||||
}
|
await parentEpml.request('apiCall', {
|
||||||
|
url: _url,
|
||||||
|
method: 'POST',
|
||||||
|
body: _body
|
||||||
|
}).then((res) => {
|
||||||
|
if (isNaN(Number(res))) {
|
||||||
|
//...
|
||||||
|
} else {
|
||||||
|
this.ltcWalletBalance = (Number(res) / 1e8).toFixed(8)
|
||||||
|
store.dispatch(
|
||||||
|
setCoinBalances({
|
||||||
|
type: 'ltc',
|
||||||
|
fullValue: Number(res)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
async fetchBalance(){
|
}
|
||||||
try {
|
}).catch(() => {
|
||||||
let arrayOfCoins = []
|
console.log('error')
|
||||||
const copyObject = {...this.coinList}
|
})
|
||||||
const currentDate = Date.now()
|
}
|
||||||
const array = Object.keys(this.coinList)
|
|
||||||
for (const key of array) {
|
|
||||||
const item = this.coinList[key]
|
|
||||||
|
|
||||||
if(item < currentDate){
|
async updateDogeWalletBalance() {
|
||||||
delete copyObject[key]
|
let _url = `/crosschain/doge/walletbalance?apiKey=${this.myNode.apiKey}`
|
||||||
} else {
|
let _body = store.getState().app.selectedAddress.dogeWallet.derivedMasterPublicKey
|
||||||
arrayOfCoins.push(key)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(!this.stop){
|
|
||||||
this.stop = true
|
|
||||||
await this.fetchCoins(arrayOfCoins)
|
|
||||||
this.stop = false
|
|
||||||
}
|
|
||||||
this.coinList = copyObject
|
|
||||||
} catch (error) {
|
|
||||||
this.stop = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
connectedCallback() {
|
await parentEpml.request('apiCall', {
|
||||||
super.connectedCallback();
|
url: _url,
|
||||||
this.intervalID = setInterval(this.fetchBalance, 45000);
|
method: 'POST',
|
||||||
window.addEventListener(
|
body: _body
|
||||||
'ping-coin-controller-with-coin',
|
}).then((res) => {
|
||||||
this._updateCoinList
|
if (isNaN(Number(res))) {
|
||||||
);
|
//...
|
||||||
|
} else {
|
||||||
|
this.dogeWalletBalance = (Number(res) / 1e8).toFixed(8)
|
||||||
|
store.dispatch(
|
||||||
|
setCoinBalances({
|
||||||
|
type: 'doge',
|
||||||
|
fullValue: Number(res)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
console.log('error')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateDgbWalletBalance() {
|
||||||
|
let _url = `/crosschain/dgb/walletbalance?apiKey=${this.myNode.apiKey}`
|
||||||
|
let _body = store.getState().app.selectedAddress.dgbWallet.derivedMasterPublicKey
|
||||||
|
|
||||||
|
await parentEpml.request('apiCall', {
|
||||||
|
url: _url,
|
||||||
|
method: 'POST',
|
||||||
|
body: _body
|
||||||
|
}).then((res) => {
|
||||||
|
if (isNaN(Number(res))) {
|
||||||
|
//...
|
||||||
|
} else {
|
||||||
|
this.dgbWalletBalance = (Number(res) / 1e8).toFixed(8)
|
||||||
|
store.dispatch(
|
||||||
|
setCoinBalances({
|
||||||
|
type: 'dgb',
|
||||||
|
fullValue: Number(res)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
console.log('error')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateRvnWalletBalance() {
|
||||||
|
let _url = `/crosschain/rvn/walletbalance?apiKey=${this.myNode.apiKey}`
|
||||||
|
let _body = store.getState().app.selectedAddress.rvnWallet.derivedMasterPublicKey
|
||||||
|
|
||||||
|
await parentEpml.request('apiCall', {
|
||||||
|
url: _url,
|
||||||
|
method: 'POST',
|
||||||
|
body: _body
|
||||||
|
}).then((res) => {
|
||||||
|
if (isNaN(Number(res))) {
|
||||||
|
//...
|
||||||
|
} else {
|
||||||
|
this.rvnWalletBalance = (Number(res) / 1e8).toFixed(8)
|
||||||
|
store.dispatch(
|
||||||
|
setCoinBalances({
|
||||||
|
type: 'rvn',
|
||||||
|
fullValue: Number(res)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
console.log('error')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async updateArrrWalletBalance() {
|
||||||
|
let _url = `/crosschain/arrr/walletbalance?apiKey=${this.myNode.apiKey}`
|
||||||
|
let _body = store.getState().app.selectedAddress.arrrWallet.seed58
|
||||||
|
|
||||||
|
await parentEpml.request('apiCall', {
|
||||||
|
url: _url,
|
||||||
|
method: 'POST',
|
||||||
|
body: _body,
|
||||||
|
}).then((res) => {
|
||||||
|
if (isNaN(Number(res))) {
|
||||||
|
//...
|
||||||
|
} else {
|
||||||
|
this.arrrWalletBalance = (Number(res) / 1e8).toFixed(8)
|
||||||
|
store.dispatch(
|
||||||
|
setCoinBalances({
|
||||||
|
type: 'arrr',
|
||||||
|
fullValue: Number(res)
|
||||||
|
})
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}).catch(() => {
|
||||||
|
console.log('error')
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
_updateCoinList(event) {
|
||||||
|
const copyCoinList = { ...this.coinList }
|
||||||
|
const coin = event.detail
|
||||||
|
|
||||||
|
if (!copyCoinList[coin]) {
|
||||||
|
try {
|
||||||
|
if (coin === 'qort') {
|
||||||
|
this.updateQortWalletBalance()
|
||||||
|
} else if (coin === 'btc') {
|
||||||
|
this.updateBtcWalletBalance()
|
||||||
|
} else if (coin === 'ltc') {
|
||||||
|
this.updateLtcWalletBalance()
|
||||||
|
} else if (coin === 'doge') {
|
||||||
|
this.updateDogeWalletBalance()
|
||||||
|
} else if (coin === 'dgb') {
|
||||||
|
this.updateDgbWalletBalance()
|
||||||
|
} else if (coin === 'rvn') {
|
||||||
|
this.updateRvnWalletBalance()
|
||||||
|
} else if (coin === 'arrr') {
|
||||||
|
this.updateArrrWalletBalance()
|
||||||
|
}
|
||||||
|
} catch (error) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
copyCoinList[coin] = Date.now() + 120000
|
||||||
|
|
||||||
|
this.coinList = copyCoinList
|
||||||
|
this.requestUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchCoins(arrayOfCoins) {
|
||||||
|
const getCoinBalances = (arrayOfCoins || []).map(async (coin) => {
|
||||||
|
if (coin === 'qort') {
|
||||||
|
await this.updateQortWalletBalance()
|
||||||
|
} else if (coin === 'btc') {
|
||||||
|
await this.updateBtcWalletBalance()
|
||||||
|
} else if (coin === 'ltc') {
|
||||||
|
await this.updateLtcWalletBalance()
|
||||||
|
} else if (coin === 'doge') {
|
||||||
|
await this.updateDogeWalletBalance()
|
||||||
|
} else if (coin === 'dgb') {
|
||||||
|
await this.updateDgbWalletBalance()
|
||||||
|
} else if (coin === 'rvn') {
|
||||||
|
await this.updateRvnWalletBalance()
|
||||||
|
} else if (coin === 'arrr') {
|
||||||
|
await this.updateArrrWalletBalance()
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
await Promise.all(getCoinBalances)
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchBalance() {
|
||||||
|
try {
|
||||||
|
let arrayOfCoins = []
|
||||||
|
|
||||||
|
const copyObject = { ...this.coinList }
|
||||||
|
const currentDate = Date.now()
|
||||||
|
const array = Object.keys(this.coinList)
|
||||||
|
|
||||||
|
for (const key of array) {
|
||||||
|
const item = this.coinList[key]
|
||||||
|
|
||||||
|
if (item < currentDate) {
|
||||||
|
delete copyObject[key]
|
||||||
|
} else {
|
||||||
|
arrayOfCoins.push(key)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!this.stop) {
|
||||||
|
this.stop = true
|
||||||
|
|
||||||
|
await this.fetchCoins(arrayOfCoins)
|
||||||
|
|
||||||
|
this.stop = false
|
||||||
|
}
|
||||||
|
|
||||||
|
this.coinList = copyObject
|
||||||
|
} catch (error) {
|
||||||
|
this.stop = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
connectedCallback() {
|
||||||
|
super.connectedCallback()
|
||||||
|
this.intervalID = setInterval(this.fetchBalance, 45000)
|
||||||
|
window.addEventListener('ping-coin-controller-with-coin', this._updateCoinList)
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
|
if (this.intervalID) { clearInterval(this.intervalID) }
|
||||||
super.disconnectedCallback();
|
window.removeEventListener('ping-coin-controller-with-coin', this._updateCoinList)
|
||||||
window.removeEventListener(
|
super.disconnectedCallback()
|
||||||
'ping-coin-controller-with-coin',
|
|
||||||
this._updateCoinList
|
|
||||||
);
|
|
||||||
if(this.intervalID){
|
|
||||||
clearInterval(this.intervalID);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return html``;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('coin-balances-controller', CoinBalancesController);
|
window.customElements.define('coin-balances-controller', CoinBalancesController)
|
@ -1,221 +1,204 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {get} from '../../../translate'
|
import { connect } from 'pwa-helpers'
|
||||||
import '@material/mwc-icon'
|
import { store } from '../../store'
|
||||||
import '@vaadin/tooltip';
|
import { get } from '../../../translate'
|
||||||
|
import { chatSideNavHeadsStyles } from '../../styles/core-css'
|
||||||
import './friend-item-actions'
|
import './friend-item-actions'
|
||||||
|
import '@material/mwc-icon'
|
||||||
|
import '@vaadin/tooltip'
|
||||||
|
|
||||||
class ChatSideNavHeads extends LitElement {
|
class ChatSideNavHeads extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
selectedAddress: { type: Object },
|
selectedAddress: { type: Object },
|
||||||
config: { type: Object },
|
config: { type: Object },
|
||||||
chatInfo: { type: Object },
|
chatInfo: { type: Object },
|
||||||
iconName: { type: String },
|
iconName: { type: String },
|
||||||
activeChatHeadUrl: { type: String },
|
activeChatHeadUrl: { type: String },
|
||||||
isImageLoaded: { type: Boolean },
|
isImageLoaded: { type: Boolean },
|
||||||
setActiveChatHeadUrl: {attribute: false},
|
setActiveChatHeadUrl: { attribute: false },
|
||||||
openEditFriend: {attribute: false},
|
openEditFriend: { attribute: false },
|
||||||
closeSidePanel: {attribute: false, type: Object}
|
closeSidePanel: { attribute: false, type: Object }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return css`
|
return [chatSideNavHeadsStyles]
|
||||||
:host {
|
}
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
padding: 10px 2px 10px 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
box-sizing: border-box;
|
|
||||||
font-size: 14px;
|
|
||||||
transition: 0.2s background-color;
|
|
||||||
}
|
|
||||||
|
|
||||||
li:hover {
|
constructor() {
|
||||||
background-color: var(--lightChatHeadHover);
|
super()
|
||||||
}
|
this.selectedAddress = {}
|
||||||
|
this.config = {
|
||||||
.active {
|
user: {
|
||||||
background: var(--menuactive);
|
node: {
|
||||||
border-left: 4px solid #3498db;
|
|
||||||
}
|
|
||||||
|
|
||||||
.img-icon {
|
|
||||||
font-size:40px;
|
|
||||||
color: var(--chat-group);
|
|
||||||
}
|
|
||||||
|
|
||||||
.status {
|
|
||||||
color: #92959e;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clearfix {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.clearfix:after {
|
|
||||||
visibility: hidden;
|
|
||||||
display: block;
|
|
||||||
font-size: 0;
|
|
||||||
content: " ";
|
|
||||||
clear: both;
|
|
||||||
height: 0;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
this.selectedAddress = {}
|
|
||||||
this.config = {
|
|
||||||
user: {
|
|
||||||
node: {
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.chatInfo = {}
|
|
||||||
this.iconName = ''
|
|
||||||
this.activeChatHeadUrl = ''
|
|
||||||
this.isImageLoaded = false
|
|
||||||
this.imageFetches = 0
|
|
||||||
}
|
|
||||||
|
|
||||||
createImage(imageUrl) {
|
|
||||||
const imageHTMLRes = new Image();
|
|
||||||
imageHTMLRes.src = imageUrl;
|
|
||||||
imageHTMLRes.style= "width:30px; height:30px; float: left; border-radius:50%; font-size:14px";
|
|
||||||
imageHTMLRes.onclick= () => {
|
|
||||||
this.openDialogImage = true;
|
|
||||||
}
|
|
||||||
imageHTMLRes.onload = () => {
|
|
||||||
this.isImageLoaded = true;
|
|
||||||
}
|
|
||||||
imageHTMLRes.onerror = () => {
|
|
||||||
if (this.imageFetches < 4) {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.imageFetches = this.imageFetches + 1;
|
|
||||||
imageHTMLRes.src = imageUrl;
|
|
||||||
}, 500);
|
|
||||||
} else {
|
|
||||||
this.isImageLoaded = false
|
|
||||||
}
|
|
||||||
};
|
|
||||||
return imageHTMLRes;
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let avatarImg = ""
|
|
||||||
if (this.chatInfo.name) {
|
|
||||||
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node];
|
|
||||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
|
|
||||||
const avatarUrl = `${nodeUrl}/arbitrary/THUMBNAIL/${this.chatInfo.name}/qortal_avatar?async=true&apiKey=${myNode.apiKey}`;
|
|
||||||
avatarImg = this.createImage(avatarUrl)
|
|
||||||
}
|
|
||||||
|
|
||||||
return html`
|
|
||||||
<li style="display:flex; justify-content: space-between; align-items: center" @click=${(e) => {
|
|
||||||
const target = e.target
|
|
||||||
const popover =
|
|
||||||
this.shadowRoot.querySelector('friend-item-actions');
|
|
||||||
if (popover) {
|
|
||||||
popover.openPopover(target);
|
|
||||||
}
|
}
|
||||||
}} class="clearfix" id=${`friend-item-parent-${this.chatInfo.name}`}>
|
}
|
||||||
<div style="display:flex; flex-grow: 1; align-items: center">
|
}
|
||||||
${this.isImageLoaded ? html`${avatarImg}` : html``}
|
this.chatInfo = {}
|
||||||
${!this.isImageLoaded && !this.chatInfo.name && !this.chatInfo.groupName
|
this.iconName = ''
|
||||||
? html`<mwc-icon class="img-icon">account_circle</mwc-icon>`
|
this.activeChatHeadUrl = ''
|
||||||
: html``}
|
this.isImageLoaded = false
|
||||||
${!this.isImageLoaded && this.chatInfo.name
|
this.imageFetches = 0
|
||||||
? html`<div
|
}
|
||||||
style="width:30px; height:30px; float: left; border-radius:50%; background: ${this.activeChatHeadUrl === this.chatInfo.url
|
|
||||||
? "var(--chatHeadBgActive)"
|
|
||||||
: "var(--chatHeadBg)"}; color: ${this.activeChatHeadUrl ===
|
|
||||||
this.chatInfo.url
|
|
||||||
? "var(--chatHeadTextActive)"
|
|
||||||
: "var(--chatHeadText)"}; font-weight:bold; display: flex; justify-content: center; align-items: center; text-transform: capitalize"
|
|
||||||
>
|
|
||||||
${this.chatInfo.name.charAt(0)}
|
|
||||||
</div>`
|
|
||||||
: ""}
|
|
||||||
${!this.isImageLoaded && this.chatInfo.groupName
|
|
||||||
? html`<div
|
|
||||||
style="width:30px; height:30px; float: left; border-radius:50%; background: ${this.activeChatHeadUrl === this.chatInfo.url
|
|
||||||
? "var(--chatHeadBgActive)"
|
|
||||||
: "var(--chatHeadBg)"}; color: ${this.activeChatHeadUrl === this.chatInfo.url
|
|
||||||
? "var(--chatHeadTextActive)"
|
|
||||||
: "var(--chatHeadText)"}; font-weight:bold; display: flex; justify-content: center; align-items: center; text-transform: capitalize"
|
|
||||||
>
|
|
||||||
${this.chatInfo.groupName.charAt(0)}
|
|
||||||
</div>`
|
|
||||||
: ""}
|
|
||||||
<div>
|
|
||||||
<div class="name">
|
|
||||||
<span style="float:left; padding-left: 8px; color: var(--chat-group);">
|
|
||||||
${this.chatInfo.groupName
|
|
||||||
? this.chatInfo.groupName
|
|
||||||
: this.chatInfo.name !== undefined
|
|
||||||
? (this.chatInfo.alias || this.chatInfo.name)
|
|
||||||
: this.chatInfo.address.substr(0, 15)}
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
</div>
|
render() {
|
||||||
<div style="display:flex; align-items: center">
|
let avatarImg = ''
|
||||||
${this.chatInfo.willFollow ? html`
|
|
||||||
<mwc-icon id="willFollowIcon" style="color: var(--black)">connect_without_contact</mwc-icon>
|
|
||||||
<vaadin-tooltip
|
|
||||||
|
|
||||||
for="willFollowIcon"
|
if (this.chatInfo.name) {
|
||||||
position="top"
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
hover-delay=${200}
|
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
hide-delay=${1}
|
const avatarUrl = `${nodeUrl}/arbitrary/THUMBNAIL/${this.chatInfo.name}/qortal_avatar?async=true`
|
||||||
text=${get('friends.friend11')}>
|
avatarImg = this.createImage(avatarUrl)
|
||||||
</vaadin-tooltip>
|
}
|
||||||
` : ''}
|
|
||||||
</div>
|
|
||||||
</li>
|
|
||||||
<friend-item-actions
|
|
||||||
for=${`friend-item-parent-${this.chatInfo.name}`}
|
|
||||||
message=${get('notifications.explanation')}
|
|
||||||
.openEditFriend=${()=> {
|
|
||||||
this.openEditFriend(this.chatInfo)
|
|
||||||
}}
|
|
||||||
name=${this.chatInfo.name}
|
|
||||||
.closeSidePanel=${this.closeSidePanel}
|
|
||||||
></friend-item-actions>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<li
|
||||||
|
style="display:flex; justify-content: space-between; align-items: center"
|
||||||
|
@click=${(e) => {
|
||||||
|
const target = e.target
|
||||||
|
const popover = this.shadowRoot.querySelector('friend-item-actions');
|
||||||
|
if (popover) {
|
||||||
|
popover.openPopover(target);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
class="clearfix" id=${`friend-item-parent-${this.chatInfo.name}`}
|
||||||
|
>
|
||||||
|
<div style="display:flex; flex-grow: 1; align-items: center">
|
||||||
|
${this.isImageLoaded ? html`${avatarImg}` : html``}
|
||||||
|
${!this.isImageLoaded && !this.chatInfo.name && !this.chatInfo.groupName ?
|
||||||
|
html`
|
||||||
|
<mwc-icon class="img-icon">account_circle</mwc-icon>
|
||||||
|
`
|
||||||
|
: html``
|
||||||
|
}
|
||||||
|
${!this.isImageLoaded && this.chatInfo.name ?
|
||||||
|
html`
|
||||||
|
<div
|
||||||
|
style="width:30px; height:30px; float: left; border-radius:50%; background: ${this.activeChatHeadUrl === this.chatInfo.url
|
||||||
|
? "var(--chatHeadBgActive)"
|
||||||
|
: "var(--chatHeadBg)"}; color: ${this.activeChatHeadUrl === this.chatInfo.url
|
||||||
|
? "var(--chatHeadTextActive)"
|
||||||
|
: "var(--chatHeadText)"}; font-weight:bold; display: flex; justify-content: center; align-items: center; text-transform: capitalize"
|
||||||
|
>
|
||||||
|
${this.chatInfo.name.charAt(0)}
|
||||||
|
</div>
|
||||||
|
` : ''
|
||||||
|
}
|
||||||
|
${!this.isImageLoaded && this.chatInfo.groupName ?
|
||||||
|
html`
|
||||||
|
<div
|
||||||
|
style="width:30px; height:30px; float: left; border-radius:50%; background: ${this.activeChatHeadUrl === this.chatInfo.url
|
||||||
|
? "var(--chatHeadBgActive)"
|
||||||
|
: "var(--chatHeadBg)"}; color: ${this.activeChatHeadUrl === this.chatInfo.url
|
||||||
|
? "var(--chatHeadTextActive)"
|
||||||
|
: "var(--chatHeadText)"}; font-weight:bold; display: flex; justify-content: center; align-items: center; text-transform: capitalize"
|
||||||
|
>
|
||||||
|
${this.chatInfo.groupName.charAt(0)}
|
||||||
|
</div>
|
||||||
|
` : ''
|
||||||
|
}
|
||||||
|
<div>
|
||||||
|
<div class="name">
|
||||||
|
<span style="float:left; padding-left: 8px; color: var(--chat-group);">
|
||||||
|
${this.chatInfo.groupName
|
||||||
|
? this.chatInfo.groupName
|
||||||
|
: this.chatInfo.name !== undefined
|
||||||
|
? (this.chatInfo.alias || this.chatInfo.name)
|
||||||
|
: this.chatInfo.address.substr(0, 15)
|
||||||
|
}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="display:flex; align-items: center">
|
||||||
|
${this.chatInfo.willFollow ?
|
||||||
|
html`
|
||||||
|
<mwc-icon id="willFollowIcon" style="color: var(--black)">connect_without_contact</mwc-icon>
|
||||||
|
<vaadin-tooltip
|
||||||
|
for="willFollowIcon"
|
||||||
|
position="top"
|
||||||
|
hover-delay=${200}
|
||||||
|
hide-delay=${1}
|
||||||
|
text=${get('friends.friend11')}
|
||||||
|
></vaadin-tooltip>
|
||||||
|
` : ''
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</li>
|
||||||
|
<friend-item-actions
|
||||||
|
for=${`friend-item-parent-${this.chatInfo.name}`}
|
||||||
|
message=${get('notifications.explanation')}
|
||||||
|
.openEditFriend=${() => {
|
||||||
|
this.openEditFriend(this.chatInfo)
|
||||||
|
}}
|
||||||
|
name=${this.chatInfo.name}
|
||||||
|
.closeSidePanel=${this.closeSidePanel}
|
||||||
|
></friend-item-actions>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated() {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
shouldUpdate(changedProperties) {
|
createImage(imageUrl) {
|
||||||
if(changedProperties.has('activeChatHeadUrl')){
|
const imageHTMLRes = new Image()
|
||||||
return true
|
imageHTMLRes.src = imageUrl
|
||||||
}
|
imageHTMLRes.style = "width:30px; height:30px; float: left; border-radius:50%; font-size:14px"
|
||||||
if(changedProperties.has('chatInfo')){
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
return !!changedProperties.has('isImageLoaded');
|
|
||||||
|
|
||||||
|
imageHTMLRes.onclick = () => {
|
||||||
|
this.openDialogImage = true
|
||||||
|
}
|
||||||
|
|
||||||
}
|
imageHTMLRes.onload = () => {
|
||||||
|
this.isImageLoaded = true
|
||||||
|
}
|
||||||
|
|
||||||
getUrl(chatUrl) {
|
imageHTMLRes.onerror = () => {
|
||||||
this.setActiveChatHeadUrl(chatUrl)
|
if (this.imageFetches < 4) {
|
||||||
}
|
setTimeout(() => {
|
||||||
|
this.imageFetches = this.imageFetches + 1
|
||||||
|
imageHTMLRes.src = imageUrl
|
||||||
|
}, 500)
|
||||||
|
} else {
|
||||||
|
this.isImageLoaded = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return imageHTMLRes
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldUpdate(changedProperties) {
|
||||||
|
if (changedProperties.has('activeChatHeadUrl')) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
if (changedProperties.has('chatInfo')) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
return !!changedProperties.has('isImageLoaded')
|
||||||
|
}
|
||||||
|
|
||||||
|
getUrl(chatUrl) {
|
||||||
|
this.setActiveChatHeadUrl(chatUrl)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Standard functions
|
||||||
|
getApiKey() {
|
||||||
|
const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
return coreNode.apiKey
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmptyArray(arr) {
|
||||||
|
if (!arr) { return true }
|
||||||
|
return arr.length === 0
|
||||||
|
}
|
||||||
|
|
||||||
|
round(number) {
|
||||||
|
return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('chat-side-nav-heads', ChatSideNavHeads)
|
window.customElements.define('chat-side-nav-heads', ChatSideNavHeads)
|
@ -1,10 +1,11 @@
|
|||||||
import {css, html, LitElement} from 'lit';
|
import { html, LitElement } from 'lit'
|
||||||
import {translate,} from '../../../translate'
|
import { connect } from 'pwa-helpers'
|
||||||
import '@material/mwc-button';
|
import { store } from '../../store'
|
||||||
import '@material/mwc-dialog';
|
import { translate, } from '../../../translate'
|
||||||
import '@material/mwc-checkbox';
|
import { addFriendsModalStyles } from '../../styles/core-css'
|
||||||
import {connect} from 'pwa-helpers';
|
import '@material/mwc-button'
|
||||||
import {store} from '../../store';
|
import '@material/mwc-checkbox'
|
||||||
|
import '@material/mwc-dialog'
|
||||||
import '@polymer/paper-spinner/paper-spinner-lite.js'
|
import '@polymer/paper-spinner/paper-spinner-lite.js'
|
||||||
|
|
||||||
class AddFriendsModal extends connect(store)(LitElement) {
|
class AddFriendsModal extends connect(store)(LitElement) {
|
||||||
@ -21,199 +22,195 @@ class AddFriendsModal extends connect(store)(LitElement) {
|
|||||||
editContent: { type: Object },
|
editContent: { type: Object },
|
||||||
onClose: { attribute: false },
|
onClose: { attribute: false },
|
||||||
mySelectedFeeds: { type: Array },
|
mySelectedFeeds: { type: Array },
|
||||||
availableFeeedSchemas: {type: Array},
|
availableFeeedSchemas: { type: Array },
|
||||||
isLoadingSchemas: {type: Boolean}
|
isLoadingSchemas: { type: Boolean }
|
||||||
};
|
}
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.isOpen = false;
|
|
||||||
this.isLoading = false;
|
|
||||||
this.alias = '';
|
|
||||||
this.willFollow = true;
|
|
||||||
this.notes = '';
|
|
||||||
this.nodeUrl = this.getNodeUrl();
|
|
||||||
this.myNode = this.getMyNode();
|
|
||||||
this.mySelectedFeeds = [];
|
|
||||||
this.availableFeeedSchemas = [];
|
|
||||||
this.isLoadingSchemas= false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return css`
|
return [addFriendsModalStyles]
|
||||||
* {
|
|
||||||
--mdc-theme-primary: rgb(3, 169, 244);
|
|
||||||
--mdc-theme-secondary: var(--mdc-theme-primary);
|
|
||||||
--mdc-theme-surface: var(--white);
|
|
||||||
--mdc-dialog-content-ink-color: var(--black);
|
|
||||||
--mdc-dialog-min-width: 400px;
|
|
||||||
--mdc-dialog-max-width: 1024px;
|
|
||||||
box-sizing:border-box;
|
|
||||||
}
|
|
||||||
.input {
|
|
||||||
width: 90%;
|
|
||||||
outline: 0;
|
|
||||||
border-width: 0 0 2px;
|
|
||||||
border-color: var(--mdc-theme-primary);
|
|
||||||
background-color: transparent;
|
|
||||||
padding: 10px;
|
|
||||||
font-family: Roboto, sans-serif;
|
|
||||||
font-size: 15px;
|
|
||||||
color: var(--chat-bubble-msg-color);
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input::selection {
|
|
||||||
background-color: var(--mdc-theme-primary);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.input::placeholder {
|
|
||||||
opacity: 0.6;
|
|
||||||
color: var(--black);
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-button {
|
|
||||||
font-family: Roboto, sans-serif;
|
|
||||||
font-size: 16px;
|
|
||||||
color: var(--mdc-theme-primary);
|
|
||||||
background-color: transparent;
|
|
||||||
padding: 8px 10px;
|
|
||||||
border-radius: 5px;
|
|
||||||
border: none;
|
|
||||||
transition: all 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-button-red {
|
|
||||||
font-family: Roboto, sans-serif;
|
|
||||||
font-size: 16px;
|
|
||||||
color: #f44336;
|
|
||||||
background-color: transparent;
|
|
||||||
padding: 8px 10px;
|
|
||||||
border-radius: 5px;
|
|
||||||
border: none;
|
|
||||||
transition: all 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-button-red:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: #f4433663;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-button:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: #03a8f475;
|
|
||||||
}
|
|
||||||
.checkbox-row {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
align-content: center;
|
|
||||||
font-family: Montserrat, sans-serif;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--black);
|
|
||||||
}
|
|
||||||
.modal-overlay {
|
|
||||||
display: block;
|
|
||||||
position: fixed;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
width: 100vw;
|
|
||||||
height: 100vh;
|
|
||||||
background-color: rgba(
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0,
|
|
||||||
0.5
|
|
||||||
); /* Semi-transparent backdrop */
|
|
||||||
z-index: 1000;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-content {
|
|
||||||
position: fixed;
|
|
||||||
top: 50vh;
|
|
||||||
left: 50vw;
|
|
||||||
transform: translate(-50%, -50%);
|
|
||||||
background-color: var(--mdc-theme-surface);
|
|
||||||
width: 80vw;
|
|
||||||
max-width: 600px;
|
|
||||||
padding: 20px;
|
|
||||||
box-shadow: rgba(0, 0, 0, 0.1) 0px 4px 6px;
|
|
||||||
z-index: 1001;
|
|
||||||
border-radius: 5px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction:column;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.modal-overlay.hidden {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.avatar {
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-name {
|
|
||||||
display: flex;
|
|
||||||
gap: 20px;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
cursor: pointer;
|
|
||||||
padding: 5px;
|
|
||||||
border-radius: 5px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.inner-content {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
max-height: 75vh;
|
|
||||||
flex-grow: 1;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inner-content::-webkit-scrollbar-track {
|
|
||||||
background-color: whitesmoke;
|
|
||||||
border-radius: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inner-content::-webkit-scrollbar {
|
|
||||||
width: 12px;
|
|
||||||
border-radius: 7px;
|
|
||||||
background-color: whitesmoke;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inner-content::-webkit-scrollbar-thumb {
|
|
||||||
background-color: rgb(180, 176, 176);
|
|
||||||
border-radius: 7px;
|
|
||||||
transition: all 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated() {}
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.isOpen = false
|
||||||
|
this.isLoading = false
|
||||||
|
this.alias = ''
|
||||||
|
this.willFollow = true
|
||||||
|
this.notes = ''
|
||||||
|
this.nodeUrl = this.getNodeUrl()
|
||||||
|
this.myNode = this.getMyNode()
|
||||||
|
this.mySelectedFeeds = []
|
||||||
|
this.availableFeeedSchemas = []
|
||||||
|
this.isLoadingSchemas = false
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<div class="modal-overlay ${this.isOpen ? '' : 'hidden'}">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="inner-content">
|
||||||
|
<div style="text-align:center">
|
||||||
|
<h1>
|
||||||
|
${this.editContent
|
||||||
|
? translate('friends.friend10')
|
||||||
|
: translate('friends.friend2')}
|
||||||
|
</h1>
|
||||||
|
<hr />
|
||||||
|
</div>
|
||||||
|
<p>${translate('friends.friend3')}</p>
|
||||||
|
<div class="checkbox-row">
|
||||||
|
<label
|
||||||
|
for="willFollow"
|
||||||
|
id="willFollowLabel"
|
||||||
|
style="color: var(--black);"
|
||||||
|
>
|
||||||
|
${translate('friends.friend5')}
|
||||||
|
</label>
|
||||||
|
<mwc-checkbox
|
||||||
|
style="margin-right: -15px;"
|
||||||
|
id="willFollow"
|
||||||
|
@change=${(e) => {
|
||||||
|
this.willFollow = e.target.checked;
|
||||||
|
}}
|
||||||
|
?checked=${this.willFollow}
|
||||||
|
></mwc-checkbox>
|
||||||
|
</div>
|
||||||
|
<div style="height:15px"></div>
|
||||||
|
<div style="display: flex;flex-direction: column;">
|
||||||
|
<label
|
||||||
|
for="name"
|
||||||
|
id="nameLabel"
|
||||||
|
style="color: var(--black);"
|
||||||
|
>
|
||||||
|
${translate('login.name')}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="name"
|
||||||
|
class="input"
|
||||||
|
?disabled=${true}
|
||||||
|
value=${this.userSelected ? this.userSelected.name : ''}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style="height:15px"></div>
|
||||||
|
<div style="display: flex;flex-direction: column;">
|
||||||
|
<label
|
||||||
|
for="alias"
|
||||||
|
id="aliasLabel"
|
||||||
|
style="color: var(--black);"
|
||||||
|
>
|
||||||
|
${translate('friends.friend6')}
|
||||||
|
</label>
|
||||||
|
<input
|
||||||
|
id="alias"
|
||||||
|
placeholder=${translate('friends.friend7')}
|
||||||
|
class="input"
|
||||||
|
.value=${this.alias}
|
||||||
|
@change=${(e) => {
|
||||||
|
this.alias = e.target.value
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div style="height:15px"></div>
|
||||||
|
<div style="margin-bottom:0;">
|
||||||
|
<textarea
|
||||||
|
class="input"
|
||||||
|
@change=${(e) => {
|
||||||
|
this.notes = e.target.value
|
||||||
|
}}
|
||||||
|
.value=${this.notes}
|
||||||
|
?disabled=${this.isLoading}
|
||||||
|
id="messageBoxAddFriend"
|
||||||
|
placeholder="${translate('friends.friend4')}"
|
||||||
|
rows="3"
|
||||||
|
></textarea>
|
||||||
|
</div>
|
||||||
|
<div style="height:15px"></div>
|
||||||
|
<h2>${translate('friends.friend15')}</h2>
|
||||||
|
<div style="margin-bottom:0;">
|
||||||
|
<p>${translate('friends.friend16')}</p>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
${this.isLoadingSchemas ?
|
||||||
|
html`
|
||||||
|
<div style="width:100%;display: flex; justify-content:center">
|
||||||
|
<paper-spinner-lite active></paper-spinner-lite>
|
||||||
|
</div>
|
||||||
|
` : ''
|
||||||
|
}
|
||||||
|
${this.availableFeeedSchemas.map((schema) => {
|
||||||
|
const isAlreadySelected = this.mySelectedFeeds.find((item) => item.name === schema.name);
|
||||||
|
let avatarImgApp;
|
||||||
|
const avatarUrl2 = `${this.nodeUrl}/arbitrary/THUMBNAIL/${schema.name}/qortal_avatar?async=true&apiKey=${this.myNode.apiKey}`;
|
||||||
|
avatarImgApp = html`<img src="${avatarUrl2}" style="max-width:100%; max-height:100%;" onerror="this.onerror=null; this.src='/img/incognito.png';"/>`;
|
||||||
|
return html`
|
||||||
|
<div
|
||||||
|
class="app-name"
|
||||||
|
style="background:${isAlreadySelected ? 'lightblue' : ''}"
|
||||||
|
@click=${() => {
|
||||||
|
const copymySelectedFeeds = [...this.mySelectedFeeds];
|
||||||
|
const findIndex = copymySelectedFeeds.findIndex((item) => item.name === schema.name);
|
||||||
|
if (findIndex === -1) {
|
||||||
|
if (this.mySelectedFeeds.length > 4) return
|
||||||
|
copymySelectedFeeds.push({name: schema.name, identifier: schema.identifier, service: schema.service});
|
||||||
|
this.mySelectedFeeds = copymySelectedFeeds;
|
||||||
|
} else {
|
||||||
|
this.mySelectedFeeds = copymySelectedFeeds.filter((item) => item.name !== schema.name);
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div class="avatar">${avatarImgApp}</div>
|
||||||
|
<span style="color:${isAlreadySelected ? 'var(--white)' : 'var(--black)'};font-size:16px">${schema.name}</span>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div style="display:flex;justify-content:space-between;align-items:center;margin-top:20px">
|
||||||
|
<button
|
||||||
|
class="modal-button-red"
|
||||||
|
?disabled="${this.isLoading}"
|
||||||
|
@click="${() => {
|
||||||
|
this.setIsOpen(false);
|
||||||
|
this.clearFields();
|
||||||
|
this.onClose();
|
||||||
|
}}"
|
||||||
|
>
|
||||||
|
${translate('general.close')}
|
||||||
|
</button>
|
||||||
|
${this.editContent ?
|
||||||
|
html`
|
||||||
|
<button ?disabled="${this.isLoading}" class="modal-button-red" @click=${() => {this.removeFriend();}}>
|
||||||
|
${translate('friends.friend14')}
|
||||||
|
</button>
|
||||||
|
` : ''
|
||||||
|
}
|
||||||
|
<button ?disabled="${this.isLoading}" class="modal-button" @click=${() => {this.addFriend();}}>
|
||||||
|
${this.editContent ? translate('friends.friend10') : translate('friends.friend2')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated() {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
getNodeUrl() {
|
getNodeUrl() {
|
||||||
const myNode =
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
store.getState().app.nodeConfig.knownNodes[
|
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
];
|
|
||||||
|
|
||||||
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getMyNode() {
|
getMyNode() {
|
||||||
return store.getState().app.nodeConfig.knownNodes[
|
return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
clearFields() {
|
clearFields() {
|
||||||
this.alias = '';
|
this.alias = ''
|
||||||
this.willFollow = true;
|
this.willFollow = true
|
||||||
this.notes = '';
|
this.notes = ''
|
||||||
}
|
}
|
||||||
|
|
||||||
addFriend() {
|
addFriend() {
|
||||||
@ -223,10 +220,10 @@ class AddFriendsModal extends connect(store)(LitElement) {
|
|||||||
notes: this.notes,
|
notes: this.notes,
|
||||||
willFollow: this.willFollow,
|
willFollow: this.willFollow,
|
||||||
mySelectedFeeds: this.mySelectedFeeds
|
mySelectedFeeds: this.mySelectedFeeds
|
||||||
|
})
|
||||||
|
|
||||||
});
|
this.clearFields()
|
||||||
this.clearFields();
|
this.onClose()
|
||||||
this.onClose();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
removeFriend() {
|
removeFriend() {
|
||||||
@ -239,244 +236,60 @@ class AddFriendsModal extends connect(store)(LitElement) {
|
|||||||
mySelectedFeeds: this.mySelectedFeeds
|
mySelectedFeeds: this.mySelectedFeeds
|
||||||
},
|
},
|
||||||
true
|
true
|
||||||
);
|
)
|
||||||
this.clearFields();
|
|
||||||
this.onClose();
|
this.clearFields()
|
||||||
|
this.onClose()
|
||||||
}
|
}
|
||||||
|
|
||||||
async updated(changedProperties) {
|
async updated(changedProperties) {
|
||||||
if (
|
if (changedProperties && changedProperties.has('editContent') && this.editContent) {
|
||||||
changedProperties &&
|
this.userSelected = { name: this.editContent.name ?? '' }
|
||||||
changedProperties.has('editContent') &&
|
this.notes = this.editContent.notes ?? ''
|
||||||
this.editContent
|
this.willFollow = this.editContent.willFollow ?? true
|
||||||
) {
|
this.alias = this.editContent.alias ?? ''
|
||||||
this.userSelected = {
|
|
||||||
name: this.editContent.name ?? '',
|
|
||||||
};
|
|
||||||
this.notes = this.editContent.notes ?? '';
|
|
||||||
this.willFollow = this.editContent.willFollow ?? true;
|
|
||||||
this.alias = this.editContent.alias ?? '';
|
|
||||||
this.requestUpdate()
|
this.requestUpdate()
|
||||||
}
|
}
|
||||||
if (
|
|
||||||
changedProperties &&
|
if (changedProperties && changedProperties.has('isOpen') && this.isOpen) {
|
||||||
changedProperties.has('isOpen') && this.isOpen
|
|
||||||
) {
|
|
||||||
await this.getAvailableFeedSchemas()
|
await this.getAvailableFeedSchemas()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getAvailableFeedSchemas() {
|
async getAvailableFeedSchemas() {
|
||||||
try {
|
try {
|
||||||
this.isLoadingSchemas= true
|
this.isLoadingSchemas = true
|
||||||
const url = `${this.nodeUrl}/arbitrary/resources/search?service=DOCUMENT&identifier=ui_schema_feed&prefix=true`;
|
const url = `${this.nodeUrl}/arbitrary/resources/search?service=DOCUMENT&identifier=ui_schema_feed&prefix=true`
|
||||||
const res = await fetch(url);
|
const res = await fetch(url)
|
||||||
const data = await res.json();
|
const data = await res.json()
|
||||||
|
|
||||||
if (data.error === 401) {
|
if (data.error === 401) {
|
||||||
this.availableFeeedSchemas = [];
|
this.availableFeeedSchemas = []
|
||||||
} else {
|
} else {
|
||||||
this.availableFeeedSchemas = data.filter(
|
this.availableFeeedSchemas = data.filter((item) => item.identifier === 'ui_schema_feed')
|
||||||
(item) => item.identifier === 'ui_schema_feed'
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
this.userFoundModalOpen = true;
|
|
||||||
} catch (error) {} finally {
|
this.userFoundModalOpen = true
|
||||||
this.isLoadingSchemas= false
|
} catch (error) {
|
||||||
|
} finally {
|
||||||
|
this.isLoadingSchemas = false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
// Standard functions
|
||||||
return html`
|
getApiKey() {
|
||||||
<div class="modal-overlay ${this.isOpen ? '' : 'hidden'}">
|
const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
return coreNode.apiKey
|
||||||
|
}
|
||||||
|
|
||||||
<div class="modal-content">
|
isEmptyArray(arr) {
|
||||||
<div class="inner-content">
|
if (!arr) { return true }
|
||||||
<div style="text-align:center">
|
return arr.length === 0
|
||||||
<h1>
|
}
|
||||||
${this.editContent
|
|
||||||
? translate('friends.friend10')
|
|
||||||
: translate('friends.friend2')}
|
|
||||||
</h1>
|
|
||||||
<hr />
|
|
||||||
</div>
|
|
||||||
<p>${translate('friends.friend3')}</p>
|
|
||||||
<div class="checkbox-row">
|
|
||||||
<label
|
|
||||||
for="willFollow"
|
|
||||||
id="willFollowLabel"
|
|
||||||
style="color: var(--black);"
|
|
||||||
>
|
|
||||||
${translate('friends.friend5')}
|
|
||||||
</label>
|
|
||||||
<mwc-checkbox
|
|
||||||
style="margin-right: -15px;"
|
|
||||||
id="willFollow"
|
|
||||||
@change=${(e) => {
|
|
||||||
this.willFollow = e.target.checked;
|
|
||||||
}}
|
|
||||||
?checked=${this.willFollow}
|
|
||||||
></mwc-checkbox>
|
|
||||||
</div>
|
|
||||||
<div style="height:15px"></div>
|
|
||||||
<div style="display: flex;flex-direction: column;">
|
|
||||||
<label
|
|
||||||
for="name"
|
|
||||||
id="nameLabel"
|
|
||||||
style="color: var(--black);"
|
|
||||||
>
|
|
||||||
${translate('login.name')}
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
id="name"
|
|
||||||
class="input"
|
|
||||||
?disabled=${true}
|
|
||||||
value=${this.userSelected
|
|
||||||
? this.userSelected.name
|
|
||||||
: ''}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div style="height:15px"></div>
|
|
||||||
<div style="display: flex;flex-direction: column;">
|
|
||||||
<label
|
|
||||||
for="alias"
|
|
||||||
id="aliasLabel"
|
|
||||||
style="color: var(--black);"
|
|
||||||
>
|
|
||||||
${translate('friends.friend6')}
|
|
||||||
</label>
|
|
||||||
<input
|
|
||||||
id="alias"
|
|
||||||
placeholder=${translate('friends.friend7')}
|
|
||||||
class="input"
|
|
||||||
.value=${this.alias}
|
|
||||||
@change=${(e) => {
|
|
||||||
this.alias = e.target.value
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div style="height:15px"></div>
|
|
||||||
<div style="margin-bottom:0;">
|
|
||||||
<textarea
|
|
||||||
class="input"
|
|
||||||
@change=${(e) => {
|
|
||||||
this.notes = e.target.value
|
|
||||||
}}
|
|
||||||
.value=${this.notes}
|
|
||||||
?disabled=${this.isLoading}
|
|
||||||
id="messageBoxAddFriend"
|
|
||||||
placeholder="${translate('friends.friend4')}"
|
|
||||||
rows="3"
|
|
||||||
></textarea>
|
|
||||||
</div>
|
|
||||||
<div style="height:15px"></div>
|
|
||||||
<h2>${translate('friends.friend15')}</h2>
|
|
||||||
<div style="margin-bottom:0;">
|
|
||||||
<p>${translate('friends.friend16')}</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
${this.isLoadingSchemas ? html`
|
|
||||||
<div style="width:100%;display: flex; justify-content:center">
|
|
||||||
<paper-spinner-lite active></paper-spinner-lite>
|
|
||||||
</div>
|
|
||||||
` : ''}
|
|
||||||
${this.availableFeeedSchemas.map((schema) => {
|
|
||||||
const isAlreadySelected = this.mySelectedFeeds.find(
|
|
||||||
(item) => item.name === schema.name
|
|
||||||
);
|
|
||||||
let avatarImgApp;
|
|
||||||
const avatarUrl2 = `${this.nodeUrl}/arbitrary/THUMBNAIL/${schema.name}/qortal_avatar?async=true&apiKey=${this.myNode.apiKey}`;
|
|
||||||
avatarImgApp = html`<img
|
|
||||||
src="${avatarUrl2}"
|
|
||||||
style="max-width:100%; max-height:100%;"
|
|
||||||
onerror="this.onerror=null; this.src='/img/incognito.png';"
|
|
||||||
/>`;
|
|
||||||
return html`
|
|
||||||
<div
|
|
||||||
class="app-name"
|
|
||||||
style="background:${isAlreadySelected ? 'lightblue': ''}"
|
|
||||||
@click=${() => {
|
|
||||||
const copymySelectedFeeds = [
|
|
||||||
...this.mySelectedFeeds,
|
|
||||||
];
|
|
||||||
const findIndex =
|
|
||||||
copymySelectedFeeds.findIndex(
|
|
||||||
(item) =>
|
|
||||||
item.name === schema.name
|
|
||||||
);
|
|
||||||
if (findIndex === -1) {
|
|
||||||
if(this.mySelectedFeeds.length > 4) return
|
|
||||||
copymySelectedFeeds.push({
|
|
||||||
name: schema.name,
|
|
||||||
identifier: schema.identifier,
|
|
||||||
service: schema.service,
|
|
||||||
});
|
|
||||||
this.mySelectedFeeds =
|
|
||||||
copymySelectedFeeds;
|
|
||||||
} else {
|
|
||||||
this.mySelectedFeeds =
|
|
||||||
copymySelectedFeeds.filter(
|
|
||||||
(item) =>
|
|
||||||
item.name !==
|
|
||||||
schema.name
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<div class="avatar">${avatarImgApp}</div>
|
|
||||||
<span
|
|
||||||
style="color:${isAlreadySelected ? 'var(--white)': 'var(--black)'};font-size:16px"
|
|
||||||
>${schema.name}</span
|
|
||||||
>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
})}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div
|
|
||||||
style="display:flex;justify-content:space-between;align-items:center;margin-top:20px"
|
|
||||||
>
|
|
||||||
<button
|
|
||||||
class="modal-button-red"
|
|
||||||
?disabled="${this.isLoading}"
|
|
||||||
@click="${() => {
|
|
||||||
this.setIsOpen(false);
|
|
||||||
this.clearFields();
|
|
||||||
this.onClose();
|
|
||||||
}}"
|
|
||||||
>
|
|
||||||
${translate('general.close')}
|
|
||||||
</button>
|
|
||||||
${this.editContent
|
|
||||||
? html`
|
|
||||||
<button
|
|
||||||
?disabled="${this.isLoading}"
|
|
||||||
class="modal-button-red"
|
|
||||||
@click=${() => {
|
|
||||||
this.removeFriend();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
${translate('friends.friend14')}
|
|
||||||
</button>
|
|
||||||
`
|
|
||||||
: ''}
|
|
||||||
|
|
||||||
<button
|
round(number) {
|
||||||
?disabled="${this.isLoading}"
|
return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8)
|
||||||
class="modal-button"
|
|
||||||
@click=${() => {
|
|
||||||
this.addFriend();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
${this.editContent
|
|
||||||
? translate('friends.friend10')
|
|
||||||
: translate('friends.friend2')}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('add-friends-modal', AddFriendsModal);
|
window.customElements.define('add-friends-modal', AddFriendsModal)
|
@ -1,16 +1,17 @@
|
|||||||
import {css, html, LitElement} from 'lit';
|
import { html, LitElement } from 'lit'
|
||||||
import axios from 'axios';
|
import { connect } from 'pwa-helpers'
|
||||||
import '@material/mwc-menu';
|
import { store } from '../../store'
|
||||||
import '@material/mwc-list/mwc-list-item.js';
|
import { RequestQueueWithPromise } from '../../../../plugins/plugins/utils/classes'
|
||||||
import {RequestQueueWithPromise} from '../../../../plugins/plugins/utils/queue';
|
import { avatarComponentStyles } from '../../styles/core-css'
|
||||||
import '../../../../plugins/plugins/core/components/TimeAgo';
|
import axios from 'axios'
|
||||||
import {connect} from 'pwa-helpers';
|
import ShortUniqueId from 'short-unique-id'
|
||||||
import {store} from '../../store';
|
import '../../../../plugins/plugins/core/components/TimeAgo'
|
||||||
import ShortUniqueId from 'short-unique-id';
|
import '@material/mwc-menu'
|
||||||
|
import '@material/mwc-list/mwc-list-item.js'
|
||||||
|
|
||||||
const requestQueue = new RequestQueueWithPromise(3);
|
const requestQueue = new RequestQueueWithPromise(3)
|
||||||
const requestQueueRawData = new RequestQueueWithPromise(3);
|
const requestQueueRawData = new RequestQueueWithPromise(3)
|
||||||
const requestQueueStatus = new RequestQueueWithPromise(3);
|
const requestQueueStatus = new RequestQueueWithPromise(3)
|
||||||
|
|
||||||
export class AvatarComponent extends connect(store)(LitElement) {
|
export class AvatarComponent extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
@ -18,284 +19,210 @@ export class AvatarComponent extends connect(store)(LitElement) {
|
|||||||
resource: { type: Object },
|
resource: { type: Object },
|
||||||
isReady: { type: Boolean },
|
isReady: { type: Boolean },
|
||||||
status: { type: Object },
|
status: { type: Object },
|
||||||
name: { type: String },
|
name: { type: String }
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return css`
|
return [avatarComponentStyles]
|
||||||
* {
|
|
||||||
--mdc-theme-text-primary-on-background: var(--black);
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
:host {
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
img {
|
|
||||||
width: 100%;
|
|
||||||
max-height: 30vh;
|
|
||||||
border-radius: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.smallLoading,
|
|
||||||
.smallLoading:after {
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 2px;
|
|
||||||
height: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.defaultSize {
|
|
||||||
width: 100%;
|
|
||||||
height: 160px;
|
|
||||||
}
|
|
||||||
.parent-feed-item {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
background-color: var(--chat-bubble-bg);
|
|
||||||
flex-grow: 0;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: center;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 12px 15px 4px 15px;
|
|
||||||
min-width: 150px;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
.avatar {
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
border-radius: 50%;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.avatarApp {
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
border-radius: 50%;
|
|
||||||
overflow: hidden;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.feed-item-name {
|
|
||||||
user-select: none;
|
|
||||||
color: #03a9f4;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.app-name {
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
mwc-menu {
|
|
||||||
position: absolute;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super()
|
||||||
this.resource = {
|
this.resource = {
|
||||||
identifier: '',
|
identifier: '',
|
||||||
name: '',
|
name: '',
|
||||||
service: '',
|
service: ''
|
||||||
};
|
}
|
||||||
this.status = {
|
this.status = {
|
||||||
status: '',
|
status: ''
|
||||||
};
|
|
||||||
this.isReady = false;
|
|
||||||
this.nodeUrl = this.getNodeUrl();
|
|
||||||
this.myNode = this.getMyNode();
|
|
||||||
this.isFetching = false;
|
|
||||||
this.uid = new ShortUniqueId();
|
|
||||||
}
|
|
||||||
getNodeUrl() {
|
|
||||||
const myNode =
|
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
|
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
];
|
|
||||||
|
|
||||||
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
|
|
||||||
}
|
|
||||||
getMyNode() {
|
|
||||||
return window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
|
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
getApiKey() {
|
|
||||||
const myNode =
|
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
|
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
];
|
|
||||||
return myNode.apiKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchResource() {
|
|
||||||
try {
|
|
||||||
if (this.isFetching) return;
|
|
||||||
this.isFetching = true;
|
|
||||||
await axios.get(
|
|
||||||
`${this.nodeUrl}/arbitrary/resource/properties/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`
|
|
||||||
);
|
|
||||||
this.isFetching = false;
|
|
||||||
} catch (error) {
|
|
||||||
this.isFetching = false;
|
|
||||||
}
|
}
|
||||||
}
|
this.isReady = false
|
||||||
|
this.nodeUrl = this.getNodeUrl()
|
||||||
async fetchVideoUrl() {
|
this.myNode = this.getMyNode()
|
||||||
await this.fetchResource();
|
this.isFetching = false
|
||||||
}
|
this.uid = new ShortUniqueId()
|
||||||
|
|
||||||
async getRawData() {
|
|
||||||
const url = `${this.nodeUrl}/arbitrary/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`;
|
|
||||||
return await requestQueueRawData.enqueue(() => {
|
|
||||||
return axios.get(url);
|
|
||||||
});
|
|
||||||
// const response2 = await fetch(url, {
|
|
||||||
// method: 'GET',
|
|
||||||
// headers: {
|
|
||||||
// 'Content-Type': 'application/json'
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
// const responseData2 = await response2.json()
|
|
||||||
// return responseData2
|
|
||||||
}
|
|
||||||
|
|
||||||
updateDisplayWithPlaceholders(display, resource, rawdata) {
|
|
||||||
const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g;
|
|
||||||
|
|
||||||
for (const key in display) {
|
|
||||||
const value = display[key];
|
|
||||||
|
|
||||||
display[key] = value.replace(pattern, (match, p1) => {
|
|
||||||
if (p1.startsWith('rawdata.')) {
|
|
||||||
const dataKey = p1.split('.')[1];
|
|
||||||
if (rawdata[dataKey] === undefined) {
|
|
||||||
console.error('rawdata key not found:', dataKey);
|
|
||||||
}
|
|
||||||
return rawdata[dataKey] || match;
|
|
||||||
} else if (p1.startsWith('resource.')) {
|
|
||||||
const resourceKey = p1.split('.')[1];
|
|
||||||
if (resource[resourceKey] === undefined) {
|
|
||||||
console.error('resource key not found:', resourceKey);
|
|
||||||
}
|
|
||||||
return resource[resourceKey] || match;
|
|
||||||
}
|
|
||||||
return match;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchStatus() {
|
|
||||||
let isCalling = false;
|
|
||||||
let percentLoaded = 0;
|
|
||||||
let timer = 24;
|
|
||||||
const response = await requestQueueStatus.enqueue(() => {
|
|
||||||
return axios.get(
|
|
||||||
`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
if (response && response.data && response.data.status === 'READY') {
|
|
||||||
this.status = response.data;
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
const intervalId = setInterval(async () => {
|
|
||||||
if (isCalling) return;
|
|
||||||
isCalling = true;
|
|
||||||
|
|
||||||
const data = await requestQueue.enqueue(() => {
|
|
||||||
return axios.get(
|
|
||||||
`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`
|
|
||||||
);
|
|
||||||
});
|
|
||||||
const res = data.data;
|
|
||||||
|
|
||||||
isCalling = false;
|
|
||||||
if (res.localChunkCount) {
|
|
||||||
if (res.percentLoaded) {
|
|
||||||
if (
|
|
||||||
res.percentLoaded === percentLoaded &&
|
|
||||||
res.percentLoaded !== 100
|
|
||||||
) {
|
|
||||||
timer = timer - 5;
|
|
||||||
} else {
|
|
||||||
timer = 24;
|
|
||||||
}
|
|
||||||
if (timer < 0) {
|
|
||||||
clearInterval(intervalId);
|
|
||||||
}
|
|
||||||
percentLoaded = res.percentLoaded;
|
|
||||||
}
|
|
||||||
|
|
||||||
this.status = res;
|
|
||||||
if (this.status.status === 'DOWNLOADED') {
|
|
||||||
await this.fetchResource();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check if progress is 100% and clear interval if true
|
|
||||||
if (res.status === 'READY') {
|
|
||||||
clearInterval(intervalId);
|
|
||||||
this.status = res;
|
|
||||||
this.isReady = true;
|
|
||||||
}
|
|
||||||
}, 5000); // 1 second interval
|
|
||||||
}
|
|
||||||
|
|
||||||
async _fetchImage() {
|
|
||||||
try {
|
|
||||||
await this.fetchVideoUrl();
|
|
||||||
await this.fetchStatus();
|
|
||||||
} catch (error) {
|
|
||||||
/* empty */
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
firstUpdated() {
|
|
||||||
this._fetchImage();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div>
|
<div>
|
||||||
${this.status.status !== 'READY'
|
${this.status.status !== 'READY' ?
|
||||||
? html`
|
html`
|
||||||
<mwc-icon style="user-select:none;"
|
<mwc-icon style="user-select:none;">account_circle</mwc-icon>
|
||||||
>account_circle</mwc-icon
|
` : ''
|
||||||
>
|
}
|
||||||
`
|
${this.status.status === 'READY' ?
|
||||||
: ''}
|
html`
|
||||||
${this.status.status === 'READY'
|
<div style="height: 24px;width: 24px;overflow: hidden;">
|
||||||
? html`
|
<img
|
||||||
<div
|
src="${this.nodeUrl}/arbitrary/THUMBNAIL/${this.name}/qortal_avatar?async=true&apiKey=${this.myNode.apiKey}"
|
||||||
style="height: 24px;width: 24px;overflow: hidden;"
|
style="width:100%; height:100%;border-radius:50%"
|
||||||
>
|
onerror="this.onerror=null; this.src='/img/incognito.png';"
|
||||||
<img
|
/>
|
||||||
src="${this
|
</div>
|
||||||
.nodeUrl}/arbitrary/THUMBNAIL/${this
|
` : ''
|
||||||
.name}/qortal_avatar?async=true&apiKey=${this
|
}
|
||||||
.myNode.apiKey}"
|
|
||||||
style="width:100%; height:100%;border-radius:50%"
|
|
||||||
onerror="this.onerror=null; this.src='/img/incognito.png';"
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
: ''}
|
|
||||||
</div>
|
</div>
|
||||||
`;
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated() {
|
||||||
|
this._fetchImage()
|
||||||
|
}
|
||||||
|
|
||||||
|
getNodeUrl() {
|
||||||
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
|
}
|
||||||
|
|
||||||
|
getMyNode() {
|
||||||
|
return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchResource() {
|
||||||
|
try {
|
||||||
|
if (this.isFetching) return
|
||||||
|
|
||||||
|
this.isFetching = true
|
||||||
|
|
||||||
|
await axios.get(
|
||||||
|
`${this.nodeUrl}/arbitrary/resource/properties/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`
|
||||||
|
)
|
||||||
|
|
||||||
|
this.isFetching = false
|
||||||
|
} catch (error) {
|
||||||
|
this.isFetching = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchVideoUrl() {
|
||||||
|
await this.fetchResource()
|
||||||
|
}
|
||||||
|
|
||||||
|
async getRawData() {
|
||||||
|
const url = `${this.nodeUrl}/arbitrary/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`
|
||||||
|
|
||||||
|
return await requestQueueRawData.enqueue(() => {
|
||||||
|
return axios.get(url)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
updateDisplayWithPlaceholders(display, resource, rawdata) {
|
||||||
|
const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g
|
||||||
|
|
||||||
|
for (const key in display) {
|
||||||
|
const value = display[key]
|
||||||
|
|
||||||
|
display[key] = value.replace(pattern, (match, p1) => {
|
||||||
|
if (p1.startsWith('rawdata.')) {
|
||||||
|
const dataKey = p1.split('.')[1]
|
||||||
|
|
||||||
|
if (rawdata[dataKey] === undefined) {
|
||||||
|
console.error('rawdata key not found:', dataKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
return rawdata[dataKey] || match
|
||||||
|
} else if (p1.startsWith('resource.')) {
|
||||||
|
const resourceKey = p1.split('.')[1]
|
||||||
|
|
||||||
|
if (resource[resourceKey] === undefined) {
|
||||||
|
console.error('resource key not found:', resourceKey)
|
||||||
|
}
|
||||||
|
|
||||||
|
return resource[resourceKey] || match
|
||||||
|
}
|
||||||
|
|
||||||
|
return match
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async fetchStatus() {
|
||||||
|
let isCalling = false
|
||||||
|
let percentLoaded = 0
|
||||||
|
let timer = 24
|
||||||
|
|
||||||
|
const response = await requestQueueStatus.enqueue(() => {
|
||||||
|
return axios.get(
|
||||||
|
`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (response && response.data && response.data.status === 'READY') {
|
||||||
|
this.status = response.data
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const intervalId = setInterval(async () => {
|
||||||
|
if (isCalling) return
|
||||||
|
|
||||||
|
isCalling = true
|
||||||
|
|
||||||
|
const data = await requestQueue.enqueue(() => {
|
||||||
|
return axios.get(
|
||||||
|
`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
const res = data.data
|
||||||
|
|
||||||
|
isCalling = false
|
||||||
|
|
||||||
|
if (res.localChunkCount) {
|
||||||
|
if (res.percentLoaded) {
|
||||||
|
if (res.percentLoaded === percentLoaded && res.percentLoaded !== 100) {
|
||||||
|
timer = timer - 5
|
||||||
|
} else {
|
||||||
|
timer = 24
|
||||||
|
}
|
||||||
|
|
||||||
|
if (timer < 0) {
|
||||||
|
clearInterval(intervalId)
|
||||||
|
}
|
||||||
|
|
||||||
|
percentLoaded = res.percentLoaded
|
||||||
|
}
|
||||||
|
|
||||||
|
this.status = res
|
||||||
|
|
||||||
|
if (this.status.status === 'DOWNLOADED') {
|
||||||
|
await this.fetchResource()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// check if progress is 100% and clear interval if true
|
||||||
|
if (res.status === 'READY') {
|
||||||
|
clearInterval(intervalId)
|
||||||
|
this.status = res
|
||||||
|
this.isReady = true
|
||||||
|
}
|
||||||
|
}, 5000) // 5 second interval
|
||||||
|
}
|
||||||
|
|
||||||
|
async _fetchImage() {
|
||||||
|
try {
|
||||||
|
await this.fetchVideoUrl()
|
||||||
|
await this.fetchStatus()
|
||||||
|
} catch (error) {
|
||||||
|
/* empty */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Standard functions
|
||||||
|
getApiKey() {
|
||||||
|
const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
return coreNode.apiKey
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmptyArray(arr) {
|
||||||
|
if (!arr) { return true }
|
||||||
|
return arr.length === 0
|
||||||
|
}
|
||||||
|
|
||||||
|
round(number) {
|
||||||
|
return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('avatar-component', AvatarComponent);
|
window.customElements.define('avatar-component', AvatarComponent)
|
@ -1,344 +1,214 @@
|
|||||||
import {css, html, LitElement} from 'lit';
|
import { html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers';
|
import { connect } from 'pwa-helpers'
|
||||||
|
import { store } from '../../store'
|
||||||
import '@vaadin/item';
|
import { setNewTab } from '../../redux/app/app-actions'
|
||||||
import '@vaadin/list-box';
|
import { get } from '../../../translate'
|
||||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
import { beginnerChecklistStyles } from '../../styles/core-css'
|
||||||
import '@polymer/iron-icons/iron-icons.js';
|
import ShortUniqueId from 'short-unique-id'
|
||||||
import {store} from '../../store.js';
|
import '../notification-view/popover'
|
||||||
import {setNewTab} from '../../redux/app/app-actions.js';
|
import '../../../../plugins/plugins/core/components/TimeAgo'
|
||||||
import '@material/mwc-icon';
|
import '@material/mwc-icon'
|
||||||
import {get} from '../../../translate';
|
import '@polymer/paper-icon-button/paper-icon-button.js'
|
||||||
import '../../../../plugins/plugins/core/components/TimeAgo.js';
|
import '@polymer/iron-icons/iron-icons.js'
|
||||||
import '../notification-view/popover.js';
|
import '@vaadin/item'
|
||||||
import ShortUniqueId from 'short-unique-id';
|
import '@vaadin/list-box'
|
||||||
|
|
||||||
class BeginnerChecklist extends connect(store)(LitElement) {
|
class BeginnerChecklist extends connect(store)(LitElement) {
|
||||||
static properties = {
|
static get properties() {
|
||||||
notifications: { type: Array },
|
return {
|
||||||
showChecklist: { type: Boolean },
|
notifications: { type: Array },
|
||||||
theme: { type: String, reflect: true },
|
showChecklist: { type: Boolean },
|
||||||
isSynced: { type: Boolean },
|
isSynced: { type: Boolean },
|
||||||
hasName: { type: Boolean },
|
hasName: { type: Boolean },
|
||||||
hasTourFinished: { type: Boolean },
|
hasTourFinished: { type: Boolean },
|
||||||
};
|
theme: { type: String, reflect: true }
|
||||||
|
}
|
||||||
constructor() {
|
|
||||||
super();
|
|
||||||
this.showChecklist = false;
|
|
||||||
this.initialFetch = false;
|
|
||||||
this.theme = localStorage.getItem('qortalTheme')
|
|
||||||
? localStorage.getItem('qortalTheme')
|
|
||||||
: 'light';
|
|
||||||
this.isSynced = false;
|
|
||||||
this.hasName = null;
|
|
||||||
this.nodeUrl = this.getNodeUrl();
|
|
||||||
this.myNode = this.getMyNode();
|
|
||||||
this.hasTourFinished = null;
|
|
||||||
this._controlTourFinished = this._controlTourFinished.bind(this);
|
|
||||||
this.uid = new ShortUniqueId();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_controlTourFinished() {
|
static get styles() {
|
||||||
this.hasTourFinished = true;
|
return [beginnerChecklistStyles]
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.showChecklist = false
|
||||||
|
this.initialFetch = false
|
||||||
|
this.isSynced = false
|
||||||
|
this.hasName = null
|
||||||
|
this.nodeUrl = this.getNodeUrl()
|
||||||
|
this.myNode = this.getMyNode()
|
||||||
|
this.hasTourFinished = null
|
||||||
|
this._controlTourFinished = this._controlTourFinished.bind(this)
|
||||||
|
this.uid = new ShortUniqueId()
|
||||||
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return this.hasName === false || this.hasTourFinished === false ?
|
||||||
|
html`
|
||||||
|
<div class="layout">
|
||||||
|
<popover-component for="popover-checklist" message=${get('tour.tour16')}></popover-component>
|
||||||
|
<div id="popover-checklist" @click=${() => this._toggleChecklist()}>
|
||||||
|
<mwc-icon id="checklist-general-icon" style=${`color: ${!this.hasName ? 'red' : 'var(--black)'}; cursor:pointer;user-select:none`}>
|
||||||
|
checklist
|
||||||
|
</mwc-icon>
|
||||||
|
<vaadin-tooltip for="checklist-general-icon" position="bottom" hover-delay=${400} hide-delay=${1} text=${get('tour.tour16')}></vaadin-tooltip>
|
||||||
|
</div>
|
||||||
|
<div id="checklist-panel" class="popover-panel" style="visibility:${this.showChecklist ? 'visibile' : 'hidden'}" tabindex="0" @blur=${this.handleBlur}>
|
||||||
|
<div class="list">
|
||||||
|
<div class="task-list-item">
|
||||||
|
<p>Are you synced?</p>
|
||||||
|
${this.syncPercentage === 100 ?
|
||||||
|
html`
|
||||||
|
<mwc-icon id="checklist-general-icon" style="color: green; user-select:none">
|
||||||
|
task_alt
|
||||||
|
</mwc-icon>
|
||||||
|
`
|
||||||
|
: html`
|
||||||
|
<mwc-icon id="checklist-general-icon" style="color: red; user-select:none">
|
||||||
|
radio_button_unchecked
|
||||||
|
</mwc-icon>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="task-list-item"
|
||||||
|
style="cursor:pointer"
|
||||||
|
@click=${() => {
|
||||||
|
store.dispatch(
|
||||||
|
setNewTab({
|
||||||
|
url: `group-management`,
|
||||||
|
id: this.uid.rnd(),
|
||||||
|
myPlugObj: {
|
||||||
|
url: 'name-registration',
|
||||||
|
domain: 'core',
|
||||||
|
page: 'name-registration/index.html',
|
||||||
|
title: 'Name Registration',
|
||||||
|
icon: 'vaadin:user-check',
|
||||||
|
mwcicon: 'manage_accounts',
|
||||||
|
pluginNumber: 'plugin-qCmtXAQmtu',
|
||||||
|
menus: [],
|
||||||
|
parent: false
|
||||||
|
},
|
||||||
|
openExisting: true
|
||||||
|
})
|
||||||
|
);
|
||||||
|
this.handleBlur();
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<p>Do you have a name registered?</p>
|
||||||
|
${this.hasName ?
|
||||||
|
html`
|
||||||
|
<mwc-icon id="checklist-general-icon" style="color: green; user-select:none">
|
||||||
|
task_alt
|
||||||
|
</mwc-icon>
|
||||||
|
` : html`
|
||||||
|
<mwc-icon id="checklist-general-icon" style="color: red; user-select:none">
|
||||||
|
radio_button_unchecked
|
||||||
|
</mwc-icon>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ''
|
||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated() {
|
firstUpdated() {
|
||||||
this.address = store.getState().app.selectedAddress.address;
|
this.address = store.getState().app.selectedAddress.address
|
||||||
this.hasTourFinished = JSON.parse(
|
this.hasTourFinished = JSON.parse(localStorage.getItem(`hasViewedTour-${this.address}`) || 'null')
|
||||||
localStorage.getItem(`hasViewedTour-${this.address}`) || 'null'
|
}
|
||||||
);
|
|
||||||
|
_controlTourFinished() {
|
||||||
|
this.hasTourFinished = true
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
super.connectedCallback();
|
super.connectedCallback()
|
||||||
window.addEventListener(
|
window.addEventListener('send-tour-finished', this._controlTourFinished)
|
||||||
'send-tour-finished',
|
|
||||||
this._controlTourFinished
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
window.removeEventListener(
|
window.removeEventListener('send-tour-finished', this._controlTourFinished)
|
||||||
'send-tour-finished',
|
super.disconnectedCallback()
|
||||||
this._controlTourFinished
|
|
||||||
);
|
|
||||||
|
|
||||||
super.disconnectedCallback();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getNodeUrl() {
|
getNodeUrl() {
|
||||||
const myNode =
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
|
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
];
|
|
||||||
|
|
||||||
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getMyNode() {
|
getMyNode() {
|
||||||
return window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
|
return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
async getName(recipient) {
|
async getName(recipient) {
|
||||||
try {
|
try {
|
||||||
if (!recipient) return '';
|
if (!recipient) return ''
|
||||||
const endpoint = `${this.nodeUrl}/names/address/${recipient}`;
|
|
||||||
const res = await fetch(endpoint);
|
|
||||||
const getNames = await res.json();
|
|
||||||
|
|
||||||
this.hasName = Array.isArray(getNames) && getNames.length > 0;
|
const endpoint = `${this.nodeUrl}/names/address/${recipient}`
|
||||||
|
const res = await fetch(endpoint)
|
||||||
|
const getNames = await res.json()
|
||||||
|
|
||||||
|
this.hasName = Array.isArray(getNames) && getNames.length > 0
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
return '';
|
return ''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stateChanged(state) {
|
stateChanged(state) {
|
||||||
if (
|
if (state.app.nodeStatus && state.app.nodeStatus.syncPercent !== this.syncPercentage) {
|
||||||
state.app.nodeStatus &&
|
this.syncPercentage = state.app.nodeStatus.syncPercent
|
||||||
state.app.nodeStatus.syncPercent !== this.syncPercentage
|
|
||||||
) {
|
|
||||||
this.syncPercentage = state.app.nodeStatus.syncPercent;
|
|
||||||
|
|
||||||
if (
|
if (!this.hasAttempted && state.app.selectedAddress && state.app.nodeStatus.syncPercent === 100) {
|
||||||
!this.hasAttempted &&
|
this.hasAttempted = true
|
||||||
state.app.selectedAddress &&
|
this.getName(state.app.selectedAddress.address)
|
||||||
state.app.nodeStatus.syncPercent === 100
|
|
||||||
) {
|
|
||||||
this.hasAttempted = true;
|
|
||||||
this.getName(state.app.selectedAddress.address);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (
|
|
||||||
state.app.accountInfo &&
|
if (state.app.accountInfo &&
|
||||||
state.app.accountInfo.names.length &&
|
state.app.accountInfo.names.length && state.app.nodeStatus && state.app.nodeStatus.syncPercent === 100 &&
|
||||||
state.app.nodeStatus &&
|
this.hasName === false && this.hasAttempted && state.app.accountInfo && state.app.accountInfo.names &&
|
||||||
state.app.nodeStatus.syncPercent === 100 &&
|
|
||||||
this.hasName === false &&
|
|
||||||
this.hasAttempted &&
|
|
||||||
state.app.accountInfo &&
|
|
||||||
state.app.accountInfo.names &&
|
|
||||||
state.app.accountInfo.names.length > 0
|
state.app.accountInfo.names.length > 0
|
||||||
) {
|
) {
|
||||||
this.hasName = true;
|
this.hasName = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
handleBlur() {
|
handleBlur() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
if (!this.shadowRoot.contains(document.activeElement)) {
|
if (!this.shadowRoot.contains(document.activeElement)) {
|
||||||
this.showChecklist = false;
|
this.showChecklist = false
|
||||||
}
|
}
|
||||||
}, 0);
|
}, 0)
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return this.hasName === false || this.hasTourFinished === false
|
|
||||||
? html`
|
|
||||||
<div class="layout">
|
|
||||||
<popover-component
|
|
||||||
for="popover-checklist"
|
|
||||||
message=${get('tour.tour16')}
|
|
||||||
></popover-component>
|
|
||||||
<div
|
|
||||||
id="popover-checklist"
|
|
||||||
@click=${() => this._toggleChecklist()}
|
|
||||||
>
|
|
||||||
<mwc-icon
|
|
||||||
id="checklist-general-icon"
|
|
||||||
style=${`color: ${
|
|
||||||
!this.hasName ? 'red' : 'var(--black)'
|
|
||||||
}; cursor:pointer;user-select:none`}
|
|
||||||
>checklist</mwc-icon
|
|
||||||
>
|
|
||||||
<vaadin-tooltip
|
|
||||||
for="checklist-general-icon"
|
|
||||||
position="bottom"
|
|
||||||
hover-delay=${400}
|
|
||||||
hide-delay=${1}
|
|
||||||
text=${get('tour.tour16')}
|
|
||||||
>
|
|
||||||
</vaadin-tooltip>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
id="checklist-panel"
|
|
||||||
class="popover-panel"
|
|
||||||
style="visibility:${this.showChecklist
|
|
||||||
? 'visibile'
|
|
||||||
: 'hidden'}"
|
|
||||||
tabindex="0"
|
|
||||||
@blur=${this.handleBlur}
|
|
||||||
>
|
|
||||||
<div class="list">
|
|
||||||
<div class="task-list-item">
|
|
||||||
<p>Are you synced?</p>
|
|
||||||
${this.syncPercentage === 100
|
|
||||||
? html`
|
|
||||||
<mwc-icon
|
|
||||||
id="checklist-general-icon"
|
|
||||||
style="color: green; user-select:none"
|
|
||||||
>task_alt</mwc-icon
|
|
||||||
>
|
|
||||||
`
|
|
||||||
: html`
|
|
||||||
<mwc-icon
|
|
||||||
id="checklist-general-icon"
|
|
||||||
style="color: red; user-select:none"
|
|
||||||
>radio_button_unchecked</mwc-icon
|
|
||||||
>
|
|
||||||
`}
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div
|
|
||||||
class="task-list-item"
|
|
||||||
style="cursor:pointer"
|
|
||||||
@click=${() => {
|
|
||||||
store.dispatch(
|
|
||||||
setNewTab({
|
|
||||||
url: `group-management`,
|
|
||||||
id: this.uid.rnd(),
|
|
||||||
myPlugObj: {
|
|
||||||
url: 'name-registration',
|
|
||||||
domain: 'core',
|
|
||||||
page: 'name-registration/index.html',
|
|
||||||
title: 'Name Registration',
|
|
||||||
icon: 'vaadin:user-check',
|
|
||||||
mwcicon: 'manage_accounts',
|
|
||||||
pluginNumber:
|
|
||||||
'plugin-qCmtXAQmtu',
|
|
||||||
menus: [],
|
|
||||||
parent: false,
|
|
||||||
},
|
|
||||||
openExisting: true,
|
|
||||||
})
|
|
||||||
);
|
|
||||||
this.handleBlur();
|
|
||||||
}}
|
|
||||||
>
|
|
||||||
<p>Do you have a name registered?</p>
|
|
||||||
${this.hasName
|
|
||||||
? html`
|
|
||||||
<mwc-icon
|
|
||||||
id="checklist-general-icon"
|
|
||||||
style="color: green; user-select:none"
|
|
||||||
>task_alt</mwc-icon
|
|
||||||
>
|
|
||||||
`
|
|
||||||
: html`
|
|
||||||
<mwc-icon
|
|
||||||
id="checklist-general-icon"
|
|
||||||
style="color: red; user-select:none"
|
|
||||||
>radio_button_unchecked</mwc-icon
|
|
||||||
>
|
|
||||||
`}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
: '';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_toggleChecklist() {
|
_toggleChecklist() {
|
||||||
this.showChecklist = !this.showChecklist;
|
this.showChecklist = !this.showChecklist
|
||||||
|
|
||||||
if (this.showChecklist) {
|
if (this.showChecklist) {
|
||||||
requestAnimationFrame(() => {
|
requestAnimationFrame(() => {
|
||||||
this.shadowRoot.getElementById('checklist-panel').focus();
|
this.shadowRoot.getElementById('checklist-panel').focus()
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = css`
|
// Standard functions
|
||||||
.layout {
|
getApiKey() {
|
||||||
display: flex;
|
const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
flex-direction: column;
|
return coreNode.apiKey
|
||||||
align-items: center;
|
}
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.count {
|
isEmptyArray(arr) {
|
||||||
position: absolute;
|
if (!arr) { return true }
|
||||||
top: -5px;
|
return arr.length === 0
|
||||||
right: -5px;
|
}
|
||||||
font-size: 12px;
|
|
||||||
background-color: red;
|
|
||||||
color: white;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nocount {
|
round(number) {
|
||||||
display: none;
|
return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8)
|
||||||
}
|
}
|
||||||
|
|
||||||
.popover-panel {
|
|
||||||
position: absolute;
|
|
||||||
width: 200px;
|
|
||||||
padding: 10px;
|
|
||||||
background-color: var(--white);
|
|
||||||
border: 1px solid var(--black);
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
top: 40px;
|
|
||||||
max-height: 350px;
|
|
||||||
overflow: auto;
|
|
||||||
scrollbar-width: thin;
|
|
||||||
scrollbar-color: #6a6c75 #a1a1a1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover-panel::-webkit-scrollbar {
|
|
||||||
width: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover-panel::-webkit-scrollbar-track {
|
|
||||||
background: #a1a1a1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover-panel::-webkit-scrollbar-thumb {
|
|
||||||
background-color: #6a6c75;
|
|
||||||
border-radius: 6px;
|
|
||||||
border: 3px solid #a1a1a1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
gap: 15px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.task-list-item {
|
|
||||||
display: flex;
|
|
||||||
gap: 15px;
|
|
||||||
justify-content: space-between;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checklist-item {
|
|
||||||
padding: 5px;
|
|
||||||
border-bottom: 1px solid;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: 0.2s all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checklist-item:hover {
|
|
||||||
background: var(--nav-color-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 16px;
|
|
||||||
color: var(--black);
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('beginner-checklist', BeginnerChecklist);
|
window.customElements.define('beginner-checklist', BeginnerChecklist)
|
@ -1,91 +1,67 @@
|
|||||||
import {Sha256} from 'asmcrypto.js'
|
import { Sha256 } from 'asmcrypto.js'
|
||||||
|
|
||||||
|
function sbrk(size, heap) {
|
||||||
function sbrk(size, heap){
|
let brk = 512 * 1024 // stack top
|
||||||
let brk = 512 * 1024 // stack top
|
let old = brk
|
||||||
let old = brk
|
brk += size
|
||||||
brk += size
|
if (brk > heap.length) throw new Error('heap exhausted')
|
||||||
|
return old
|
||||||
if (brk > heap.length)
|
|
||||||
throw new Error('heap exhausted')
|
|
||||||
|
|
||||||
return old
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
self.addEventListener('message', async e => {
|
self.addEventListener('message', async e => {
|
||||||
const response = await computePow(e.data.convertedBytes, e.data.path)
|
const response = await computePow(e.data.convertedBytes, e.data.path)
|
||||||
postMessage(response)
|
postMessage(response)
|
||||||
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 })
|
const memory = new WebAssembly.Memory({ initial: 256, maximum: 256 })
|
||||||
const heap = new Uint8Array(memory.buffer)
|
const heap = new Uint8Array(memory.buffer)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
const computePow = async (convertedBytes, path) => {
|
const computePow = async (convertedBytes, path) => {
|
||||||
|
let response = null
|
||||||
|
await new Promise((resolve, reject) => {
|
||||||
|
const _convertedBytesArray = Object.keys(convertedBytes).map(
|
||||||
|
function (key) {
|
||||||
|
return convertedBytes[key]
|
||||||
|
}
|
||||||
|
)
|
||||||
|
const convertedBytesArray = new Uint8Array(_convertedBytesArray)
|
||||||
|
const convertedBytesHash = new Sha256()
|
||||||
|
.process(convertedBytesArray)
|
||||||
|
.finish().result
|
||||||
|
const hashPtr = sbrk(32, heap)
|
||||||
|
const hashAry = new Uint8Array(
|
||||||
|
memory.buffer,
|
||||||
|
hashPtr,
|
||||||
|
32
|
||||||
|
)
|
||||||
|
hashAry.set(convertedBytesHash)
|
||||||
|
const difficulty = 14
|
||||||
|
const workBufferLength = 8 * 1024 * 1024
|
||||||
|
const workBufferPtr = sbrk(
|
||||||
|
workBufferLength,
|
||||||
|
heap
|
||||||
|
)
|
||||||
|
const importObject = {
|
||||||
|
env: {
|
||||||
|
memory: memory
|
||||||
|
}
|
||||||
|
}
|
||||||
|
function loadWebAssembly(filename, imports) {
|
||||||
|
return fetch(filename)
|
||||||
|
.then(response => response.arrayBuffer())
|
||||||
|
.then(buffer => WebAssembly.compile(buffer))
|
||||||
|
.then(module => {
|
||||||
|
return new WebAssembly.Instance(module, importObject)
|
||||||
|
})
|
||||||
|
}
|
||||||
|
loadWebAssembly(path)
|
||||||
|
.then(wasmModule => {
|
||||||
|
response = {
|
||||||
|
nonce: wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty),
|
||||||
|
|
||||||
|
}
|
||||||
let response = null
|
resolve()
|
||||||
|
})
|
||||||
await new Promise((resolve, reject)=> {
|
})
|
||||||
|
return response
|
||||||
const _convertedBytesArray = Object.keys(convertedBytes).map(
|
}
|
||||||
function (key) {
|
|
||||||
return convertedBytes[key]
|
|
||||||
}
|
|
||||||
)
|
|
||||||
const convertedBytesArray = new Uint8Array(_convertedBytesArray)
|
|
||||||
const convertedBytesHash = new Sha256()
|
|
||||||
.process(convertedBytesArray)
|
|
||||||
.finish().result
|
|
||||||
const hashPtr = sbrk(32, heap)
|
|
||||||
const hashAry = new Uint8Array(
|
|
||||||
memory.buffer,
|
|
||||||
hashPtr,
|
|
||||||
32
|
|
||||||
)
|
|
||||||
|
|
||||||
hashAry.set(convertedBytesHash)
|
|
||||||
const difficulty = 14
|
|
||||||
const workBufferLength = 8 * 1024 * 1024
|
|
||||||
const workBufferPtr = sbrk(
|
|
||||||
workBufferLength,
|
|
||||||
heap
|
|
||||||
)
|
|
||||||
|
|
||||||
const importObject = {
|
|
||||||
env: {
|
|
||||||
memory: memory
|
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
function loadWebAssembly(filename, imports) {
|
|
||||||
return fetch(filename)
|
|
||||||
.then(response => response.arrayBuffer())
|
|
||||||
.then(buffer => WebAssembly.compile(buffer))
|
|
||||||
.then(module => {
|
|
||||||
return new WebAssembly.Instance(module, importObject);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
loadWebAssembly(path)
|
|
||||||
.then(wasmModule => {
|
|
||||||
response = {
|
|
||||||
nonce : wasmModule.exports.compute2(hashPtr, workBufferPtr, workBufferLength, difficulty),
|
|
||||||
|
|
||||||
}
|
|
||||||
resolve()
|
|
||||||
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
||||||
|
|
||||||
return response
|
|
||||||
}
|
|
@ -1,7 +1,8 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {store} from '../../store'
|
import { connect } from 'pwa-helpers'
|
||||||
import {connect} from 'pwa-helpers'
|
import { store } from '../../store'
|
||||||
import {translate} from '../../../translate'
|
import { translate } from '../../../translate'
|
||||||
|
import { coreSyncStatusStyles } from '../../styles/core-css'
|
||||||
|
|
||||||
class CoreSyncStatus extends connect(store)(LitElement) {
|
class CoreSyncStatus extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
@ -12,6 +13,10 @@ class CoreSyncStatus extends connect(store)(LitElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return [coreSyncStatusStyles]
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
this.nodeInfos = []
|
this.nodeInfos = []
|
||||||
@ -19,69 +24,6 @@ class CoreSyncStatus extends connect(store)(LitElement) {
|
|||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
|
||||||
return css`
|
|
||||||
.lineHeight {
|
|
||||||
line-height: 33%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip {
|
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip .bottom {
|
|
||||||
min-width: 200px;
|
|
||||||
max-width: 250px;
|
|
||||||
top: 35px;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%, 0);
|
|
||||||
padding: 10px 10px;
|
|
||||||
color: var(--black);
|
|
||||||
background-color: var(--white);
|
|
||||||
font-weight: normal;
|
|
||||||
font-size: 13px;
|
|
||||||
border-radius: 8px;
|
|
||||||
position: absolute;
|
|
||||||
z-index: 99999999;
|
|
||||||
box-sizing: border-box;
|
|
||||||
box-shadow: 0 1px 8px rgba(0,0,0,0.5);
|
|
||||||
border: 1px solid var(--black);
|
|
||||||
visibility: hidden;
|
|
||||||
opacity: 0;
|
|
||||||
transition: opacity 0.8s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip:hover .bottom {
|
|
||||||
visibility: visible;
|
|
||||||
opacity: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip .bottom i {
|
|
||||||
position: absolute;
|
|
||||||
bottom: 100%;
|
|
||||||
left: 50%;
|
|
||||||
margin-left: -12px;
|
|
||||||
width: 24px;
|
|
||||||
height: 12px;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.tooltip .bottom i::after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
left: 50%;
|
|
||||||
transform: translate(-50%,50%) rotate(45deg);
|
|
||||||
background-color: var(--white);
|
|
||||||
border: 1px solid var(--black);
|
|
||||||
box-shadow: 0 1px 8px rgba(0,0,0,0.5);
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div id="core-sync-status-id">
|
<div id="core-sync-status-id">
|
||||||
@ -136,7 +78,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {
|
|||||||
<span><img src="/img/syncing.png" style="height: 24px; width: 24px; padding-top: 4px;"></span>
|
<span><img src="/img/syncing.png" style="height: 24px; width: 24px; padding-top: 4px;"></span>
|
||||||
<div class="bottom">
|
<div class="bottom">
|
||||||
<h3>${translate("walletprofile.wp3")}</h3>
|
<h3>${translate("walletprofile.wp3")}</h3>
|
||||||
<h4 class="lineHeight">${translate("appinfo.coreversion")}: <span style="color: #03a9f4">${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.coreversion")}: <span style="color: #03a9f4">${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}</span></h4>
|
||||||
<h4 class="lineHeight">${translate("appinfo.synchronizing")}... <span style="color: #03a9f4">${this.nodeInfos.syncPercent !== undefined ? this.nodeInfos.syncPercent + '%' : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.synchronizing")}... <span style="color: #03a9f4">${this.nodeInfos.syncPercent !== undefined ? this.nodeInfos.syncPercent + '%' : ''}</span></h4>
|
||||||
<h4 class="lineHeight">${translate("appinfo.blockheight")}: <span style="color: #03a9f4">${this.nodeInfos.height ? this.nodeInfos.height : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.blockheight")}: <span style="color: #03a9f4">${this.nodeInfos.height ? this.nodeInfos.height : ''}</span></h4>
|
||||||
<h4 class="lineHeight">${translate("appinfo.peers")}: <span style="color: #03a9f4">${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.peers")}: <span style="color: #03a9f4">${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}</span></h4>
|
||||||
@ -150,7 +92,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {
|
|||||||
<span><img src="/img/synced.png" style="height: 24px; width: 24px; padding-top: 4px;"></span>
|
<span><img src="/img/synced.png" style="height: 24px; width: 24px; padding-top: 4px;"></span>
|
||||||
<div class="bottom">
|
<div class="bottom">
|
||||||
<h3>${translate("walletprofile.wp3")}</h3>
|
<h3>${translate("walletprofile.wp3")}</h3>
|
||||||
<h4 class="lineHeight">${translate("appinfo.coreversion")}: <span style="color: #03a9f4">${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.coreversion")}: <span style="color: #03a9f4">${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}</span></h4>
|
||||||
<h4 class="lineHeight">${translate("walletprofile.wp4")} ${translate("walletprofile.wp2")}</h4>
|
<h4 class="lineHeight">${translate("walletprofile.wp4")} ${translate("walletprofile.wp2")}</h4>
|
||||||
<h4 class="lineHeight">${translate("appinfo.blockheight")}: <span style="color: #03a9f4">${this.nodeInfos.height ? this.nodeInfos.height : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.blockheight")}: <span style="color: #03a9f4">${this.nodeInfos.height ? this.nodeInfos.height : ''}</span></h4>
|
||||||
<h4 class="lineHeight">${translate("appinfo.peers")}: <span style="color: #03a9f4">${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.peers")}: <span style="color: #03a9f4">${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}</span></h4>
|
||||||
@ -164,7 +106,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {
|
|||||||
<span><img src="/img/synced.png" style="height: 24px; width: 24px; padding-top: 4px;"></span>
|
<span><img src="/img/synced.png" style="height: 24px; width: 24px; padding-top: 4px;"></span>
|
||||||
<div class="bottom">
|
<div class="bottom">
|
||||||
<h3>${translate("walletprofile.wp3")}</h3>
|
<h3>${translate("walletprofile.wp3")}</h3>
|
||||||
<h4 class="lineHeight">${translate("appinfo.coreversion")}: <span style="color: #03a9f4">${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.coreversion")}: <span style="color: #03a9f4">${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}</span></h4>
|
||||||
<h4 class="lineHeight">${translate("walletprofile.wp4")} ${translate("walletprofile.wp2")}</h4>
|
<h4 class="lineHeight">${translate("walletprofile.wp4")} ${translate("walletprofile.wp2")}</h4>
|
||||||
<h4 class="lineHeight">${translate("appinfo.blockheight")}: <span style="color: #03a9f4">${this.nodeInfos.height ? this.nodeInfos.height : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.blockheight")}: <span style="color: #03a9f4">${this.nodeInfos.height ? this.nodeInfos.height : ''}</span></h4>
|
||||||
<h4 class="lineHeight">${translate("appinfo.peers")}: <span style="color: #03a9f4">${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.peers")}: <span style="color: #03a9f4">${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}</span></h4>
|
||||||
@ -178,7 +120,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {
|
|||||||
<span><img src="/img/synced_minting.png" style="height: 24px; width: 24px; padding-top: 4px;"></span>
|
<span><img src="/img/synced_minting.png" style="height: 24px; width: 24px; padding-top: 4px;"></span>
|
||||||
<div class="bottom">
|
<div class="bottom">
|
||||||
<h3>${translate("walletprofile.wp3")}</h3>
|
<h3>${translate("walletprofile.wp3")}</h3>
|
||||||
<h4 class="lineHeight">${translate("appinfo.coreversion")}: <span style="color: #03a9f4">${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.coreversion")}: <span style="color: #03a9f4">${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}</span></h4>
|
||||||
<h4 class="lineHeight">${translate("walletprofile.wp4")} <span style="color: #03a9f4">( ${translate("walletprofile.wp1")} )</span></h4>
|
<h4 class="lineHeight">${translate("walletprofile.wp4")} <span style="color: #03a9f4">( ${translate("walletprofile.wp1")} )</span></h4>
|
||||||
<h4 class="lineHeight">${translate("appinfo.blockheight")}: <span style="color: #03a9f4">${this.nodeInfos.height ? this.nodeInfos.height : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.blockheight")}: <span style="color: #03a9f4">${this.nodeInfos.height ? this.nodeInfos.height : ''}</span></h4>
|
||||||
<h4 class="lineHeight">${translate("appinfo.peers")}: <span style="color: #03a9f4">${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.peers")}: <span style="color: #03a9f4">${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}</span></h4>
|
||||||
@ -192,7 +134,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {
|
|||||||
<span><img src="/img/synced_minting.png" style="height: 24px; width: 24px; padding-top: 4px;"></span>
|
<span><img src="/img/synced_minting.png" style="height: 24px; width: 24px; padding-top: 4px;"></span>
|
||||||
<div class="bottom">
|
<div class="bottom">
|
||||||
<h3>${translate("walletprofile.wp3")}</h3>
|
<h3>${translate("walletprofile.wp3")}</h3>
|
||||||
<h4 class="lineHeight">${translate("appinfo.coreversion")}: <span style="color: #03a9f4">${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.coreversion")}: <span style="color: #03a9f4">${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}</span></h4>
|
||||||
<h4 class="lineHeight">${translate("walletprofile.wp4")} <span style="color: #03a9f4">( ${translate("walletprofile.wp1")} )</span></h4>
|
<h4 class="lineHeight">${translate("walletprofile.wp4")} <span style="color: #03a9f4">( ${translate("walletprofile.wp1")} )</span></h4>
|
||||||
<h4 class="lineHeight">${translate("appinfo.blockheight")}: <span style="color: #03a9f4">${this.nodeInfos.height ? this.nodeInfos.height : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.blockheight")}: <span style="color: #03a9f4">${this.nodeInfos.height ? this.nodeInfos.height : ''}</span></h4>
|
||||||
<h4 class="lineHeight">${translate("appinfo.peers")}: <span style="color: #03a9f4">${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.peers")}: <span style="color: #03a9f4">${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}</span></h4>
|
||||||
@ -206,7 +148,7 @@ class CoreSyncStatus extends connect(store)(LitElement) {
|
|||||||
<span><img src="/img/syncing.png" style="height: 24px; width: 24px; padding-top: 4px;"></span>
|
<span><img src="/img/syncing.png" style="height: 24px; width: 24px; padding-top: 4px;"></span>
|
||||||
<div class="bottom">
|
<div class="bottom">
|
||||||
<h3>${translate("walletprofile.wp3")}</h3>
|
<h3>${translate("walletprofile.wp3")}</h3>
|
||||||
<h4 class="lineHeight">${translate("appinfo.coreversion")}: <span style="color: #03a9f4">${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0,12) : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.coreversion")}: <span style="color: #03a9f4">${this.coreInfos.buildVersion ? (this.coreInfos.buildVersion).substring(0, 12) : ''}</span></h4>
|
||||||
<h4 class="lineHeight">${translate("appinfo.synchronizing")}... <span style="color: #03a9f4">${this.nodeInfos.syncPercent !== undefined ? this.nodeInfos.syncPercent + '%' : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.synchronizing")}... <span style="color: #03a9f4">${this.nodeInfos.syncPercent !== undefined ? this.nodeInfos.syncPercent + '%' : ''}</span></h4>
|
||||||
<h4 class="lineHeight">${translate("appinfo.blockheight")}: <span style="color: #03a9f4">${this.nodeInfos.height ? this.nodeInfos.height : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.blockheight")}: <span style="color: #03a9f4">${this.nodeInfos.height ? this.nodeInfos.height : ''}</span></h4>
|
||||||
<h4 class="lineHeight">${translate("appinfo.peers")}: <span style="color: #03a9f4">${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}</span></h4>
|
<h4 class="lineHeight">${translate("appinfo.peers")}: <span style="color: #03a9f4">${this.nodeInfos.numberOfConnections ? this.nodeInfos.numberOfConnections : ''}</span></h4>
|
||||||
@ -221,6 +163,20 @@ class CoreSyncStatus extends connect(store)(LitElement) {
|
|||||||
// ...
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Standard functions
|
||||||
|
getApiKey() {
|
||||||
|
const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
return coreNode.apiKey
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmptyArray(arr) {
|
||||||
|
if (!arr) { return true }
|
||||||
|
return arr.length === 0
|
||||||
|
}
|
||||||
|
|
||||||
|
round(number) {
|
||||||
|
return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('core-sync-status', CoreSyncStatus)
|
window.customElements.define('core-sync-status', CoreSyncStatus)
|
@ -1,366 +1,282 @@
|
|||||||
import {css, html, LitElement} from 'lit';
|
import { html, LitElement } from 'lit'
|
||||||
import {translate,} from '../../../translate'
|
import { connect } from 'pwa-helpers'
|
||||||
|
import { store } from '../../store'
|
||||||
|
import { setNewTab } from '../../redux/app/app-actions'
|
||||||
|
import { RequestQueueWithPromise } from '../../../../plugins/plugins/utils/classes'
|
||||||
|
import { translate, } from '../../../translate'
|
||||||
|
import { feedItemStyles } from '../../styles/core-css'
|
||||||
import axios from 'axios'
|
import axios from 'axios'
|
||||||
import '@material/mwc-menu';
|
import ShortUniqueId from 'short-unique-id'
|
||||||
import '@material/mwc-list/mwc-list-item.js'
|
|
||||||
import {RequestQueueWithPromise} from '../../../../plugins/plugins/utils/queue';
|
|
||||||
import '../../../../plugins/plugins/core/components/TimeAgo'
|
import '../../../../plugins/plugins/core/components/TimeAgo'
|
||||||
import {connect} from 'pwa-helpers';
|
import '@material/mwc-menu'
|
||||||
import {store} from '../../store';
|
import '@material/mwc-list/mwc-list-item.js'
|
||||||
import {setNewTab} from '../../redux/app/app-actions';
|
|
||||||
import ShortUniqueId from 'short-unique-id';
|
|
||||||
|
|
||||||
const requestQueue = new RequestQueueWithPromise(3);
|
|
||||||
const requestQueueRawData = new RequestQueueWithPromise(3);
|
|
||||||
const requestQueueStatus = new RequestQueueWithPromise(3);
|
|
||||||
|
|
||||||
|
const requestQueue = new RequestQueueWithPromise(3)
|
||||||
|
const requestQueueRawData = new RequestQueueWithPromise(3)
|
||||||
|
const requestQueueStatus = new RequestQueueWithPromise(3)
|
||||||
|
|
||||||
export class FeedItem extends connect(store)(LitElement) {
|
export class FeedItem extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
resource: { type: Object },
|
resource: { type: Object },
|
||||||
isReady: { type: Boolean},
|
isReady: { type: Boolean },
|
||||||
status: {type: Object},
|
status: { type: Object },
|
||||||
feedItem: {type: Object},
|
feedItem: { type: Object },
|
||||||
appName: {type: String},
|
appName: { type: String },
|
||||||
link: {type: String}
|
link: { type: String }
|
||||||
};
|
}
|
||||||
}
|
|
||||||
|
|
||||||
static get styles() {
|
|
||||||
return css`
|
|
||||||
* {
|
|
||||||
--mdc-theme-text-primary-on-background: var(--black);
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
:host {
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
img {
|
|
||||||
width:100%;
|
|
||||||
max-height:30vh;
|
|
||||||
border-radius: 5px;
|
|
||||||
cursor: pointer;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.smallLoading,
|
|
||||||
.smallLoading:after {
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 2px;
|
|
||||||
height: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.smallLoading {
|
|
||||||
border-width: 0.8em;
|
|
||||||
border-style: solid;
|
|
||||||
border-color: rgba(3, 169, 244, 0.2) rgba(3, 169, 244, 0.2)
|
|
||||||
rgba(3, 169, 244, 0.2) rgb(3, 169, 244);
|
|
||||||
font-size: 30px;
|
|
||||||
position: relative;
|
|
||||||
text-indent: -9999em;
|
|
||||||
transform: translateZ(0px);
|
|
||||||
animation: 1.1s linear 0s infinite normal none running loadingAnimation;
|
|
||||||
}
|
|
||||||
|
|
||||||
.defaultSize {
|
|
||||||
width: 100%;
|
|
||||||
height: 160px;
|
|
||||||
}
|
|
||||||
.parent-feed-item {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
background-color: var(--chat-bubble-bg);
|
|
||||||
flex-grow: 0;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: flex-start;
|
|
||||||
justify-content: center;
|
|
||||||
border-radius: 5px;
|
|
||||||
padding: 12px 15px 4px 15px;
|
|
||||||
min-width: 150px;
|
|
||||||
width: 100%;
|
|
||||||
box-sizing: border-box;
|
|
||||||
cursor: pointer;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
.avatar {
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
border-radius:50%;
|
|
||||||
overflow: hidden;
|
|
||||||
display:flex;
|
|
||||||
align-items:center;
|
|
||||||
}
|
|
||||||
.avatarApp {
|
|
||||||
width: 30px;
|
|
||||||
height: 30px;
|
|
||||||
border-radius:50%;
|
|
||||||
overflow: hidden;
|
|
||||||
display:flex;
|
|
||||||
align-items:center;
|
|
||||||
}
|
|
||||||
.feed-item-name {
|
|
||||||
user-select: none;
|
|
||||||
color: #03a9f4;
|
|
||||||
margin-bottom: 5px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.app-name {
|
static get styles() {
|
||||||
display: flex;
|
return [feedItemStyles]
|
||||||
justify-content: space-between;
|
}
|
||||||
align-items: center;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
mwc-menu {
|
constructor() {
|
||||||
position: absolute;
|
super()
|
||||||
}
|
this.resource = {
|
||||||
|
identifier: "",
|
||||||
|
name: "",
|
||||||
|
service: ""
|
||||||
|
}
|
||||||
|
this.status = {
|
||||||
|
status: ''
|
||||||
|
}
|
||||||
|
this.isReady = false
|
||||||
|
this.nodeUrl = this.getNodeUrl()
|
||||||
|
this.myNode = this.getMyNode()
|
||||||
|
this.hasCalledWhenDownloaded = false
|
||||||
|
this.isFetching = false
|
||||||
|
this.uid = new ShortUniqueId()
|
||||||
|
this.observer = new IntersectionObserver(entries => {
|
||||||
|
for (const entry of entries) {
|
||||||
|
if (entry.isIntersecting && this.status.status !== 'READY') {
|
||||||
|
this._fetchImage()
|
||||||
|
// Stop observing after the image has started loading
|
||||||
|
this.observer.unobserve(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
this.feedItem = null
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
let avatarImg
|
||||||
|
const avatarUrl = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.resource.name}/qortal_avatar?async=true`
|
||||||
|
avatarImg = html`<img src="${avatarUrl}" style="width:100%; height:100%;" onerror="this.onerror=null; this.src='/img/incognito.png';" />`
|
||||||
|
|
||||||
|
let avatarImgApp
|
||||||
|
const avatarUrl2 = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.appName}/qortal_avatar?async=true`
|
||||||
|
avatarImgApp = html`<img src="${avatarUrl2}" style="width:100%; height:100%;" onerror="this.onerror=null; this.src='/img/incognito.png';" />`
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<div
|
||||||
|
class=${[`image-container`, this.status.status !== 'READY' ? 'defaultSize' : '', this.status.status !== 'READY' ? 'hideImg' : '',].join(' ')}
|
||||||
|
style=" box-sizing: border-box;"
|
||||||
|
>
|
||||||
|
${this.status.status !== 'READY' ?
|
||||||
|
html`
|
||||||
|
<div style="display:flex;flex-direction:column;width:100%;height:100%;justify-content:center;align-items:center; box-sizing: border-box;">
|
||||||
|
<div class=${`smallLoading`}></div>
|
||||||
|
<p style="color: var(--black)">
|
||||||
|
${`${Math.round(this.status.percentLoaded || 0).toFixed(0)}% `}${translate('chatpage.cchange94')}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
${this.status.status === 'READY' && this.feedItem ?
|
||||||
|
html`
|
||||||
|
<div class="parent-feed-item" style="position:relative" @click=${this.goToFeedLink}>
|
||||||
|
<div style="display:flex;gap:10px;margin-bottom:5px">
|
||||||
|
<div class="avatar">${avatarImg}</div>
|
||||||
|
<span class="feed-item-name">${this.resource.name}</span>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>${this.feedItem.title}</p>
|
||||||
|
</div>
|
||||||
|
<div class="app-name">
|
||||||
|
<div class="avatarApp">${avatarImgApp}</div>
|
||||||
|
<message-time timestamp=${this.resource.created}></message-time>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
: ''
|
||||||
|
}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
@-webkit-keyframes loadingAnimation {
|
firstUpdated() {
|
||||||
0% {
|
this.observer.observe(this)
|
||||||
-webkit-transform: rotate(0deg);
|
}
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes loadingAnimation {
|
getNodeUrl() {
|
||||||
0% {
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
-webkit-transform: rotate(0deg);
|
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
transform: rotate(0deg);
|
}
|
||||||
}
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
getMyNode() {
|
||||||
super();
|
return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
this.resource = {
|
}
|
||||||
identifier: "",
|
|
||||||
name: "",
|
|
||||||
service: ""
|
|
||||||
}
|
|
||||||
this.status = {
|
|
||||||
status: ''
|
|
||||||
}
|
|
||||||
this.isReady = false
|
|
||||||
this.nodeUrl = this.getNodeUrl()
|
|
||||||
this.myNode = this.getMyNode()
|
|
||||||
this.hasCalledWhenDownloaded = false
|
|
||||||
this.isFetching = false
|
|
||||||
this.uid = new ShortUniqueId()
|
|
||||||
|
|
||||||
this.observer = new IntersectionObserver(entries => {
|
async fetchResource() {
|
||||||
for (const entry of entries) {
|
try {
|
||||||
if (entry.isIntersecting && this.status.status !== 'READY') {
|
if (this.isFetching) return
|
||||||
this._fetchImage();
|
this.isFetching = true
|
||||||
// Stop observing after the image has started loading
|
await axios.get(`${this.nodeUrl}/arbitrary/resource/properties/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`)
|
||||||
this.observer.unobserve(this);
|
this.isFetching = false
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
this.feedItem = null
|
|
||||||
}
|
|
||||||
getNodeUrl(){
|
|
||||||
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
|
||||||
|
|
||||||
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
} catch (error) {
|
||||||
}
|
this.isFetching = false
|
||||||
getMyNode(){
|
}
|
||||||
return window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
}
|
||||||
}
|
|
||||||
|
|
||||||
getApiKey() {
|
async fetchVideoUrl() {
|
||||||
const myNode =
|
await this.fetchResource()
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.knownNodes[
|
}
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
];
|
|
||||||
return myNode.apiKey;
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchResource() {
|
async getRawData() {
|
||||||
try {
|
const url = `${this.nodeUrl}/arbitrary/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`
|
||||||
if(this.isFetching) return
|
|
||||||
this.isFetching = true
|
|
||||||
await axios.get(`${this.nodeUrl}/arbitrary/resource/properties/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`)
|
|
||||||
this.isFetching = false
|
|
||||||
|
|
||||||
} catch (error) {
|
return await requestQueueRawData.enqueue(() => {
|
||||||
this.isFetching = false
|
return axios.get(url)
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchVideoUrl() {
|
updateDisplayWithPlaceholders(display, resource, rawdata) {
|
||||||
|
const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g
|
||||||
|
|
||||||
await this.fetchResource()
|
for (const key in display) {
|
||||||
|
const value = display[key]
|
||||||
|
|
||||||
}
|
display[key] = value.replace(pattern, (match, p1) => {
|
||||||
|
if (p1.startsWith('rawdata.')) {
|
||||||
|
const dataKey = p1.split('.')[1]
|
||||||
|
if (rawdata[dataKey] === undefined) {
|
||||||
|
console.error("rawdata key not found:", dataKey)
|
||||||
|
}
|
||||||
|
return rawdata[dataKey] || match
|
||||||
|
} else if (p1.startsWith('resource.')) {
|
||||||
|
const resourceKey = p1.split('.')[1]
|
||||||
|
if (resource[resourceKey] === undefined) {
|
||||||
|
console.error("resource key not found:", resourceKey)
|
||||||
|
}
|
||||||
|
return resource[resourceKey] || match
|
||||||
|
}
|
||||||
|
return match
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async getRawData(){
|
async fetchStatus() {
|
||||||
const url = `${this.nodeUrl}/arbitrary/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`
|
let isCalling = false
|
||||||
return await requestQueueRawData.enqueue(()=> {
|
let percentLoaded = 0
|
||||||
return axios.get(url)
|
let timer = 24
|
||||||
})
|
|
||||||
// const response2 = await fetch(url, {
|
|
||||||
// method: 'GET',
|
|
||||||
// headers: {
|
|
||||||
// 'Content-Type': 'application/json'
|
|
||||||
// }
|
|
||||||
// })
|
|
||||||
|
|
||||||
// const responseData2 = await response2.json()
|
const response = await requestQueueStatus.enqueue(() => {
|
||||||
// return responseData2
|
return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`)
|
||||||
}
|
})
|
||||||
|
|
||||||
updateDisplayWithPlaceholders(display, resource, rawdata) {
|
if (response && response.data && response.data.status === 'READY') {
|
||||||
const pattern = /\$\$\{([a-zA-Z0-9_\.]+)\}\$\$/g;
|
const rawData = await this.getRawData()
|
||||||
|
|
||||||
for (const key in display) {
|
const object = {
|
||||||
const value = display[key];
|
...this.resource.schema.display
|
||||||
|
}
|
||||||
|
|
||||||
display[key] = value.replace(pattern, (match, p1) => {
|
this.updateDisplayWithPlaceholders(object, {}, rawData.data)
|
||||||
if (p1.startsWith('rawdata.')) {
|
this.feedItem = object
|
||||||
const dataKey = p1.split('.')[1];
|
this.status = response.data
|
||||||
if (rawdata[dataKey] === undefined) {
|
|
||||||
console.error("rawdata key not found:", dataKey);
|
|
||||||
}
|
|
||||||
return rawdata[dataKey] || match;
|
|
||||||
} else if (p1.startsWith('resource.')) {
|
|
||||||
const resourceKey = p1.split('.')[1];
|
|
||||||
if (resource[resourceKey] === undefined) {
|
|
||||||
console.error("resource key not found:", resourceKey);
|
|
||||||
}
|
|
||||||
return resource[resourceKey] || match;
|
|
||||||
}
|
|
||||||
return match;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const intervalId = setInterval(async () => {
|
||||||
|
if (isCalling) return
|
||||||
|
isCalling = true
|
||||||
|
|
||||||
|
const data = await requestQueue.enqueue(() => {
|
||||||
|
return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`)
|
||||||
|
})
|
||||||
|
|
||||||
async fetchStatus(){
|
const res = data.data
|
||||||
let isCalling = false
|
|
||||||
let percentLoaded = 0
|
|
||||||
let timer = 24
|
|
||||||
const response = await requestQueueStatus.enqueue(()=> {
|
|
||||||
return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`)
|
|
||||||
})
|
|
||||||
if(response && response.data && response.data.status === 'READY'){
|
|
||||||
const rawData = await this.getRawData()
|
|
||||||
const object = {
|
|
||||||
...this.resource.schema.display
|
|
||||||
}
|
|
||||||
this.updateDisplayWithPlaceholders(object, {},rawData.data)
|
|
||||||
this.feedItem = object
|
|
||||||
this.status = response.data
|
|
||||||
|
|
||||||
return
|
isCalling = false
|
||||||
}
|
if (res.localChunkCount) {
|
||||||
const intervalId = setInterval(async () => {
|
if (res.percentLoaded) {
|
||||||
if (isCalling) return
|
if (res.percentLoaded === percentLoaded && res.percentLoaded !== 100) {
|
||||||
isCalling = true
|
timer = timer - 5
|
||||||
|
} else {
|
||||||
|
timer = 24
|
||||||
|
}
|
||||||
|
if (timer < 0) {
|
||||||
|
timer = 24
|
||||||
|
isCalling = true
|
||||||
|
this.status = {
|
||||||
|
...res,
|
||||||
|
status: 'REFETCHING'
|
||||||
|
}
|
||||||
|
|
||||||
const data = await requestQueue.enqueue(() => {
|
setTimeout(() => {
|
||||||
return axios.get(`${this.nodeUrl}/arbitrary/resource/status/${this.resource.service}/${this.resource.name}/${this.resource.identifier}?apiKey=${this.myNode.apiKey}`)
|
isCalling = false
|
||||||
});
|
this.fetchResource()
|
||||||
const res = data.data
|
}, 25000)
|
||||||
|
|
||||||
isCalling = false
|
return
|
||||||
if (res.localChunkCount) {
|
}
|
||||||
if (res.percentLoaded) {
|
percentLoaded = res.percentLoaded
|
||||||
if (
|
}
|
||||||
res.percentLoaded === percentLoaded &&
|
|
||||||
res.percentLoaded !== 100
|
|
||||||
) {
|
|
||||||
timer = timer - 5
|
|
||||||
} else {
|
|
||||||
timer = 24
|
|
||||||
}
|
|
||||||
if (timer < 0) {
|
|
||||||
timer = 24
|
|
||||||
isCalling = true
|
|
||||||
this.status = {
|
|
||||||
...res,
|
|
||||||
status: 'REFETCHING'
|
|
||||||
}
|
|
||||||
|
|
||||||
setTimeout(() => {
|
this.status = res
|
||||||
isCalling = false
|
|
||||||
this.fetchResource()
|
|
||||||
}, 25000)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
percentLoaded = res.percentLoaded
|
|
||||||
}
|
|
||||||
|
|
||||||
this.status = res
|
if (this.status.status === 'DOWNLOADED') {
|
||||||
if(this.status.status === 'DOWNLOADED'){
|
await this.fetchResource()
|
||||||
await this.fetchResource()
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
// check if progress is 100% and clear interval if true
|
// check if progress is 100% and clear interval if true
|
||||||
if (res.status === 'READY') {
|
if (res.status === 'READY') {
|
||||||
const rawData = await this.getRawData()
|
const rawData = await this.getRawData()
|
||||||
const object = {
|
const object = {
|
||||||
...this.resource.schema.display
|
...this.resource.schema.display
|
||||||
}
|
}
|
||||||
this.updateDisplayWithPlaceholders(object, {},rawData.data)
|
this.updateDisplayWithPlaceholders(object, {}, rawData.data)
|
||||||
this.feedItem = object
|
this.feedItem = object
|
||||||
clearInterval(intervalId)
|
clearInterval(intervalId)
|
||||||
this.status = res
|
this.status = res
|
||||||
this.isReady = true
|
this.isReady = true
|
||||||
}
|
}
|
||||||
}, 5000) // 1 second interval
|
}, 5000) // 5 second interval
|
||||||
}
|
}
|
||||||
|
|
||||||
async _fetchImage() {
|
async _fetchImage() {
|
||||||
try {
|
try {
|
||||||
await this.fetchVideoUrl()
|
await this.fetchVideoUrl()
|
||||||
await this.fetchStatus()
|
await this.fetchStatus()
|
||||||
} catch (error) { /* empty */ }
|
} catch (error) { /* empty */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated(){
|
async goToFeedLink() {
|
||||||
this.observer.observe(this);
|
try {
|
||||||
|
let newQuery = this.link
|
||||||
|
if (newQuery.endsWith('/')) {
|
||||||
|
newQuery = newQuery.slice(0, -1)
|
||||||
|
}
|
||||||
|
const res = await this.extractComponents(newQuery)
|
||||||
|
if (!res) return
|
||||||
|
const { service, name, identifier, path } = res
|
||||||
|
let query = `?service=${service}`
|
||||||
|
if (name) {
|
||||||
|
query = query + `&name=${name}`
|
||||||
|
}
|
||||||
|
if (identifier) {
|
||||||
|
query = query + `&identifier=${identifier}`
|
||||||
|
}
|
||||||
|
if (path) {
|
||||||
|
query = query + `&path=${path}`
|
||||||
|
}
|
||||||
|
|
||||||
}
|
store.dispatch(setNewTab({
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
async goToFeedLink(){
|
|
||||||
try {
|
|
||||||
let newQuery = this.link
|
|
||||||
if (newQuery.endsWith('/')) {
|
|
||||||
newQuery = newQuery.slice(0, -1)
|
|
||||||
}
|
|
||||||
const res = await this.extractComponents(newQuery)
|
|
||||||
if (!res) return
|
|
||||||
const { service, name, identifier, path } = res
|
|
||||||
let query = `?service=${service}`
|
|
||||||
if (name) {
|
|
||||||
query = query + `&name=${name}`
|
|
||||||
}
|
|
||||||
if (identifier) {
|
|
||||||
query = query + `&identifier=${identifier}`
|
|
||||||
}
|
|
||||||
if (path) {
|
|
||||||
query = query + `&path=${path}`
|
|
||||||
}
|
|
||||||
|
|
||||||
store.dispatch(setNewTab({
|
|
||||||
url: `qdn/browser/index.html${query}`,
|
url: `qdn/browser/index.html${query}`,
|
||||||
id: this.uid.rnd(),
|
id: this.uid.rnd(),
|
||||||
myPlugObj: {
|
myPlugObj: {
|
||||||
@ -373,137 +289,72 @@ getMyNode(){
|
|||||||
"menus": [],
|
"menus": [],
|
||||||
"parent": false
|
"parent": false
|
||||||
},
|
},
|
||||||
openExisting: true
|
openExisting: true
|
||||||
}))
|
}))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log({error})
|
console.log({ error })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async extractComponents(url) {
|
||||||
|
if (!url.startsWith("qortal://")) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
url = url.replace(/^(qortal\:\/\/)/, "")
|
||||||
|
|
||||||
async extractComponents(url) {
|
if (url.includes("/")) {
|
||||||
if (!url.startsWith("qortal://")) {
|
let parts = url.split("/")
|
||||||
return null
|
const service = parts[0].toUpperCase()
|
||||||
}
|
parts.shift()
|
||||||
|
const name = parts[0]
|
||||||
|
parts.shift()
|
||||||
|
let identifier
|
||||||
|
|
||||||
url = url.replace(/^(qortal\:\/\/)/, "")
|
if (parts.length > 0) {
|
||||||
if (url.includes("/")) {
|
identifier = parts[0] // Do not shift yet
|
||||||
let parts = url.split("/")
|
// Check if a resource exists with this service, name and identifier combination
|
||||||
const service = parts[0].toUpperCase()
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
parts.shift()
|
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
const name = parts[0]
|
const url = `${nodeUrl}/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${myNode.apiKey}}`
|
||||||
parts.shift()
|
|
||||||
let identifier
|
|
||||||
|
|
||||||
if (parts.length > 0) {
|
const res = await fetch(url);
|
||||||
identifier = parts[0] // Do not shift yet
|
const data = await res.json();
|
||||||
// Check if a resource exists with this service, name and identifier combination
|
if (data.totalChunkCount > 0) {
|
||||||
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
// Identifier exists, so don't include it in the path
|
||||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
parts.shift()
|
||||||
const url = `${nodeUrl}/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${myNode.apiKey}}`
|
}
|
||||||
|
else {
|
||||||
|
identifier = null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const res = await fetch(url);
|
const path = parts.join("/")
|
||||||
const data = await res.json();
|
|
||||||
if (data.totalChunkCount > 0) {
|
|
||||||
// Identifier exists, so don't include it in the path
|
|
||||||
parts.shift()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
identifier = null
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const path = parts.join("/")
|
const components = {}
|
||||||
|
components["service"] = service
|
||||||
|
components["name"] = name
|
||||||
|
components["identifier"] = identifier
|
||||||
|
components["path"] = path
|
||||||
|
return components
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
const components = {}
|
// Standard functions
|
||||||
components["service"] = service
|
getApiKey() {
|
||||||
components["name"] = name
|
const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
components["identifier"] = identifier
|
return coreNode.apiKey
|
||||||
components["path"] = path
|
}
|
||||||
return components
|
|
||||||
}
|
isEmptyArray(arr) {
|
||||||
return null
|
if (!arr) { return true }
|
||||||
|
return arr.length === 0
|
||||||
|
}
|
||||||
|
|
||||||
|
round(number) {
|
||||||
|
return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
window.customElements.define('feed-item', FeedItem)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
let avatarImg
|
|
||||||
const avatarUrl = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.resource.name}/qortal_avatar?async=true&apiKey=${this.myNode.apiKey}`;
|
|
||||||
avatarImg = html`<img
|
|
||||||
src="${avatarUrl}"
|
|
||||||
style="width:100%; height:100%;"
|
|
||||||
onerror="this.onerror=null; this.src='/img/incognito.png';"
|
|
||||||
/>`;
|
|
||||||
let avatarImgApp
|
|
||||||
const avatarUrl2 = `${this.nodeUrl}/arbitrary/THUMBNAIL/${this.appName}/qortal_avatar?async=true&apiKey=${this.myNode.apiKey}`;
|
|
||||||
avatarImgApp = html`<img
|
|
||||||
src="${avatarUrl2}"
|
|
||||||
style="width:100%; height:100%;"
|
|
||||||
onerror="this.onerror=null; this.src='/img/incognito.png';"
|
|
||||||
/>`;
|
|
||||||
return html`
|
|
||||||
<div
|
|
||||||
class=${[
|
|
||||||
`image-container`,
|
|
||||||
this.status.status !== 'READY'
|
|
||||||
? 'defaultSize'
|
|
||||||
: '',
|
|
||||||
this.status.status !== 'READY'
|
|
||||||
? 'hideImg'
|
|
||||||
: '',
|
|
||||||
].join(' ')}
|
|
||||||
style=" box-sizing: border-box;"
|
|
||||||
>
|
|
||||||
${
|
|
||||||
this.status.status !== 'READY'
|
|
||||||
? html`
|
|
||||||
<div
|
|
||||||
style="display:flex;flex-direction:column;width:100%;height:100%;justify-content:center;align-items:center; box-sizing: border-box;"
|
|
||||||
>
|
|
||||||
<div
|
|
||||||
class=${`smallLoading`}
|
|
||||||
></div>
|
|
||||||
<p style="color: var(--black)">${`${Math.round(this.status.percentLoaded || 0
|
|
||||||
).toFixed(0)}% `}${translate('chatpage.cchange94')}</p>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
: ''
|
|
||||||
}
|
|
||||||
${this.status.status === 'READY' && this.feedItem ? html`
|
|
||||||
<div class="parent-feed-item" style="position:relative" @click=${this.goToFeedLink}>
|
|
||||||
<div style="display:flex;gap:10px;margin-bottom:5px">
|
|
||||||
<div class="avatar">
|
|
||||||
${avatarImg}</div> <span class="feed-item-name">${this.resource.name}</span>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>${this.feedItem.title}</p>
|
|
||||||
</div>
|
|
||||||
<div class="app-name">
|
|
||||||
<div class="avatarApp">
|
|
||||||
${avatarImgApp}
|
|
||||||
</div>
|
|
||||||
<message-time
|
|
||||||
timestamp=${this
|
|
||||||
.resource
|
|
||||||
.created}
|
|
||||||
></message-time>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
` : ''}
|
|
||||||
|
|
||||||
</div>
|
|
||||||
|
|
||||||
`
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
customElements.define('feed-item', FeedItem);
|
|
@ -1,146 +1,42 @@
|
|||||||
// popover-component.js
|
import { html, LitElement } from 'lit'
|
||||||
import {css, html, LitElement} from 'lit';
|
import { connect } from 'pwa-helpers'
|
||||||
import {createPopper} from '@popperjs/core';
|
import { store } from '../../store'
|
||||||
import '@material/mwc-icon';
|
import { createPopper } from '@popperjs/core'
|
||||||
import {translate} from '../../../translate'
|
import { setNewTab, setSideEffectAction } from '../../redux/app/app-actions'
|
||||||
import {store} from '../../store';
|
import { translate } from '../../../translate'
|
||||||
import {connect} from 'pwa-helpers';
|
import { friendItemActionsStyles } from '../../styles/core-css'
|
||||||
import {setNewTab, setSideEffectAction} from '../../redux/app/app-actions';
|
import ShortUniqueId from 'short-unique-id'
|
||||||
import ShortUniqueId from 'short-unique-id';
|
import '@material/mwc-icon'
|
||||||
|
|
||||||
export class FriendItemActions extends connect(store)(LitElement) {
|
export class FriendItemActions extends connect(store)(LitElement) {
|
||||||
static styles = css`
|
|
||||||
:host {
|
|
||||||
display: none;
|
|
||||||
position: absolute;
|
|
||||||
background-color: var(--white);
|
|
||||||
border: 1px solid #ddd;
|
|
||||||
padding: 8px;
|
|
||||||
z-index: 10;
|
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
color: var(--black);
|
|
||||||
max-width: 250px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close-icon {
|
|
||||||
cursor: pointer;
|
|
||||||
float: right;
|
|
||||||
margin-left: 10px;
|
|
||||||
color: var(--black);
|
|
||||||
}
|
|
||||||
|
|
||||||
.send-message-button {
|
|
||||||
font-family: Roboto, sans-serif;
|
|
||||||
letter-spacing: 0.3px;
|
|
||||||
font-weight: 300;
|
|
||||||
padding: 8px 5px;
|
|
||||||
border-radius: 3px;
|
|
||||||
text-align: center;
|
|
||||||
color: var(--mdc-theme-primary);
|
|
||||||
transition: all 0.3s ease-in-out;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.send-message-button:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background-color: #03a8f485;
|
|
||||||
}
|
|
||||||
.action-parent {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
div[tabindex='0']:focus {
|
|
||||||
outline: none;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
for: { type: String, reflect: true },
|
for: { type: String, reflect: true },
|
||||||
message: { type: String },
|
message: { type: String },
|
||||||
openEditFriend: { attribute: false },
|
openEditFriend: { attribute: false },
|
||||||
name: { type: String },
|
name: { type: String },
|
||||||
closeSidePanel: { attribute: false, type: Object },
|
closeSidePanel: { attribute: false, type: Object }
|
||||||
};
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return [friendItemActionsStyles]
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super()
|
||||||
this.message = '';
|
this.message = ''
|
||||||
this.nodeUrl = this.getNodeUrl();
|
this.nodeUrl = this.getNodeUrl()
|
||||||
this.uid = new ShortUniqueId();
|
this.uid = new ShortUniqueId()
|
||||||
this.getUserAddress = this.getUserAddress.bind(this);
|
this.getUserAddress = this.getUserAddress.bind(this)
|
||||||
}
|
|
||||||
getNodeUrl() {
|
|
||||||
const myNode =
|
|
||||||
store.getState().app.nodeConfig.knownNodes[
|
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
]
|
|
||||||
|
|
||||||
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
|
||||||
}
|
|
||||||
|
|
||||||
firstUpdated() {
|
|
||||||
// We'll defer the popper attachment to the openPopover() method to ensure target availability
|
|
||||||
}
|
|
||||||
|
|
||||||
attachToTarget(target) {
|
|
||||||
if (!this.popperInstance && target) {
|
|
||||||
this.popperInstance = createPopper(target, this, {
|
|
||||||
placement: 'bottom',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
openPopover(target) {
|
|
||||||
this.attachToTarget(target);
|
|
||||||
this.style.display = 'block';
|
|
||||||
setTimeout(() => {
|
|
||||||
this.shadowRoot.getElementById('parent-div').focus();
|
|
||||||
}, 50);
|
|
||||||
}
|
|
||||||
|
|
||||||
closePopover() {
|
|
||||||
this.style.display = 'none';
|
|
||||||
if (this.popperInstance) {
|
|
||||||
this.popperInstance.destroy();
|
|
||||||
this.popperInstance = null;
|
|
||||||
}
|
|
||||||
this.requestUpdate();
|
|
||||||
}
|
|
||||||
handleBlur() {
|
|
||||||
setTimeout(() => {
|
|
||||||
this.closePopover();
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
async getUserAddress() {
|
|
||||||
try {
|
|
||||||
const url = `${this.nodeUrl}/names/${this.name}`;
|
|
||||||
const res = await fetch(url);
|
|
||||||
const result = await res.json();
|
|
||||||
if (result.error === 401) {
|
|
||||||
return '';
|
|
||||||
} else {
|
|
||||||
return result.owner;
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
return '';
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div id="parent-div" tabindex="0" @blur=${this.handleBlur}>
|
<div id="parent-div" tabindex="0" @blur=${this.handleBlur}>
|
||||||
<span class="close-icon" @click="${this.closePopover}"
|
<span class="close-icon" @click="${this.closePopover}">
|
||||||
><mwc-icon style="color: var(--black)"
|
<mwc-icon style="color: var(--black)">close</mwc-icon>
|
||||||
>close</mwc-icon
|
</span>
|
||||||
></span
|
|
||||||
>
|
|
||||||
<div class="action-parent">
|
<div class="action-parent">
|
||||||
<div
|
<div
|
||||||
class="send-message-button"
|
class="send-message-button"
|
||||||
@ -164,16 +60,15 @@ export class FriendItemActions extends connect(store)(LitElement) {
|
|||||||
myPlugObj: {
|
myPlugObj: {
|
||||||
url: 'q-chat',
|
url: 'q-chat',
|
||||||
domain: 'core',
|
domain: 'core',
|
||||||
page: 'messaging/q-chat/index.html',
|
page: 'q-chat/index.html',
|
||||||
title: 'Q-Chat',
|
title: 'Q-Chat',
|
||||||
icon: 'vaadin:chat',
|
icon: 'vaadin:chat',
|
||||||
mwcicon: 'forum',
|
mwcicon: 'forum',
|
||||||
pluginNumber: 'plugin-qhsyOnpRhT',
|
pluginNumber: 'plugin-qhsyOnpRhT',
|
||||||
menus: [],
|
menus: [],
|
||||||
parent: false,
|
parent: false
|
||||||
},
|
},
|
||||||
|
openExisting: true
|
||||||
openExisting: true,
|
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
store.dispatch(
|
store.dispatch(
|
||||||
@ -181,8 +76,8 @@ export class FriendItemActions extends connect(store)(LitElement) {
|
|||||||
type: 'openPrivateChat',
|
type: 'openPrivateChat',
|
||||||
data: {
|
data: {
|
||||||
address,
|
address,
|
||||||
name: this.name,
|
name: this.name
|
||||||
},
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
this.closePopover();
|
this.closePopover();
|
||||||
@ -208,9 +103,9 @@ export class FriendItemActions extends connect(store)(LitElement) {
|
|||||||
icon: 'vaadin:mailbox',
|
icon: 'vaadin:mailbox',
|
||||||
mwcicon: 'mail_outline',
|
mwcicon: 'mail_outline',
|
||||||
menus: [],
|
menus: [],
|
||||||
parent: false,
|
parent: false
|
||||||
},
|
},
|
||||||
openExisting: true,
|
openExisting: true
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
this.closePopover();
|
this.closePopover();
|
||||||
@ -223,26 +118,89 @@ export class FriendItemActions extends connect(store)(LitElement) {
|
|||||||
<div
|
<div
|
||||||
class="send-message-button"
|
class="send-message-button"
|
||||||
@click="${() => {
|
@click="${() => {
|
||||||
const customEvent = new CustomEvent(
|
const customEvent = new CustomEvent('open-visiting-profile', { detail: this.name });
|
||||||
'open-visiting-profile',
|
|
||||||
{
|
|
||||||
detail: this.name,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
window.dispatchEvent(customEvent);
|
window.dispatchEvent(customEvent);
|
||||||
this.closePopover();
|
this.closePopover();
|
||||||
this.closeSidePanel();
|
this.closeSidePanel();
|
||||||
}}"
|
}}"
|
||||||
>
|
>
|
||||||
<mwc-icon style="color: var(--black)"
|
<mwc-icon style="color: var(--black)">person</mwc-icon>
|
||||||
>person</mwc-icon
|
|
||||||
>
|
|
||||||
${translate('profile.profile18')}
|
${translate('profile.profile18')}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated() {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
getNodeUrl() {
|
||||||
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
|
}
|
||||||
|
|
||||||
|
attachToTarget(target) {
|
||||||
|
if (!this.popperInstance && target) {
|
||||||
|
this.popperInstance = createPopper(target, this, {
|
||||||
|
placement: 'bottom'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
openPopover(target) {
|
||||||
|
this.attachToTarget(target)
|
||||||
|
this.style.display = 'block'
|
||||||
|
setTimeout(() => {
|
||||||
|
this.shadowRoot.getElementById('parent-div').focus()
|
||||||
|
}, 50)
|
||||||
|
}
|
||||||
|
|
||||||
|
closePopover() {
|
||||||
|
this.style.display = 'none'
|
||||||
|
if (this.popperInstance) {
|
||||||
|
this.popperInstance.destroy()
|
||||||
|
this.popperInstance = null
|
||||||
|
}
|
||||||
|
this.requestUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
handleBlur() {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.closePopover()
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
async getUserAddress() {
|
||||||
|
try {
|
||||||
|
const url = `${this.nodeUrl}/names/${this.name}`
|
||||||
|
const res = await fetch(url)
|
||||||
|
const result = await res.json()
|
||||||
|
if (result.error === 401) {
|
||||||
|
return ''
|
||||||
|
} else {
|
||||||
|
return result.owner
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
return ''
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Standard functions
|
||||||
|
getApiKey() {
|
||||||
|
const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
return coreNode.apiKey
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmptyArray(arr) {
|
||||||
|
if (!arr) { return true }
|
||||||
|
return arr.length === 0
|
||||||
|
}
|
||||||
|
|
||||||
|
round(number) {
|
||||||
|
return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('friend-item-actions', FriendItemActions);
|
window.customElements.define('friend-item-actions', FriendItemActions)
|
||||||
|
@ -1,476 +1,461 @@
|
|||||||
import {html, LitElement} from 'lit';
|
import { html, LitElement } from 'lit'
|
||||||
import '@material/mwc-icon';
|
import { store } from '../../store'
|
||||||
import './friends-view'
|
import { connect } from 'pwa-helpers'
|
||||||
import {friendsViewStyles} from './friends-view-css';
|
import { translate } from '../../../translate'
|
||||||
import {connect} from 'pwa-helpers';
|
import { friendsViewStyles } from '../../styles/core-css'
|
||||||
import {store} from '../../store';
|
|
||||||
import './feed-item'
|
import './feed-item'
|
||||||
import {translate} from '../../../translate'
|
import './friends-view'
|
||||||
|
import '@material/mwc-icon'
|
||||||
import '@polymer/paper-spinner/paper-spinner-lite.js'
|
import '@polymer/paper-spinner/paper-spinner-lite.js'
|
||||||
|
|
||||||
|
const perEndpointCount = 20
|
||||||
|
const totalDesiredCount = 100
|
||||||
|
const maxResultsInMemory = 300
|
||||||
|
|
||||||
const perEndpointCount = 20;
|
|
||||||
const totalDesiredCount = 100;
|
|
||||||
const maxResultsInMemory = 300;
|
|
||||||
class FriendsFeed extends connect(store)(LitElement) {
|
class FriendsFeed extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
feed: {type: Array},
|
feed: { type: Array },
|
||||||
setHasNewFeed: {attribute:false},
|
setHasNewFeed: { attribute: false },
|
||||||
isLoading: {type: Boolean},
|
isLoading: { type: Boolean },
|
||||||
hasFetched: {type: Boolean},
|
hasFetched: { type: Boolean },
|
||||||
mySelectedFeeds: {type: Array}
|
mySelectedFeeds: { type: Array }
|
||||||
};
|
}
|
||||||
}
|
|
||||||
constructor(){
|
|
||||||
super()
|
|
||||||
this.feed = []
|
|
||||||
this.feedToRender = []
|
|
||||||
this.nodeUrl = this.getNodeUrl();
|
|
||||||
this.myNode = this.getMyNode();
|
|
||||||
this.endpoints = []
|
|
||||||
this.endpointOffsets = [] // Initialize offsets for each endpoint to 0
|
|
||||||
|
|
||||||
this.loadAndMergeData = this.loadAndMergeData.bind(this)
|
|
||||||
this.hasInitialFetch = false
|
|
||||||
this.observerHandler = this.observerHandler.bind(this);
|
|
||||||
this.elementObserver = this.elementObserver.bind(this)
|
|
||||||
this.mySelectedFeeds = []
|
|
||||||
this.getSchemas = this.getSchemas.bind(this)
|
|
||||||
this.hasFetched = false
|
|
||||||
this._updateFeeds = this._updateFeeds.bind(this)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return [friendsViewStyles];
|
return [friendsViewStyles]
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.feed = []
|
||||||
|
this.feedToRender = []
|
||||||
|
this.nodeUrl = this.getNodeUrl()
|
||||||
|
this.myNode = this.getMyNode()
|
||||||
|
this.endpoints = []
|
||||||
|
this.endpointOffsets = [] // Initialize offsets for each endpoint to 0
|
||||||
|
this.loadAndMergeData = this.loadAndMergeData.bind(this)
|
||||||
|
this.hasInitialFetch = false
|
||||||
|
this.observerHandler = this.observerHandler.bind(this)
|
||||||
|
this.elementObserver = this.elementObserver.bind(this)
|
||||||
|
this.mySelectedFeeds = []
|
||||||
|
this.getSchemas = this.getSchemas.bind(this)
|
||||||
|
this.hasFetched = false
|
||||||
|
this._updateFeeds = this._updateFeeds.bind(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<div class="container">
|
||||||
|
<div id="viewElement" class="container-body" style=${"position: relative"}>
|
||||||
|
${this.isLoading ? html`
|
||||||
|
<div style="width:100%;display: flex; justify-content:center">
|
||||||
|
<paper-spinner-lite active></paper-spinner-lite>
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
${this.hasFetched && !this.isLoading && this.feed.length === 0 ? html`
|
||||||
|
<div style="width:100%;display: flex; justify-content:center">
|
||||||
|
<p>${translate('friends.friend17')}</p>
|
||||||
|
</div>
|
||||||
|
` : ''}
|
||||||
|
${this.feedToRender.map((item) => {
|
||||||
|
return html`
|
||||||
|
<feed-item
|
||||||
|
.resource=${item}
|
||||||
|
appName=${'Q-Blog'}
|
||||||
|
link=${item.link}
|
||||||
|
>
|
||||||
|
</feed-item>
|
||||||
|
`
|
||||||
|
})}
|
||||||
|
<div id="downObserver"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
async firstUpdated() {
|
||||||
|
this.viewElement = this.shadowRoot.getElementById('viewElement')
|
||||||
|
this.downObserverElement = this.shadowRoot.getElementById('downObserver')
|
||||||
|
this.elementObserver()
|
||||||
|
|
||||||
|
try {
|
||||||
|
await new Promise((res) => {
|
||||||
|
setTimeout(() => {
|
||||||
|
res()
|
||||||
|
}, 5000)
|
||||||
|
})
|
||||||
|
|
||||||
|
if (this.mySelectedFeeds.length === 0) {
|
||||||
|
await this.getEndpoints()
|
||||||
|
await this.loadAndMergeData()
|
||||||
|
}
|
||||||
|
|
||||||
|
this.getFeedOnInterval()
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getNodeUrl() {
|
getNodeUrl() {
|
||||||
const myNode =
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
store.getState().app.nodeConfig.knownNodes[
|
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
]
|
|
||||||
|
|
||||||
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
}
|
}
|
||||||
|
|
||||||
getMyNode() {
|
getMyNode() {
|
||||||
return store.getState().app.nodeConfig.knownNodes[
|
return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateFeeds(event) {
|
_updateFeeds(event) {
|
||||||
this.mySelectedFeeds = event.detail
|
this.mySelectedFeeds = event.detail
|
||||||
this.reFetchFeedData()
|
this.reFetchFeedData()
|
||||||
this.requestUpdate()
|
this.requestUpdate()
|
||||||
}
|
}
|
||||||
|
|
||||||
connectedCallback() {
|
connectedCallback() {
|
||||||
super.connectedCallback()
|
super.connectedCallback()
|
||||||
window.addEventListener('friends-my-selected-feeds-event', this._updateFeeds) }
|
window.addEventListener('friends-my-selected-feeds-event', this._updateFeeds)
|
||||||
|
}
|
||||||
|
|
||||||
disconnectedCallback() {
|
disconnectedCallback() {
|
||||||
window.removeEventListener('friends-my-selected-feeds-event', this._updateFeeds)
|
window.removeEventListener('friends-my-selected-feeds-event', this._updateFeeds)
|
||||||
super.disconnectedCallback()
|
super.disconnectedCallback()
|
||||||
}
|
}
|
||||||
|
|
||||||
async getSchemas(){
|
async getSchemas() {
|
||||||
this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]")
|
this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]")
|
||||||
const schemas = this.mySelectedFeeds
|
const schemas = this.mySelectedFeeds
|
||||||
const getAllSchemas = (schemas || []).map(
|
|
||||||
async (schema) => {
|
|
||||||
try {
|
|
||||||
const url = `${this.nodeUrl}/arbitrary/${schema.service}/${schema.name}/${schema.identifier}`;
|
|
||||||
const res = await fetch(url)
|
|
||||||
const data = await res.json()
|
|
||||||
if(data.error) return false
|
|
||||||
return data
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error);
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
const res = await Promise.all(getAllSchemas);
|
|
||||||
return res.filter((item)=> !!item)
|
|
||||||
}
|
|
||||||
|
|
||||||
getFeedOnInterval(){
|
const getAllSchemas = (schemas || []).map(
|
||||||
let interval = null;
|
async (schema) => {
|
||||||
let stop = false;
|
|
||||||
const getAnswer = async () => {
|
|
||||||
|
|
||||||
if (!stop) {
|
|
||||||
stop = true;
|
|
||||||
try {
|
try {
|
||||||
await this.reFetchFeedData()
|
const url = `${this.nodeUrl}/arbitrary/${schema.service}/${schema.name}/${schema.identifier}`
|
||||||
} catch (error) {}
|
const res = await fetch(url)
|
||||||
stop = false;
|
const data = await res.json()
|
||||||
|
if (data.error) return false
|
||||||
|
return data
|
||||||
|
} catch (error) {
|
||||||
|
console.log(error)
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
)
|
||||||
interval = setInterval(getAnswer, 900000);
|
|
||||||
|
|
||||||
}
|
const res = await Promise.all(getAllSchemas)
|
||||||
|
return res.filter((item) => !!item)
|
||||||
async getEndpoints(){
|
|
||||||
const dynamicVars = {
|
|
||||||
|
|
||||||
}
|
|
||||||
const schemas = await this.getSchemas()
|
|
||||||
const friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]")
|
|
||||||
const names = friendList.map(friend => `name=${friend.name}`).join('&');
|
|
||||||
if(names.length === 0){
|
|
||||||
this.endpoints= []
|
|
||||||
this.endpointOffsets = Array(this.endpoints.length).fill(0);
|
|
||||||
return
|
|
||||||
}
|
|
||||||
const baseurl = `${this.nodeUrl}/arbitrary/resources/search?reverse=true&mode=ALL&exactmatchnames=true&${names}`
|
|
||||||
let formEndpoints = []
|
|
||||||
schemas.forEach((schema)=> {
|
|
||||||
const feedData = schema.feed[0]
|
|
||||||
if(feedData){
|
|
||||||
const copyFeedData = {...feedData}
|
|
||||||
const fullUrl = constructUrl(baseurl, copyFeedData.search, dynamicVars);
|
|
||||||
if(fullUrl){
|
|
||||||
formEndpoints.push({
|
|
||||||
url: fullUrl, schemaName: schema.name, schema: copyFeedData
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
})
|
|
||||||
this.endpoints= formEndpoints
|
|
||||||
this.endpointOffsets = Array(this.endpoints.length).fill(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
async firstUpdated(){
|
|
||||||
this.viewElement = this.shadowRoot.getElementById('viewElement');
|
|
||||||
this.downObserverElement =
|
|
||||||
this.shadowRoot.getElementById('downObserver');
|
|
||||||
this.elementObserver();
|
|
||||||
|
|
||||||
|
|
||||||
try {
|
|
||||||
await new Promise((res)=> {
|
|
||||||
setTimeout(() => {
|
|
||||||
res()
|
|
||||||
}, 5000);
|
|
||||||
})
|
|
||||||
if(this.mySelectedFeeds.length === 0){
|
|
||||||
await this.getEndpoints()
|
|
||||||
|
|
||||||
await this.loadAndMergeData();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.getFeedOnInterval()
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
console.log(error)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getMoreFeed(){
|
getFeedOnInterval() {
|
||||||
if(!this.hasInitialFetch) return
|
let interval = null
|
||||||
if(this.feedToRender.length === this.feed.length ) return
|
let stop = false
|
||||||
this.feedToRender = this.feed.slice(0, this.feedToRender.length + 20)
|
|
||||||
this.requestUpdate()
|
|
||||||
}
|
|
||||||
|
|
||||||
async refresh(){
|
const getAnswer = async () => {
|
||||||
try {
|
if (!stop) {
|
||||||
await this.getEndpoints()
|
stop = true
|
||||||
await this.reFetchFeedData()
|
try {
|
||||||
} catch (error) {
|
await this.reFetchFeedData()
|
||||||
|
} catch (error) { }
|
||||||
|
stop = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
interval = setInterval(getAnswer, 900000)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async getEndpoints() {
|
||||||
|
const dynamicVars = { }
|
||||||
|
const schemas = await this.getSchemas()
|
||||||
|
const friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]")
|
||||||
|
const names = friendList.map(friend => `name=${friend.name}`).join('&')
|
||||||
|
|
||||||
|
if (names.length === 0) {
|
||||||
|
this.endpoints = []
|
||||||
|
this.endpointOffsets = Array(this.endpoints.length).fill(0)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
const baseurl = `${this.nodeUrl}/arbitrary/resources/search?reverse=true&mode=ALL&exactmatchnames=true&${names}`
|
||||||
|
let formEndpoints = []
|
||||||
|
|
||||||
|
schemas.forEach((schema) => {
|
||||||
|
const feedData = schema.feed[0]
|
||||||
|
if (feedData) {
|
||||||
|
const copyFeedData = { ...feedData }
|
||||||
|
const fullUrl = constructUrl(baseurl, copyFeedData.search, dynamicVars)
|
||||||
|
if (fullUrl) {
|
||||||
|
formEndpoints.push({
|
||||||
|
url: fullUrl, schemaName: schema.name, schema: copyFeedData
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
this.endpoints = formEndpoints
|
||||||
|
this.endpointOffsets = Array(this.endpoints.length).fill(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
getMoreFeed() {
|
||||||
|
if (!this.hasInitialFetch) return
|
||||||
|
if (this.feedToRender.length === this.feed.length) return
|
||||||
|
this.feedToRender = this.feed.slice(0, this.feedToRender.length + 20)
|
||||||
|
this.requestUpdate()
|
||||||
|
}
|
||||||
|
|
||||||
|
async refresh() {
|
||||||
|
try {
|
||||||
|
await this.getEndpoints()
|
||||||
|
await this.reFetchFeedData()
|
||||||
|
} catch (error) {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
elementObserver() {
|
elementObserver() {
|
||||||
const options = {
|
const options = {
|
||||||
rootMargin: '0px',
|
rootMargin: '0px',
|
||||||
threshold: 1,
|
threshold: 1
|
||||||
};
|
}
|
||||||
|
|
||||||
// identify an element to observe
|
// identify an element to observe
|
||||||
const elementToObserve = this.downObserverElement;
|
const elementToObserve = this.downObserverElement
|
||||||
|
|
||||||
// passing it a callback function
|
// passing it a callback function
|
||||||
const observer = new IntersectionObserver(
|
const observer = new IntersectionObserver(
|
||||||
this.observerHandler,
|
this.observerHandler,
|
||||||
options
|
options
|
||||||
);
|
)
|
||||||
|
|
||||||
// call `observe()` on that MutationObserver instance,
|
// call `observe()` on that MutationObserver instance,
|
||||||
// passing it the element to observe, and the options object
|
// passing it the element to observe, and the options object
|
||||||
observer.observe(elementToObserve);
|
observer.observe(elementToObserve)
|
||||||
}
|
}
|
||||||
|
|
||||||
observerHandler(entries) {
|
observerHandler(entries) {
|
||||||
if (!entries[0].isIntersecting) {
|
if (!entries[0].isIntersecting) {
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
if (this.feedToRender.length < 20) {
|
if (this.feedToRender.length < 20) {
|
||||||
return;
|
return
|
||||||
}
|
}
|
||||||
this.getMoreFeed();
|
this.getMoreFeed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async fetchDataFromEndpoint(endpointIndex, count) {
|
async fetchDataFromEndpoint(endpointIndex, count) {
|
||||||
const offset = this.endpointOffsets[endpointIndex];
|
const offset = this.endpointOffsets[endpointIndex]
|
||||||
const url = `${this.endpoints[endpointIndex].url}&limit=${count}&offset=${offset}`;
|
const url = `${this.endpoints[endpointIndex].url}&limit=${count}&offset=${offset}`
|
||||||
const res = await fetch(url)
|
const res = await fetch(url)
|
||||||
const data = await res.json()
|
const data = await res.json()
|
||||||
return data.map((i)=> {
|
|
||||||
return {
|
|
||||||
...this.endpoints[endpointIndex],
|
|
||||||
...i
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
}
|
return data.map((i) => {
|
||||||
|
return {
|
||||||
|
...this.endpoints[endpointIndex],
|
||||||
|
...i
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async initialLoad() {
|
||||||
|
let results = []
|
||||||
|
let totalFetched = 0
|
||||||
|
let i = 0
|
||||||
|
let madeProgress = true
|
||||||
|
let exhaustedEndpoints = new Set()
|
||||||
|
|
||||||
async initialLoad() {
|
while (totalFetched < totalDesiredCount && madeProgress) {
|
||||||
let results = [];
|
madeProgress = false
|
||||||
let totalFetched = 0;
|
this.isLoading = true
|
||||||
let i = 0;
|
for (i = 0; i < this.endpoints.length; i++) {
|
||||||
let madeProgress = true;
|
if (exhaustedEndpoints.has(i)) {
|
||||||
let exhaustedEndpoints = new Set();
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
while (totalFetched < totalDesiredCount && madeProgress) {
|
const remainingCount = totalDesiredCount - totalFetched
|
||||||
madeProgress = false;
|
|
||||||
this.isLoading = true
|
|
||||||
for (i = 0; i < this.endpoints.length; i++) {
|
|
||||||
if (exhaustedEndpoints.has(i)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
const remainingCount = totalDesiredCount - totalFetched;
|
// If we've already reached the desired count, break
|
||||||
|
if (remainingCount <= 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
// If we've already reached the desired count, break
|
let fetchCount = Math.min(perEndpointCount, remainingCount)
|
||||||
if (remainingCount <= 0) {
|
let data = await this.fetchDataFromEndpoint(i, fetchCount)
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
let fetchCount = Math.min(perEndpointCount, remainingCount);
|
// Increment the offset for this endpoint by the number of items fetched
|
||||||
let data = await this.fetchDataFromEndpoint(i, fetchCount);
|
this.endpointOffsets[i] += data.length
|
||||||
|
|
||||||
// Increment the offset for this endpoint by the number of items fetched
|
if (data.length > 0) {
|
||||||
this.endpointOffsets[i] += data.length;
|
madeProgress = true
|
||||||
|
}
|
||||||
|
|
||||||
if (data.length > 0) {
|
if (data.length < fetchCount) {
|
||||||
madeProgress = true;
|
exhaustedEndpoints.add(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data.length < fetchCount) {
|
results = results.concat(data)
|
||||||
exhaustedEndpoints.add(i);
|
totalFetched += data.length
|
||||||
}
|
}
|
||||||
|
|
||||||
results = results.concat(data);
|
if (exhaustedEndpoints.size === this.endpoints.length) {
|
||||||
totalFetched += data.length;
|
break
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (exhaustedEndpoints.size === this.endpoints.length) {
|
this.isLoading = false
|
||||||
break;
|
this.hasFetched = true
|
||||||
}
|
|
||||||
}
|
|
||||||
this.isLoading = false
|
|
||||||
this.hasFetched = true;
|
|
||||||
// Trim the results if somehow they are over the totalDesiredCount
|
|
||||||
return results.slice(0, totalDesiredCount);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
// Trim the results if somehow they are over the totalDesiredCount
|
||||||
|
return results.slice(0, totalDesiredCount)
|
||||||
|
}
|
||||||
|
|
||||||
|
trimDataToLimit(data, limit) {
|
||||||
|
return data.slice(0, limit)
|
||||||
|
}
|
||||||
|
|
||||||
|
mergeData(newData, existingData) {
|
||||||
|
const existingIds = new Set(existingData.map(item => item.identifier)) // Assume each item has a unique 'id'
|
||||||
|
const uniqueNewData = newData.filter(item => !existingIds.has(item.identifier))
|
||||||
|
return uniqueNewData.concat(existingData)
|
||||||
|
}
|
||||||
|
|
||||||
|
async addExtraData(data) {
|
||||||
|
let newData = []
|
||||||
|
for (let item of data) {
|
||||||
|
let newItem = {
|
||||||
|
...item,
|
||||||
|
schema: {
|
||||||
|
...item.schema,
|
||||||
|
customParams: { ...item.schema.customParams }
|
||||||
|
|
||||||
trimDataToLimit(data, limit) {
|
}
|
||||||
return data.slice(0, limit);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
mergeData(newData, existingData) {
|
let newResource = {
|
||||||
const existingIds = new Set(existingData.map(item => item.identifier)); // Assume each item has a unique 'id'
|
identifier: newItem.identifier,
|
||||||
const uniqueNewData = newData.filter(item => !existingIds.has(item.identifier));
|
service: newItem.service,
|
||||||
return uniqueNewData.concat(existingData);
|
name: newItem.name
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (newItem.schema) {
|
||||||
|
const resource = newItem
|
||||||
|
|
||||||
async addExtraData(data){
|
let clickValue1 = newItem.schema.click;
|
||||||
let newData = []
|
|
||||||
for (let item of data) {
|
|
||||||
let newItem = {
|
|
||||||
...item,
|
|
||||||
schema: {
|
|
||||||
...item.schema,
|
|
||||||
customParams: {...item.schema.customParams}
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let newResource = {
|
|
||||||
identifier: newItem.identifier,
|
|
||||||
service: newItem.service,
|
|
||||||
name: newItem.name
|
|
||||||
}
|
|
||||||
if(newItem.schema){
|
|
||||||
const resource = newItem
|
|
||||||
|
|
||||||
let clickValue1 = newItem.schema.click;
|
|
||||||
|
|
||||||
newItem.link = replacePlaceholders(clickValue1, resource, newItem.schema.customParams)
|
newItem.link = replacePlaceholders(clickValue1, resource, newItem.schema.customParams)
|
||||||
newData.push(newItem)
|
newData.push(newItem)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return newData
|
return newData
|
||||||
|
}
|
||||||
|
|
||||||
}
|
async reFetchFeedData() {
|
||||||
async reFetchFeedData() {
|
// Resetting offsets to start fresh.
|
||||||
// Resetting offsets to start fresh.
|
this.endpointOffsets = Array(this.endpoints.length).fill(0)
|
||||||
this.endpointOffsets = Array(this.endpoints.length).fill(0);
|
await this.getEndpoints()
|
||||||
await this.getEndpoints()
|
const oldIdentifiers = new Set(this.feed.map(item => item.identifier))
|
||||||
const oldIdentifiers = new Set(this.feed.map(item => item.identifier));
|
const newData = await this.initialLoad()
|
||||||
const newData = await this.initialLoad();
|
|
||||||
|
|
||||||
// Filter out items that are already in the feed
|
// Filter out items that are already in the feed
|
||||||
const trulyNewData = newData.filter(item => !oldIdentifiers.has(item.identifier));
|
const trulyNewData = newData.filter(item => !oldIdentifiers.has(item.identifier))
|
||||||
|
|
||||||
if (trulyNewData.length > 0) {
|
if (trulyNewData.length > 0) {
|
||||||
// Adding extra data and merging with old data
|
// Adding extra data and merging with old data
|
||||||
const enhancedNewData = await this.addExtraData(trulyNewData);
|
const enhancedNewData = await this.addExtraData(trulyNewData)
|
||||||
|
|
||||||
// Merge new data with old data immutably
|
// Merge new data with old data immutably
|
||||||
this.feed = [...enhancedNewData, ...this.feed];
|
this.feed = [...enhancedNewData, ...this.feed]
|
||||||
this.feed = this.removeDuplicates(this.feed)
|
this.feed = this.removeDuplicates(this.feed)
|
||||||
this.feed.sort((a, b) => new Date(b.created) - new Date(a.created)); // Sort by timestamp, most recent first
|
this.feed.sort((a, b) => new Date(b.created) - new Date(a.created)) // Sort by timestamp, most recent first
|
||||||
this.feed = this.trimDataToLimit(this.feed, maxResultsInMemory); // Trim to the maximum allowed in memory
|
this.feed = this.trimDataToLimit(this.feed, maxResultsInMemory) // Trim to the maximum allowed in memory
|
||||||
this.feedToRender = this.feed.slice(0, 20);
|
this.feedToRender = this.feed.slice(0, 20)
|
||||||
this.hasInitialFetch = true;
|
this.hasInitialFetch = true
|
||||||
|
|
||||||
const created = trulyNewData[0].created;
|
const created = trulyNewData[0].created
|
||||||
let value = localStorage.getItem('lastSeenFeed');
|
let value = localStorage.getItem('lastSeenFeed')
|
||||||
if (((+value || 0) < created)) {
|
|
||||||
this.setHasNewFeed(true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
removeDuplicates(array) {
|
|
||||||
const seenIds = new Set();
|
|
||||||
return array.filter(item => {
|
|
||||||
if (!seenIds.has(item.identifier)) {
|
|
||||||
seenIds.add(item.identifier);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
async loadAndMergeData() {
|
|
||||||
let allData = this.feed
|
|
||||||
const newData = await this.initialLoad();
|
|
||||||
allData = await this.addExtraData(newData)
|
|
||||||
allData = this.mergeData(newData, allData);
|
|
||||||
allData.sort((a, b) => new Date(b.created) - new Date(a.created)); // Sort by timestamp, most recent first
|
|
||||||
allData = this.trimDataToLimit(allData, maxResultsInMemory); // Trim to the maximum allowed in memory
|
|
||||||
allData = this.removeDuplicates(allData)
|
|
||||||
this.feed = [...allData]
|
|
||||||
this.feedToRender = this.feed.slice(0,20)
|
|
||||||
this.hasInitialFetch = true
|
|
||||||
if(allData.length > 0){
|
|
||||||
const created = allData[0].created
|
|
||||||
let value = localStorage.getItem('lastSeenFeed')
|
|
||||||
if (((+value || 0) < created)) {
|
if (((+value || 0) < created)) {
|
||||||
this.setHasNewFeed(true)
|
this.setHasNewFeed(true)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return html`
|
|
||||||
<div class="container">
|
|
||||||
<div id="viewElement" class="container-body" style=${"position: relative"}>
|
|
||||||
${this.isLoading ? html`
|
|
||||||
<div style="width:100%;display: flex; justify-content:center">
|
|
||||||
<paper-spinner-lite active></paper-spinner-lite>
|
|
||||||
</div>
|
|
||||||
` : ''}
|
|
||||||
${this.hasFetched && !this.isLoading && this.feed.length === 0 ? html`
|
|
||||||
<div style="width:100%;display: flex; justify-content:center">
|
|
||||||
<p>${translate('friends.friend17')}</p>
|
|
||||||
</div>
|
|
||||||
` : ''}
|
|
||||||
${this.feedToRender.map((item) => {
|
|
||||||
return html`<feed-item
|
|
||||||
.resource=${item}
|
|
||||||
appName=${'Q-Blog'}
|
|
||||||
link=${item.link}
|
|
||||||
></feed-item>`;
|
|
||||||
})}
|
|
||||||
<div id="downObserver"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
removeDuplicates(array) {
|
||||||
|
const seenIds = new Set()
|
||||||
|
return array.filter(item => {
|
||||||
|
if (!seenIds.has(item.identifier)) {
|
||||||
|
seenIds.add(item.identifier)
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
return false
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
async loadAndMergeData() {
|
||||||
|
let allData = this.feed
|
||||||
|
const newData = await this.initialLoad();
|
||||||
|
allData = await this.addExtraData(newData)
|
||||||
|
allData = this.mergeData(newData, allData);
|
||||||
|
allData.sort((a, b) => new Date(b.created) - new Date(a.created)); // Sort by timestamp, most recent first
|
||||||
|
allData = this.trimDataToLimit(allData, maxResultsInMemory); // Trim to the maximum allowed in memory
|
||||||
|
allData = this.removeDuplicates(allData)
|
||||||
|
this.feed = [...allData]
|
||||||
|
this.feedToRender = this.feed.slice(0, 20)
|
||||||
|
this.hasInitialFetch = true
|
||||||
|
if (allData.length > 0) {
|
||||||
|
const created = allData[0].created
|
||||||
|
let value = localStorage.getItem('lastSeenFeed')
|
||||||
|
if (((+value || 0) < created)) {
|
||||||
|
this.setHasNewFeed(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Standard functions
|
||||||
|
getApiKey() {
|
||||||
|
const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
return coreNode.apiKey
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmptyArray(arr) {
|
||||||
|
if (!arr) { return true }
|
||||||
|
return arr.length === 0
|
||||||
|
}
|
||||||
|
|
||||||
|
round(number) {
|
||||||
|
return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('friends-feed', FriendsFeed);
|
window.customElements.define('friends-feed', FriendsFeed)
|
||||||
|
|
||||||
export function substituteDynamicVar(value, dynamicVars) {
|
export function substituteDynamicVar(value, dynamicVars) {
|
||||||
if (typeof value !== 'string') return value;
|
if (typeof value !== 'string') return value
|
||||||
|
const pattern = /\$\$\{([a-zA-Z0-9_]+)\}\$\$/g // Adjusted pattern to capture $${name}$$ with curly braces
|
||||||
const pattern = /\$\$\{([a-zA-Z0-9_]+)\}\$\$/g; // Adjusted pattern to capture $${name}$$ with curly braces
|
return value.replace(pattern, (match, p1) => {
|
||||||
|
return dynamicVars[p1] !== undefined ? dynamicVars[p1] : match
|
||||||
return value.replace(pattern, (match, p1) => {
|
})
|
||||||
return dynamicVars[p1] !== undefined ? dynamicVars[p1] : match;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export function constructUrl(base, search, dynamicVars) {
|
export function constructUrl(base, search, dynamicVars) {
|
||||||
let queryStrings = [];
|
let queryStrings = []
|
||||||
|
for (const [key, value] of Object.entries(search)) {
|
||||||
for (const [key, value] of Object.entries(search)) {
|
const substitutedValue = substituteDynamicVar(value, dynamicVars)
|
||||||
const substitutedValue = substituteDynamicVar(value, dynamicVars);
|
queryStrings.push(`${key}=${encodeURIComponent(substitutedValue)}`)
|
||||||
queryStrings.push(`${key}=${encodeURIComponent(substitutedValue)}`);
|
}
|
||||||
}
|
return queryStrings.length > 0 ? `${base}&${queryStrings.join('&')}` : base
|
||||||
|
|
||||||
return queryStrings.length > 0 ? `${base}&${queryStrings.join('&')}` : base;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
export function replacePlaceholders(template, resource, customParams) {
|
export function replacePlaceholders(template, resource, customParams) {
|
||||||
const dataSource = { resource, customParams };
|
const dataSource = { resource, customParams }
|
||||||
|
return template.replace(/\$\$\{(.*?)\}\$\$/g, (match, p1) => {
|
||||||
return template.replace(/\$\$\{(.*?)\}\$\$/g, (match, p1) => {
|
const keys = p1.split('.')
|
||||||
const keys = p1.split('.');
|
let value = dataSource
|
||||||
let value = dataSource;
|
for (let key of keys) {
|
||||||
|
if (value[key] !== undefined) {
|
||||||
for (let key of keys) {
|
value = value[key]
|
||||||
if (value[key] !== undefined) {
|
} else {
|
||||||
value = value[key];
|
return match // Return placeholder unchanged
|
||||||
} else {
|
}
|
||||||
return match; // Return placeholder unchanged
|
}
|
||||||
}
|
return value
|
||||||
}
|
})
|
||||||
return value;
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,68 +1,43 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
|
import { connect } from 'pwa-helpers'
|
||||||
|
import { store } from '../../store'
|
||||||
|
import { translate } from '../../../translate'
|
||||||
|
import { friendsSidePanelParentStyles } from '../../styles/core-css'
|
||||||
|
import './friends-side-panel'
|
||||||
import '@material/mwc-icon'
|
import '@material/mwc-icon'
|
||||||
import './friends-side-panel.js'
|
|
||||||
import '@vaadin/tooltip'
|
import '@vaadin/tooltip'
|
||||||
import {translate} from '../../../translate'
|
|
||||||
|
|
||||||
class FriendsSidePanelParent extends LitElement {
|
class FriendsSidePanelParent extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
isOpen: {type: Boolean},
|
isOpen: { type: Boolean },
|
||||||
hasNewFeed: {type: Boolean}
|
hasNewFeed: { type: Boolean }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return [friendsSidePanelParentStyles]
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
this.isOpen = false
|
this.isOpen = false
|
||||||
this.hasNewFeed = false
|
this.hasNewFeed = false
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = css`
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 16px;
|
|
||||||
border-bottom: 1px solid #e0e0e0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
padding: 16px;
|
|
||||||
}
|
|
||||||
.close {
|
|
||||||
visibility: hidden;
|
|
||||||
position: fixed;
|
|
||||||
z-index: -100;
|
|
||||||
right: -1000px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.parent-side-panel {
|
|
||||||
transform: translateX(100%); /* start from outside the right edge */
|
|
||||||
transition: transform 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
.parent-side-panel.open {
|
|
||||||
transform: translateX(0); /* slide in to its original position */
|
|
||||||
|
|
||||||
}
|
|
||||||
`
|
|
||||||
|
|
||||||
setHasNewFeed(val){
|
|
||||||
this.hasNewFeed = val
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<mwc-icon
|
<mwc-icon
|
||||||
id="friends-icon"
|
id="friends-icon"
|
||||||
@click=${()=> {
|
@click=${() => {
|
||||||
this.isOpen = !this.isOpen
|
this.isOpen = !this.isOpen
|
||||||
if(this.isOpen && this.hasNewFeed) {
|
if (this.isOpen && this.hasNewFeed) {
|
||||||
localStorage.setItem('lastSeenFeed', Date.now())
|
localStorage.setItem('lastSeenFeed', Date.now())
|
||||||
this.hasNewFeed = false
|
this.hasNewFeed = false
|
||||||
this.shadowRoot.querySelector("friends-side-panel").selected = 'feed'
|
this.shadowRoot.querySelector("friends-side-panel").selected = 'feed'
|
||||||
}
|
}
|
||||||
}} style="color: ${this.hasNewFeed ? 'green' : 'var(--black)'}; cursor:pointer;user-select:none"
|
}}
|
||||||
|
style="color: ${this.hasNewFeed ? 'green' : 'var(--black)'}; cursor:pointer;user-select:none"
|
||||||
>
|
>
|
||||||
group
|
group
|
||||||
</mwc-icon>
|
</mwc-icon>
|
||||||
@ -72,12 +47,33 @@ class FriendsSidePanelParent extends LitElement {
|
|||||||
hover-delay=${400}
|
hover-delay=${400}
|
||||||
hide-delay=${1}
|
hide-delay=${1}
|
||||||
text=${translate('friends.friend12')}
|
text=${translate('friends.friend12')}
|
||||||
>
|
></vaadin-tooltip>
|
||||||
</vaadin-tooltip>
|
<friends-side-panel .setHasNewFeed=${(val) => this.setHasNewFeed(val)} ?isOpen=${this.isOpen} .setIsOpen=${(val) => this.isOpen = val}></friends-side-panel>
|
||||||
<friends-side-panel .setHasNewFeed=${(val)=> this.setHasNewFeed(val)} ?isOpen=${this.isOpen} .setIsOpen=${(val)=> this.isOpen = val}></friends-side-panel>
|
|
||||||
|
|
||||||
`
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
firstUpdated() {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
setHasNewFeed(val) {
|
||||||
|
this.hasNewFeed = val
|
||||||
|
}
|
||||||
|
|
||||||
|
// Standard functions
|
||||||
|
getApiKey() {
|
||||||
|
const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
return coreNode.apiKey
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmptyArray(arr) {
|
||||||
|
if (!arr) { return true }
|
||||||
|
return arr.length === 0
|
||||||
|
}
|
||||||
|
|
||||||
|
round(number) {
|
||||||
|
return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('friends-side-panel-parent', FriendsSidePanelParent)
|
window.customElements.define('friends-side-panel-parent', FriendsSidePanelParent)
|
@ -1,158 +1,94 @@
|
|||||||
import {css, html, LitElement} from 'lit';
|
import { html, LitElement } from 'lit'
|
||||||
import '@material/mwc-icon';
|
import { connect } from 'pwa-helpers'
|
||||||
|
import { store } from '../../store'
|
||||||
|
import { translate } from '../../../translate'
|
||||||
|
import { friendsSidePanelStyles } from '../../styles/core-css'
|
||||||
import './friends-view'
|
import './friends-view'
|
||||||
import './friends-feed'
|
import './friends-feed'
|
||||||
import {translate} from '../../../translate'
|
import '@material/mwc-icon'
|
||||||
|
|
||||||
class FriendsSidePanel extends LitElement {
|
class FriendsSidePanel extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
setIsOpen: { attribute: false},
|
setIsOpen: { attribute: false },
|
||||||
isOpen: {type: Boolean},
|
isOpen: { type: Boolean },
|
||||||
selected: {type: String},
|
selected: { type: String },
|
||||||
setHasNewFeed: {attribute: false},
|
setHasNewFeed: { attribute: false },
|
||||||
closeSidePanel: {attribute: false, type: Object},
|
closeSidePanel: { attribute: false, type: Object },
|
||||||
openSidePanel: {attribute: false, type: Object}
|
openSidePanel: { attribute: false, type: Object }
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor(){
|
static get styles() {
|
||||||
|
return [friendsSidePanelStyles]
|
||||||
|
}
|
||||||
|
|
||||||
|
constructor() {
|
||||||
super()
|
super()
|
||||||
this.selected = 'friends'
|
this.selected = 'friends'
|
||||||
this.closeSidePanel = this.closeSidePanel.bind(this)
|
this.closeSidePanel = this.closeSidePanel.bind(this)
|
||||||
this.openSidePanel = this.openSidePanel.bind(this)
|
this.openSidePanel = this.openSidePanel.bind(this)
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
static styles = css`
|
|
||||||
:host {
|
|
||||||
display: block;
|
|
||||||
position: fixed;
|
|
||||||
top: 55px;
|
|
||||||
right: 0px;
|
|
||||||
width: 420px;
|
|
||||||
max-width: 95%;
|
|
||||||
height: calc(100vh - 55px);
|
|
||||||
background-color: var(--white);
|
|
||||||
border-left: 1px solid rgb(224, 224, 224);
|
|
||||||
z-index: 1;
|
|
||||||
transform: translateX(100%); /* start from outside the right edge */
|
|
||||||
transition: transform 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
:host([isOpen]) {
|
|
||||||
transform: unset; /* slide in to its original position */
|
|
||||||
}
|
|
||||||
|
|
||||||
.header {
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 16px;
|
|
||||||
border-bottom: 1px solid #e0e0e0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content {
|
|
||||||
padding: 16px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
flex-grow: 1;
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
.content::-webkit-scrollbar-track {
|
|
||||||
background-color: whitesmoke;
|
|
||||||
border-radius: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content::-webkit-scrollbar {
|
|
||||||
width: 12px;
|
|
||||||
border-radius: 7px;
|
|
||||||
background-color: whitesmoke;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content::-webkit-scrollbar-thumb {
|
|
||||||
background-color: rgb(180, 176, 176);
|
|
||||||
border-radius: 7px;
|
|
||||||
transition: all 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
.parent {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.active {
|
|
||||||
font-size: 16px;
|
|
||||||
background: var(--black);
|
|
||||||
color: var(--white);
|
|
||||||
padding: 5px;
|
|
||||||
border-radius: 2px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.default {
|
|
||||||
font-size: 16px;
|
|
||||||
color: var(--black);
|
|
||||||
padding: 5px;
|
|
||||||
border-radius: 2px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.default-content {
|
|
||||||
visibility: hidden;
|
|
||||||
position: absolute;
|
|
||||||
z-index: -50;
|
|
||||||
}
|
|
||||||
|
|
||||||
`;
|
|
||||||
|
|
||||||
refreshFeed(){
|
|
||||||
|
|
||||||
this.shadowRoot.querySelector('friends-feed').refresh()
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
closeSidePanel(){
|
|
||||||
this.setIsOpen(false)
|
|
||||||
}
|
|
||||||
openSidePanel(){
|
|
||||||
this.setIsOpen(true)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div class="parent">
|
<div class="parent">
|
||||||
<div class="header">
|
<div class="header">
|
||||||
<div style="display:flex;align-items:center;gap:10px">
|
<div style="display:flex;align-items:center;gap:10px">
|
||||||
<span @click=${()=> this.selected = 'friends'} class="${this.selected === 'friends' ? 'active' : 'default'}">${translate('friends.friend12')}</span>
|
<span @click=${() => this.selected = 'friends'} class="${this.selected === 'friends' ? 'active' : 'default'}">${translate('friends.friend12')}</span>
|
||||||
<span @click=${()=> this.selected = 'feed'} class="${this.selected === 'feed' ? 'active' : 'default'}">${translate('friends.friend13')}</span>
|
<span @click=${() => this.selected = 'feed'} class="${this.selected === 'feed' ? 'active' : 'default'}">${translate('friends.friend13')}</span>
|
||||||
</div>
|
</div>
|
||||||
<div style="display:flex;gap:15px;align-items:center">
|
<div style="display:flex;gap:15px;align-items:center">
|
||||||
<mwc-icon @click=${()=> {
|
<mwc-icon @click=${() => { this.refreshFeed(); }} style="color: var(--black); cursor:pointer;">
|
||||||
this.refreshFeed()
|
refresh
|
||||||
}} style="color: var(--black); cursor:pointer;">refresh</mwc-icon>
|
</mwc-icon>
|
||||||
<mwc-icon style="cursor:pointer" @click=${()=> {
|
<mwc-icon style="cursor:pointer" @click=${() => { this.setIsOpen(false); }}>
|
||||||
this.setIsOpen(false)
|
close
|
||||||
}}>close</mwc-icon>
|
</mwc-icon>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
</div>
|
|
||||||
<div class="content">
|
|
||||||
<div class="${this.selected === 'friends' ? 'active-content' : 'default-content'}">
|
|
||||||
<friends-view .openSidePanel=${this.openSidePanel} .closeSidePanel=${this.closeSidePanel} .refreshFeed=${()=>this.refreshFeed()}></friends-view>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="${this.selected === 'feed' ? 'active-content' : 'default-content'}">
|
<div class="content">
|
||||||
<friends-feed .setHasNewFeed=${(val)=> this.setHasNewFeed(val)}></friends-feed>
|
<div class="${this.selected === 'friends' ? 'active-content' : 'default-content'}">
|
||||||
|
<friends-view .openSidePanel=${this.openSidePanel} .closeSidePanel=${this.closeSidePanel} .refreshFeed=${() => this.refreshFeed()}></friends-view>
|
||||||
|
</div>
|
||||||
|
<div class="${this.selected === 'feed' ? 'active-content' : 'default-content'}">
|
||||||
|
<friends-feed .setHasNewFeed=${(val) => this.setHasNewFeed(val)}></friends-feed>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
`
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
firstUpdated() {
|
||||||
|
// ...
|
||||||
|
}
|
||||||
|
|
||||||
|
refreshFeed() {
|
||||||
|
this.shadowRoot.querySelector('friends-feed').refresh()
|
||||||
|
}
|
||||||
|
|
||||||
|
closeSidePanel() {
|
||||||
|
this.setIsOpen(false)
|
||||||
|
}
|
||||||
|
|
||||||
|
openSidePanel() {
|
||||||
|
this.setIsOpen(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Standard functions
|
||||||
|
getApiKey() {
|
||||||
|
const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
return coreNode.apiKey
|
||||||
|
}
|
||||||
|
|
||||||
|
isEmptyArray(arr) {
|
||||||
|
if (!arr) { return true }
|
||||||
|
return arr.length === 0
|
||||||
|
}
|
||||||
|
|
||||||
|
round(number) {
|
||||||
|
return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('friends-side-panel', FriendsSidePanel);
|
window.customElements.define('friends-side-panel', FriendsSidePanel)
|
@ -1,182 +0,0 @@
|
|||||||
import {css} from 'lit'
|
|
||||||
|
|
||||||
export const friendsViewStyles = css`
|
|
||||||
* {
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
.top-bar-icon {
|
|
||||||
cursor: pointer;
|
|
||||||
height: 18px;
|
|
||||||
width: 18px;
|
|
||||||
transition: 0.2s all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.top-bar-icon:hover {
|
|
||||||
color: var(--black);
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal-button {
|
|
||||||
font-family: Roboto, sans-serif;
|
|
||||||
font-size: 16px;
|
|
||||||
color: var(--mdc-theme-primary);
|
|
||||||
background-color: transparent;
|
|
||||||
padding: 8px 10px;
|
|
||||||
border-radius: 5px;
|
|
||||||
border: none;
|
|
||||||
transition: all 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close-row {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
height: 50px;
|
|
||||||
flex:0
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
.container-body {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
flex-grow: 1;
|
|
||||||
margin-top: 5px;
|
|
||||||
padding: 0px 6px;
|
|
||||||
box-sizing: border-box;
|
|
||||||
align-items: center;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container-body::-webkit-scrollbar-track {
|
|
||||||
background-color: whitesmoke;
|
|
||||||
border-radius: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container-body::-webkit-scrollbar {
|
|
||||||
width: 6px;
|
|
||||||
border-radius: 7px;
|
|
||||||
background-color: whitesmoke;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container-body::-webkit-scrollbar-thumb {
|
|
||||||
background-color: rgb(180, 176, 176);
|
|
||||||
border-radius: 7px;
|
|
||||||
transition: all 0.3s ease-in-out;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container-body::-webkit-scrollbar-thumb:hover {
|
|
||||||
background-color: rgb(148, 146, 146);
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
color: var(--black);
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
word-break: break-all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
flex-direction: column;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.chat-right-panel-label {
|
|
||||||
font-family: Montserrat, sans-serif;
|
|
||||||
color: var(--group-header);
|
|
||||||
padding: 5px;
|
|
||||||
font-size: 13px;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-info {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
justify-content: flex-start;
|
|
||||||
gap: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-name {
|
|
||||||
font-family: Raleway, sans-serif;
|
|
||||||
font-size: 20px;
|
|
||||||
color: var(--chat-bubble-msg-color);
|
|
||||||
text-align: center;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-description {
|
|
||||||
font-family: Roboto, sans-serif;
|
|
||||||
color: var(--chat-bubble-msg-color);
|
|
||||||
letter-spacing: 0.3px;
|
|
||||||
font-weight: 300;
|
|
||||||
font-size: 14px;
|
|
||||||
margin-top: 15px;
|
|
||||||
word-break: break-word;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-subheader {
|
|
||||||
font-family: Montserrat, sans-serif;
|
|
||||||
font-size: 14px;
|
|
||||||
color: var(--chat-bubble-msg-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
.group-data {
|
|
||||||
font-family: Roboto, sans-serif;
|
|
||||||
letter-spacing: 0.3px;
|
|
||||||
font-weight: 300;
|
|
||||||
font-size: 14px;
|
|
||||||
color: var(--chat-bubble-msg-color);
|
|
||||||
}
|
|
||||||
.search-results-div {
|
|
||||||
position: absolute;
|
|
||||||
top: 25px;
|
|
||||||
right: 25px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name-input {
|
|
||||||
width: 100%;
|
|
||||||
outline: 0;
|
|
||||||
border-width: 0 0 2px;
|
|
||||||
border-color: var(--mdc-theme-primary);
|
|
||||||
background-color: transparent;
|
|
||||||
padding: 10px;
|
|
||||||
font-family: Roboto, sans-serif;
|
|
||||||
font-size: 15px;
|
|
||||||
color: var(--chat-bubble-msg-color);
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name-input::selection {
|
|
||||||
background-color: var(--mdc-theme-primary);
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.name-input::placeholder {
|
|
||||||
opacity: 0.9;
|
|
||||||
color: var(--black);
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-field {
|
|
||||||
width: 100%;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-icon {
|
|
||||||
position: absolute;
|
|
||||||
right: 3px;
|
|
||||||
color: var(--chat-bubble-msg-color);
|
|
||||||
transition: hover 0.3s ease-in-out;
|
|
||||||
background: none;
|
|
||||||
border-radius: 50%;
|
|
||||||
padding: 6px 3px;
|
|
||||||
font-size: 21px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.search-icon:hover {
|
|
||||||
cursor: pointer;
|
|
||||||
background: #d7d7d75c;
|
|
||||||
}
|
|
||||||
`
|
|
@ -1,22 +1,20 @@
|
|||||||
import {html, LitElement} from 'lit';
|
import { html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers';
|
import { store } from '../../store'
|
||||||
|
import { connect } from 'pwa-helpers'
|
||||||
import '@material/mwc-button';
|
import { parentEpml } from '../show-plugin'
|
||||||
import '@material/mwc-dialog';
|
import { translate } from '../../../translate'
|
||||||
import '@polymer/paper-spinner/paper-spinner-lite.js';
|
import { friendsViewStyles } from '../../styles/core-css'
|
||||||
import '@polymer/paper-progress/paper-progress.js';
|
import './add-friends-modal'
|
||||||
import '@material/mwc-icon';
|
import './ChatSideNavHeads'
|
||||||
|
import '../../../../plugins/plugins/core/components/ChatSearchResults'
|
||||||
|
import '@material/mwc-button'
|
||||||
|
import '@material/mwc-dialog'
|
||||||
|
import '@material/mwc-icon'
|
||||||
|
import '@polymer/paper-spinner/paper-spinner-lite.js'
|
||||||
|
import '@polymer/paper-progress/paper-progress.js'
|
||||||
import '@vaadin/icon'
|
import '@vaadin/icon'
|
||||||
import '@vaadin/icons'
|
import '@vaadin/icons'
|
||||||
import '@vaadin/button';
|
import '@vaadin/button'
|
||||||
import './ChatSideNavHeads';
|
|
||||||
import '../../../../plugins/plugins/core/components/ChatSearchResults'
|
|
||||||
import './add-friends-modal'
|
|
||||||
|
|
||||||
import {translate,} from '../../../translate'
|
|
||||||
import {store} from '../../store';
|
|
||||||
import {friendsViewStyles} from './friends-view-css';
|
|
||||||
import {parentEpml} from '../show-plugin';
|
|
||||||
|
|
||||||
class FriendsView extends connect(store)(LitElement) {
|
class FriendsView extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
@ -29,94 +27,159 @@ class FriendsView extends connect(store)(LitElement) {
|
|||||||
setUserName: { attribute: false },
|
setUserName: { attribute: false },
|
||||||
friendList: { type: Array },
|
friendList: { type: Array },
|
||||||
userSelected: { type: Object },
|
userSelected: { type: Object },
|
||||||
isLoading: {type: Boolean},
|
isLoading: { type: Boolean },
|
||||||
userFoundModalOpen: {type: Boolean},
|
userFoundModalOpen: { type: Boolean },
|
||||||
userFound: { type: Array},
|
userFound: { type: Array },
|
||||||
isOpenAddFriendsModal: {type: Boolean},
|
isOpenAddFriendsModal: { type: Boolean },
|
||||||
editContent: {type: Object},
|
editContent: { type: Object },
|
||||||
mySelectedFeeds: {type: Array},
|
mySelectedFeeds: { type: Array },
|
||||||
refreshFeed: {attribute: false},
|
refreshFeed: { attribute: false },
|
||||||
closeSidePanel: {attribute: false, type: Object},
|
closeSidePanel: { attribute: false, type: Object },
|
||||||
openSidePanel: {attribute:false, type: Object}
|
openSidePanel: { attribute: false, type: Object }
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return [friendsViewStyles];
|
return [friendsViewStyles]
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super()
|
||||||
this.error = false;
|
this.error = false
|
||||||
this.observerHandler = this.observerHandler.bind(this);
|
this.observerHandler = this.observerHandler.bind(this)
|
||||||
this.viewElement = '';
|
this.viewElement = ''
|
||||||
this.downObserverElement = '';
|
this.downObserverElement = ''
|
||||||
this.myAddress =
|
this.myAddress = store.getState().app.selectedAddress.address
|
||||||
window.parent.reduxStore.getState().app.selectedAddress.address;
|
this.errorMessage = ''
|
||||||
this.errorMessage = '';
|
this.successMessage = ''
|
||||||
this.successMessage = '';
|
this.friendList = []
|
||||||
this.friendList = [];
|
this.userSelected = {}
|
||||||
this.userSelected = {};
|
this.isLoading = false
|
||||||
this.isLoading = false;
|
|
||||||
this.userFoundModalOpen = false
|
this.userFoundModalOpen = false
|
||||||
this.userFound = [];
|
this.userFound = []
|
||||||
this.nodeUrl = this.getNodeUrl();
|
this.nodeUrl = this.getNodeUrl()
|
||||||
this.myNode = this.getMyNode();
|
this.myNode = this.getMyNode()
|
||||||
this.isOpenAddFriendsModal = false
|
this.isOpenAddFriendsModal = false
|
||||||
this.editContent = null
|
this.editContent = null
|
||||||
this.addToFriendList = this.addToFriendList.bind(this)
|
this.addToFriendList = this.addToFriendList.bind(this)
|
||||||
this._updateFriends = this._updateFriends.bind(this)
|
this._updateFriends = this._updateFriends.bind(this)
|
||||||
this._updateFeed = this._updateFeed.bind(this)
|
this._updateFeed = this._updateFeed.bind(this)
|
||||||
this._addFriend = this._addFriend.bind(this)
|
this._addFriend = this._addFriend.bind(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return html`
|
||||||
|
<div class="container">
|
||||||
|
<div id="viewElement" class="container-body" style=${"position: relative"}>
|
||||||
|
<p class="group-name">My Friends</p>
|
||||||
|
<div class="search-field">
|
||||||
|
<input
|
||||||
|
type="text"
|
||||||
|
class="name-input"
|
||||||
|
?disabled=${this.isLoading}
|
||||||
|
id="sendTo"
|
||||||
|
placeholder="${translate("friends.friend1")}"
|
||||||
|
value=${this.userSelected.name ? this.userSelected.name : ''}
|
||||||
|
@keypress=${(e) => {
|
||||||
|
if (e.key === 'Enter') {
|
||||||
|
this.userSearch()
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<vaadin-icon
|
||||||
|
@click=${this.userSearch}
|
||||||
|
slot="icon"
|
||||||
|
icon="vaadin:search"
|
||||||
|
class="search-icon"
|
||||||
|
>
|
||||||
|
</vaadin-icon>
|
||||||
|
</div>
|
||||||
|
<div class="search-results-div">
|
||||||
|
<chat-search-results
|
||||||
|
.onClickFunc=${(result) => {
|
||||||
|
this.userSelected = result;
|
||||||
|
this.isOpenAddFriendsModal = true
|
||||||
|
this.userFound = [];
|
||||||
|
this.userFoundModalOpen = false;
|
||||||
|
}}
|
||||||
|
.closeFunc=${() => {
|
||||||
|
this.userFoundModalOpen = false;
|
||||||
|
this.userFound = [];
|
||||||
|
}}
|
||||||
|
.searchResults=${this.userFound}
|
||||||
|
?isOpen=${this.userFoundModalOpen}
|
||||||
|
?loading=${this.isLoading}
|
||||||
|
>
|
||||||
|
</chat-search-results>
|
||||||
|
</div>
|
||||||
|
${this.friendList.map((item) => {
|
||||||
|
return html`
|
||||||
|
<chat-side-nav-heads
|
||||||
|
activeChatHeadUrl=""
|
||||||
|
.setActiveChatHeadUrl=${(val) => { }}
|
||||||
|
.chatInfo=${item}
|
||||||
|
.openEditFriend=${(val) => this.openEditFriend(val)}
|
||||||
|
.closeSidePanel=${this.closeSidePanel}
|
||||||
|
>
|
||||||
|
</chat-side-nav-heads>
|
||||||
|
`
|
||||||
|
})}
|
||||||
|
<div id="downObserver"></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<add-friends-modal
|
||||||
|
?isOpen=${this.isOpenAddFriendsModal}
|
||||||
|
.setIsOpen=${(val) => {
|
||||||
|
this.isOpenAddFriendsModal = val
|
||||||
|
}}
|
||||||
|
.userSelected=${this.userSelected}
|
||||||
|
.onSubmit=${(val, isRemove) => this.addToFriendList(val, isRemove)}
|
||||||
|
.editContent=${this.editContent}
|
||||||
|
.onClose=${() => this.onClose()}
|
||||||
|
.mySelectedFeeds=${this.mySelectedFeeds}
|
||||||
|
>
|
||||||
|
</add-friends-modal>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated() {
|
||||||
|
this.viewElement = this.shadowRoot.getElementById('viewElement')
|
||||||
|
this.downObserverElement = this.shadowRoot.getElementById('downObserver')
|
||||||
|
this.elementObserver()
|
||||||
|
this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]")
|
||||||
|
this.friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]")
|
||||||
}
|
}
|
||||||
|
|
||||||
getNodeUrl() {
|
getNodeUrl() {
|
||||||
const myNode =
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
store.getState().app.nodeConfig.knownNodes[
|
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
]
|
|
||||||
|
|
||||||
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
}
|
}
|
||||||
|
|
||||||
getMyNode() {
|
getMyNode() {
|
||||||
return store.getState().app.nodeConfig.knownNodes[
|
return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
getMoreFriends() {}
|
getMoreFriends() { }
|
||||||
|
|
||||||
firstUpdated() {
|
|
||||||
this.viewElement = this.shadowRoot.getElementById('viewElement');
|
|
||||||
this.downObserverElement =
|
|
||||||
this.shadowRoot.getElementById('downObserver');
|
|
||||||
this.elementObserver();
|
|
||||||
this.mySelectedFeeds = JSON.parse(localStorage.getItem('friends-my-selected-feeds') || "[]")
|
|
||||||
this.friendList = JSON.parse(localStorage.getItem('friends-my-friend-list') || "[]")
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
_updateFriends(event) {
|
_updateFriends(event) {
|
||||||
this.friendList = event.detail
|
this.friendList = event.detail
|
||||||
}
|
}
|
||||||
|
|
||||||
_updateFeed(event) {
|
_updateFeed(event) {
|
||||||
this.mySelectedFeeds = event.detail
|
this.mySelectedFeeds = event.detail
|
||||||
this.requestUpdate()
|
this.requestUpdate()
|
||||||
}
|
}
|
||||||
_addFriend(event){
|
|
||||||
const name = event.detail;
|
|
||||||
const findFriend = this.friendList.find((friend)=> friend.name === name)
|
|
||||||
if(findFriend){
|
|
||||||
this.editContent = {...findFriend, mySelectedFeeds: this.mySelectedFeeds}
|
|
||||||
this.userSelected = findFriend;
|
|
||||||
|
|
||||||
|
_addFriend(event) {
|
||||||
|
const name = event.detail;
|
||||||
|
const findFriend = this.friendList.find((friend) => friend.name === name)
|
||||||
|
if (findFriend) {
|
||||||
|
this.editContent = { ...findFriend, mySelectedFeeds: this.mySelectedFeeds }
|
||||||
|
this.userSelected = findFriend
|
||||||
} else {
|
} else {
|
||||||
this.userSelected = {
|
this.userSelected = {
|
||||||
name
|
name
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
this.isOpenAddFriendsModal = true
|
this.isOpenAddFriendsModal = true
|
||||||
@ -134,7 +197,6 @@ class FriendsView extends connect(store)(LitElement) {
|
|||||||
window.removeEventListener('friends-my-friend-list-event', this._updateFriends)
|
window.removeEventListener('friends-my-friend-list-event', this._updateFriends)
|
||||||
window.removeEventListener('friends-my-selected-feeds-event', this._updateFeed)
|
window.removeEventListener('friends-my-selected-feeds-event', this._updateFeed)
|
||||||
window.removeEventListener('add-friend', this._addFriend)
|
window.removeEventListener('add-friend', this._addFriend)
|
||||||
|
|
||||||
super.disconnectedCallback()
|
super.disconnectedCallback()
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,18 +204,21 @@ class FriendsView extends connect(store)(LitElement) {
|
|||||||
const options = {
|
const options = {
|
||||||
root: this.viewElement,
|
root: this.viewElement,
|
||||||
rootMargin: '0px',
|
rootMargin: '0px',
|
||||||
threshold: 1,
|
threshold: 1
|
||||||
};
|
}
|
||||||
|
|
||||||
// identify an element to observe
|
// identify an element to observe
|
||||||
const elementToObserve = this.downObserverElement;
|
const elementToObserve = this.downObserverElement
|
||||||
|
|
||||||
// passing it a callback function
|
// passing it a callback function
|
||||||
const observer = new IntersectionObserver(
|
const observer = new IntersectionObserver(
|
||||||
this.observerHandler,
|
this.observerHandler,
|
||||||
options
|
options
|
||||||
);
|
)
|
||||||
|
|
||||||
// call `observe()` on that MutationObserver instance,
|
// call `observe()` on that MutationObserver instance,
|
||||||
// passing it the element to observe, and the options object
|
// passing it the element to observe, and the options object
|
||||||
observer.observe(elementToObserve);
|
observer.observe(elementToObserve)
|
||||||
}
|
}
|
||||||
|
|
||||||
observerHandler(entries) {
|
observerHandler(entries) {
|
||||||
@ -163,112 +228,121 @@ class FriendsView extends connect(store)(LitElement) {
|
|||||||
if (this.friendList.length < 20) {
|
if (this.friendList.length < 20) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.getMoreFriends();
|
|
||||||
|
this.getMoreFriends()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async userSearch() {
|
async userSearch() {
|
||||||
const nameValue = this.shadowRoot.getElementById('sendTo').value
|
const nameValue = this.shadowRoot.getElementById('sendTo').value
|
||||||
if(!nameValue) {
|
|
||||||
|
if (!nameValue) {
|
||||||
|
this.userFound = []
|
||||||
|
this.userFoundModalOpen = true
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const url = `${this.nodeUrl}/names/${nameValue}`
|
||||||
|
const res = await fetch(url)
|
||||||
|
const result = await res.json()
|
||||||
|
|
||||||
|
if (result.error === 401) {
|
||||||
this.userFound = []
|
this.userFound = []
|
||||||
this.userFoundModalOpen = true
|
} else {
|
||||||
return;
|
this.userFound = [
|
||||||
}
|
result
|
||||||
try {
|
]
|
||||||
const url = `${this.nodeUrl}/names/${nameValue}`
|
|
||||||
const res = await fetch(url)
|
|
||||||
const result = await res.json()
|
|
||||||
if (result.error === 401) {
|
|
||||||
this.userFound = []
|
|
||||||
} else {
|
|
||||||
this.userFound = [
|
|
||||||
result
|
|
||||||
];
|
|
||||||
}
|
|
||||||
this.userFoundModalOpen = true;
|
|
||||||
} catch (error) {
|
|
||||||
// let err4string = get("chatpage.cchange35");
|
|
||||||
// parentEpml.request('showSnackBar', `${err4string}`)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
this.userFoundModalOpen = true;
|
||||||
|
} catch (error) {
|
||||||
|
// let err4string = get("chatpage.cchange35")
|
||||||
|
// parentEpml.request('showSnackBar', `${err4string}`)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getApiKey() {
|
async myFollowName(name) {
|
||||||
const apiNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
let items = [
|
||||||
return apiNode.apiKey
|
name
|
||||||
}
|
]
|
||||||
|
|
||||||
async myFollowName(name) {
|
let namesJsonString = JSON.stringify({ "items": items })
|
||||||
let items = [
|
|
||||||
name
|
|
||||||
]
|
|
||||||
let namesJsonString = JSON.stringify({ "items": items })
|
|
||||||
|
|
||||||
return await parentEpml.request('apiCall', {
|
return await parentEpml.request('apiCall', {
|
||||||
url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
|
url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: {
|
headers: {
|
||||||
'Content-Type': 'application/json'
|
'Content-Type': 'application/json'
|
||||||
},
|
},
|
||||||
body: `${namesJsonString}`
|
body: `${namesJsonString}`
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
async unFollowName(name) {
|
async unFollowName(name) {
|
||||||
let items = [
|
let items = [
|
||||||
name
|
name
|
||||||
]
|
]
|
||||||
let namesJsonString = JSON.stringify({ "items": items })
|
|
||||||
|
|
||||||
return await parentEpml.request('apiCall', {
|
let namesJsonString = JSON.stringify({ "items": items })
|
||||||
url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
|
|
||||||
method: 'DELETE',
|
return await parentEpml.request('apiCall', {
|
||||||
headers: {
|
url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
|
||||||
'Content-Type': 'application/json'
|
method: 'DELETE',
|
||||||
},
|
headers: {
|
||||||
body: `${namesJsonString}`
|
'Content-Type': 'application/json'
|
||||||
})
|
},
|
||||||
}
|
body: `${namesJsonString}`
|
||||||
async addToFriendList(val, isRemove){
|
})
|
||||||
const copyVal = {...val}
|
}
|
||||||
|
|
||||||
|
async addToFriendList(val, isRemove) {
|
||||||
|
const copyVal = { ...val }
|
||||||
delete copyVal.mySelectedFeeds
|
delete copyVal.mySelectedFeeds
|
||||||
if(isRemove){
|
|
||||||
this.friendList = this.friendList.filter((item)=> item.name !== copyVal.name)
|
if (isRemove) {
|
||||||
}else if(this.editContent){
|
this.friendList = this.friendList.filter((item) => item.name !== copyVal.name)
|
||||||
const findFriend = this.friendList.findIndex(item=> item.name === copyVal.name)
|
} else if (this.editContent) {
|
||||||
if(findFriend !== -1){
|
const findFriend = this.friendList.findIndex(item => item.name === copyVal.name)
|
||||||
|
if (findFriend !== -1) {
|
||||||
const copyList = [...this.friendList]
|
const copyList = [...this.friendList]
|
||||||
copyList[findFriend] = copyVal
|
copyList[findFriend] = copyVal
|
||||||
this.friendList = copyList
|
this.friendList = copyList
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
this.friendList = [...this.friendList, copyVal]
|
this.friendList = [...this.friendList, copyVal]
|
||||||
}
|
}
|
||||||
if(!copyVal.willFollow || isRemove) {
|
|
||||||
|
if (!copyVal.willFollow || isRemove) {
|
||||||
await this.unFollowName(copyVal.name)
|
await this.unFollowName(copyVal.name)
|
||||||
} else if(copyVal.willFollow){
|
} else if (copyVal.willFollow) {
|
||||||
await this.myFollowName(copyVal.name)
|
await this.myFollowName(copyVal.name)
|
||||||
}
|
}
|
||||||
|
|
||||||
this.setMySelectedFeeds(val.mySelectedFeeds)
|
this.setMySelectedFeeds(val.mySelectedFeeds)
|
||||||
await new Promise((res)=> {
|
|
||||||
setTimeout(()=> {
|
await new Promise((res) => {
|
||||||
|
setTimeout(() => {
|
||||||
res()
|
res()
|
||||||
},50)
|
}, 50)
|
||||||
})
|
})
|
||||||
this.userSelected = {};
|
|
||||||
|
this.userSelected = {}
|
||||||
this.shadowRoot.getElementById('sendTo').value = ''
|
this.shadowRoot.getElementById('sendTo').value = ''
|
||||||
this.isLoading = false;
|
this.isLoading = false
|
||||||
this.isOpenAddFriendsModal = false
|
this.isOpenAddFriendsModal = false
|
||||||
this.editContent = null
|
this.editContent = null
|
||||||
this.setMyFriends(this.friendList)
|
this.setMyFriends(this.friendList)
|
||||||
if(!isRemove && this.friendList.length === 1){
|
|
||||||
|
if (!isRemove && this.friendList.length === 1) {
|
||||||
this.refreshFeed()
|
this.refreshFeed()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
setMyFriends(friendList){
|
|
||||||
|
setMyFriends(friendList) {
|
||||||
localStorage.setItem('friends-my-friend-list', JSON.stringify(friendList));
|
localStorage.setItem('friends-my-friend-list', JSON.stringify(friendList));
|
||||||
const tempSettingsData= JSON.parse(localStorage.getItem('temp-settings-data') || "{}")
|
const tempSettingsData = JSON.parse(localStorage.getItem('temp-settings-data') || "{}")
|
||||||
const newTemp = {
|
const newTemp = {
|
||||||
...tempSettingsData,
|
...tempSettingsData,
|
||||||
userLists: {
|
userLists: {
|
||||||
@ -277,18 +351,20 @@ class FriendsView extends connect(store)(LitElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
localStorage.setItem('temp-settings-data', JSON.stringify(newTemp));
|
localStorage.setItem('temp-settings-data', JSON.stringify(newTemp))
|
||||||
|
|
||||||
this.dispatchEvent(
|
this.dispatchEvent(
|
||||||
new CustomEvent('temp-settings-data-event', {
|
new CustomEvent('temp-settings-data-event', {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
composed: true
|
composed: true
|
||||||
}),
|
})
|
||||||
);
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
setMySelectedFeeds(mySelectedFeeds){
|
|
||||||
|
setMySelectedFeeds(mySelectedFeeds) {
|
||||||
this.mySelectedFeeds = mySelectedFeeds
|
this.mySelectedFeeds = mySelectedFeeds
|
||||||
const tempSettingsData= JSON.parse(localStorage.getItem('temp-settings-data') || "{}")
|
const tempSettingsData = JSON.parse(localStorage.getItem('temp-settings-data') || "{}")
|
||||||
|
|
||||||
const newTemp = {
|
const newTemp = {
|
||||||
...tempSettingsData,
|
...tempSettingsData,
|
||||||
friendsFeed: {
|
friendsFeed: {
|
||||||
@ -297,98 +373,37 @@ class FriendsView extends connect(store)(LitElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
localStorage.setItem('temp-settings-data', JSON.stringify(newTemp));
|
localStorage.setItem('temp-settings-data', JSON.stringify(newTemp))
|
||||||
localStorage.setItem('friends-my-selected-feeds', JSON.stringify(mySelectedFeeds));
|
localStorage.setItem('friends-my-selected-feeds', JSON.stringify(mySelectedFeeds))
|
||||||
}
|
|
||||||
openEditFriend(val){
|
|
||||||
this.isOpenAddFriendsModal = true
|
|
||||||
this.userSelected = val
|
|
||||||
this.editContent = {...val, mySelectedFeeds: this.mySelectedFeeds}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onClose(){
|
openEditFriend(val) {
|
||||||
|
this.isOpenAddFriendsModal = true
|
||||||
|
this.userSelected = val
|
||||||
|
this.editContent = { ...val, mySelectedFeeds: this.mySelectedFeeds }
|
||||||
|
}
|
||||||
|
|
||||||
|
onClose() {
|
||||||
this.isLoading = false;
|
this.isLoading = false;
|
||||||
this.isOpenAddFriendsModal = false
|
this.isOpenAddFriendsModal = false
|
||||||
this.editContent = null
|
this.editContent = null
|
||||||
this.userSelected = {}
|
this.userSelected = {}
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
// Standard functions
|
||||||
return html`
|
getApiKey() {
|
||||||
<div class="container">
|
const coreNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
<div id="viewElement" class="container-body" style=${"position: relative"}>
|
return coreNode.apiKey
|
||||||
<p class="group-name">My Friends</p>
|
}
|
||||||
<div class="search-field">
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
class="name-input"
|
|
||||||
?disabled=${this.isLoading}
|
|
||||||
id="sendTo"
|
|
||||||
placeholder="${translate("friends.friend1")}"
|
|
||||||
value=${this.userSelected.name ? this.userSelected.name: ''}
|
|
||||||
@keypress=${(e) => {
|
|
||||||
if(e.key === 'Enter'){
|
|
||||||
this.userSearch()
|
|
||||||
}
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<vaadin-icon
|
isEmptyArray(arr) {
|
||||||
@click=${this.userSearch}
|
if (!arr) { return true }
|
||||||
slot="icon"
|
return arr.length === 0
|
||||||
icon="vaadin:search"
|
}
|
||||||
class="search-icon">
|
|
||||||
</vaadin-icon>
|
|
||||||
|
|
||||||
</div>
|
round(number) {
|
||||||
<div class="search-results-div">
|
return (Math.round(parseFloat(number) * 1e8) / 1e8).toFixed(8)
|
||||||
<chat-search-results
|
|
||||||
.onClickFunc=${(result) => {
|
|
||||||
this.userSelected = result;
|
|
||||||
this.isOpenAddFriendsModal = true
|
|
||||||
|
|
||||||
this.userFound = [];
|
|
||||||
this.userFoundModalOpen = false;
|
|
||||||
}}
|
|
||||||
.closeFunc=${() => {
|
|
||||||
this.userFoundModalOpen = false;
|
|
||||||
this.userFound = [];
|
|
||||||
}}
|
|
||||||
.searchResults=${this.userFound}
|
|
||||||
?isOpen=${this.userFoundModalOpen}
|
|
||||||
?loading=${this.isLoading}>
|
|
||||||
</chat-search-results>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
${this.friendList.map((item) => {
|
|
||||||
return html`<chat-side-nav-heads
|
|
||||||
activeChatHeadUrl=""
|
|
||||||
.setActiveChatHeadUrl=${(val) => {
|
|
||||||
|
|
||||||
}}
|
|
||||||
.chatInfo=${item}
|
|
||||||
.openEditFriend=${(val)=> this.openEditFriend(val)}
|
|
||||||
.closeSidePanel=${this.closeSidePanel}
|
|
||||||
></chat-side-nav-heads>`;
|
|
||||||
})}
|
|
||||||
<div id="downObserver"></div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<add-friends-modal
|
|
||||||
?isOpen=${this.isOpenAddFriendsModal}
|
|
||||||
.setIsOpen=${(val)=> {
|
|
||||||
this.isOpenAddFriendsModal = val
|
|
||||||
}}
|
|
||||||
.userSelected=${this.userSelected}
|
|
||||||
.onSubmit=${(val, isRemove)=> this.addToFriendList(val, isRemove)}
|
|
||||||
.editContent=${this.editContent}
|
|
||||||
.onClose=${()=> this.onClose()}
|
|
||||||
.mySelectedFeeds=${this.mySelectedFeeds}
|
|
||||||
>
|
|
||||||
</add-friends-modal>
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('friends-view', FriendsView);
|
window.customElements.define('friends-view', FriendsView)
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,125 +1,88 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {registerTranslateConfig, translate, use} from '../../translate'
|
import { languageSelectorStyles } from '../styles/core-css'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { registerTranslateConfig, translate, use } from '../../translate'
|
||||||
|
|
||||||
registerTranslateConfig({
|
registerTranslateConfig({
|
||||||
loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
|
loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
|
||||||
})
|
})
|
||||||
|
|
||||||
const checkLanguage = localStorage.getItem('qortalLanguage')
|
const checkLanguage = localStorage.getItem('qortalLanguage')
|
||||||
|
|
||||||
if (checkLanguage === null || checkLanguage.length === 0) {
|
if (checkLanguage === null || checkLanguage.length === 0) {
|
||||||
localStorage.setItem('qortalLanguage', 'us')
|
localStorage.setItem('qortalLanguage', 'us')
|
||||||
use('us')
|
use('us')
|
||||||
} else {
|
} else {
|
||||||
use(checkLanguage)
|
use(checkLanguage)
|
||||||
}
|
}
|
||||||
|
|
||||||
class LanguageSelector extends LitElement {
|
class LanguageSelector extends LitElement {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
theme: { type: String, reflect: true }
|
theme: { type: String, reflect: true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return [
|
return [languageSelectorStyles]
|
||||||
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:
|
|
||||||
linear-gradient(45deg, transparent 50%, white 50%),
|
|
||||||
linear-gradient(135deg, white 50%, transparent 50%),
|
|
||||||
linear-gradient(to right, #03a9f4, #03a9f4);
|
|
||||||
background-position:
|
|
||||||
calc(100% - 17px) calc(0.5em + 4px),
|
|
||||||
calc(100% - 7px) calc(0.5em + 4px),
|
|
||||||
100% 0;
|
|
||||||
background-size:
|
|
||||||
10px 10px,
|
|
||||||
10px 10px,
|
|
||||||
2.2em 2.2em;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
-webkit-appearance:none;
|
|
||||||
-moz-appearance:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
*:focus {
|
constructor() {
|
||||||
outline: none;
|
super()
|
||||||
}
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
|
}
|
||||||
|
|
||||||
select option {
|
render() {
|
||||||
color: var(--black);
|
return html`
|
||||||
background: var(--white);
|
<div style="display: inline;">
|
||||||
line-height: 34px;
|
<select id="languageSelect" @change="${this.changeLanguage}">
|
||||||
}
|
<option value="us">US - ${translate("selectmenu.english")}</option>
|
||||||
`
|
<option value="de">DE - ${translate("selectmenu.german")}</option>
|
||||||
]
|
<option value="es">ES - ${translate("selectmenu.spanish")}</option>
|
||||||
}
|
<option value="et">ET - ${translate("selectmenu.estonian")}</option>
|
||||||
|
<option value="fi">FI - ${translate("selectmenu.finnish")}</option>
|
||||||
|
<option value="fr">FR - ${translate("selectmenu.french")}</option>
|
||||||
|
<option value="hr">HR - ${translate("selectmenu.croatian")}</option>
|
||||||
|
<option value="hu">HU - ${translate("selectmenu.hungarian")}</option>
|
||||||
|
<option value="hindi">IN - ${translate("selectmenu.hindi")}</option>
|
||||||
|
<option value="it">IT - ${translate("selectmenu.italian")}</option>
|
||||||
|
<option value="jp">JP - ${translate("selectmenu.japanese")}</option>
|
||||||
|
<option value="ko">KO - ${translate("selectmenu.korean")}</option>
|
||||||
|
<option value="nl">NL - ${translate("selectmenu.dutch")}</option>
|
||||||
|
<option value="no">NO - ${translate("selectmenu.norwegian")}</option>
|
||||||
|
<option value="pl">PL - ${translate("selectmenu.polish")}</option>
|
||||||
|
<option value="pt">PT - ${translate("selectmenu.portuguese")}</option>
|
||||||
|
<option value="rs">RS - ${translate("selectmenu.serbian")}</option>
|
||||||
|
<option value="ro">RO - ${translate("selectmenu.romanian")}</option>
|
||||||
|
<option value="ru">RU - ${translate("selectmenu.russian")}</option>
|
||||||
|
<option value="zht">ZHT - ${translate("selectmenu.chinese2")}</option>
|
||||||
|
<option value="zhc">ZHC - ${translate("selectmenu.chinese1")}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
firstUpdated() {
|
||||||
super()
|
const myElement = this.shadowRoot.getElementById('languageSelect')
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
myElement.addEventListener('change', () => {
|
||||||
return html`
|
this.selectElement()
|
||||||
<div style="display: inline;">
|
})
|
||||||
<select id="languageSelect" @change="${this.changeLanguage}">
|
|
||||||
<option value="us">US - ${translate("selectmenu.english")}</option>
|
|
||||||
<option value="de">DE - ${translate("selectmenu.german")}</option>
|
|
||||||
<option value="es">ES - ${translate("selectmenu.spanish")}</option>
|
|
||||||
<option value="et">ET - ${translate("selectmenu.estonian")}</option>
|
|
||||||
<option value="fi">FI - ${translate("selectmenu.finnish")}</option>
|
|
||||||
<option value="fr">FR - ${translate("selectmenu.french")}</option>
|
|
||||||
<option value="hr">HR - ${translate("selectmenu.croatian")}</option>
|
|
||||||
<option value="hu">HU - ${translate("selectmenu.hungarian")}</option>
|
|
||||||
<option value="hindi">IN - ${translate("selectmenu.hindi")}</option>
|
|
||||||
<option value="it">IT - ${translate("selectmenu.italian")}</option>
|
|
||||||
<option value="jp">JP - ${translate("selectmenu.japanese")}</option>
|
|
||||||
<option value="ko">KO - ${translate("selectmenu.korean")}</option>
|
|
||||||
<option value="nl">NL - ${translate("selectmenu.dutch")}</option>
|
|
||||||
<option value="no">NO - ${translate("selectmenu.norwegian")}</option>
|
|
||||||
<option value="pl">PL - ${translate("selectmenu.polish")}</option>
|
|
||||||
<option value="pt">PT - ${translate("selectmenu.portuguese")}</option>
|
|
||||||
<option value="rs">RS - ${translate("selectmenu.serbian")}</option>
|
|
||||||
<option value="ro">RO - ${translate("selectmenu.romanian")}</option>
|
|
||||||
<option value="ru">RU - ${translate("selectmenu.russian")}</option>
|
|
||||||
<option value="zht">ZHT - ${translate("selectmenu.chinese2")}</option>
|
|
||||||
<option value="zhc">ZHC - ${translate("selectmenu.chinese1")}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
firstUpdated() {
|
this.selectElement()
|
||||||
const myElement = this.shadowRoot.getElementById('languageSelect')
|
}
|
||||||
|
|
||||||
myElement.addEventListener("change", () => {
|
selectElement() {
|
||||||
this.selectElement()
|
const selectedLanguage = localStorage.getItem('qortalLanguage')
|
||||||
})
|
let element = this.shadowRoot.getElementById('languageSelect')
|
||||||
|
element.value = selectedLanguage
|
||||||
|
}
|
||||||
|
|
||||||
this.selectElement()
|
changeLanguage(event) {
|
||||||
}
|
use(event.target.value)
|
||||||
|
localStorage.setItem('qortalLanguage', event.target.value)
|
||||||
selectElement() {
|
}
|
||||||
const selectedLanguage = localStorage.getItem('qortalLanguage')
|
|
||||||
let element = this.shadowRoot.getElementById('languageSelect')
|
|
||||||
element.value = selectedLanguage
|
|
||||||
}
|
|
||||||
|
|
||||||
changeLanguage(event) {
|
|
||||||
use(event.target.value)
|
|
||||||
localStorage.setItem('qortalLanguage', event.target.value)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('language-selector', LanguageSelector)
|
window.customElements.define('language-selector', LanguageSelector)
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,20 +1,7 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers'
|
import { connect } from 'pwa-helpers'
|
||||||
import {store} from '../../store.js'
|
import { store } from '../../store'
|
||||||
import {stateAwait} from '../../stateAwait.js'
|
import { stateAwait } from '../../stateAwait'
|
||||||
import {get} from '../../../translate'
|
|
||||||
|
|
||||||
import '@material/mwc-button'
|
|
||||||
import '@material/mwc-icon'
|
|
||||||
import '@material/mwc-fab'
|
|
||||||
import '@polymer/iron-pages'
|
|
||||||
import '@polymer/paper-icon-button/paper-icon-button.js'
|
|
||||||
import './welcome-page.js'
|
|
||||||
import './create-account-section.js'
|
|
||||||
import './login-section.js'
|
|
||||||
import '../qort-theme-toggle.js'
|
|
||||||
|
|
||||||
import settings from '../../functional-components/settings-page.js'
|
|
||||||
import {
|
import {
|
||||||
addAutoLoadImageChat,
|
addAutoLoadImageChat,
|
||||||
addChatLastSeen,
|
addChatLastSeen,
|
||||||
@ -32,352 +19,388 @@ import {
|
|||||||
setNewTab,
|
setNewTab,
|
||||||
setSideEffectAction,
|
setSideEffectAction,
|
||||||
setTabNotifications
|
setTabNotifications
|
||||||
} from '../../redux/app/app-actions.js'
|
} from '../../redux/app/app-actions'
|
||||||
|
import settings from '../../functional-components/settings-page'
|
||||||
|
import './welcome-page'
|
||||||
|
import './create-account-section'
|
||||||
|
import './login-section'
|
||||||
|
import '../qort-theme-toggle'
|
||||||
|
import '@material/mwc-button'
|
||||||
|
import '@material/mwc-icon'
|
||||||
|
import '@material/mwc-fab'
|
||||||
|
import '@polymer/iron-pages'
|
||||||
|
import '@polymer/paper-icon-button/paper-icon-button.js'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { get } from '../../../translate'
|
||||||
|
|
||||||
window.reduxStore = store
|
window.reduxStore = store
|
||||||
|
|
||||||
window.reduxAction = {
|
window.reduxAction = {
|
||||||
addAutoLoadImageChat: addAutoLoadImageChat,
|
addAutoLoadImageChat: addAutoLoadImageChat,
|
||||||
removeAutoLoadImageChat: removeAutoLoadImageChat,
|
removeAutoLoadImageChat: removeAutoLoadImageChat,
|
||||||
addChatLastSeen: addChatLastSeen,
|
addChatLastSeen: addChatLastSeen,
|
||||||
allowQAPPAutoAuth: allowQAPPAutoAuth,
|
allowQAPPAutoAuth: allowQAPPAutoAuth,
|
||||||
removeQAPPAutoAuth: removeQAPPAutoAuth,
|
removeQAPPAutoAuth: removeQAPPAutoAuth,
|
||||||
allowQAPPAutoLists: allowQAPPAutoLists,
|
allowQAPPAutoLists: allowQAPPAutoLists,
|
||||||
removeQAPPAutoLists: removeQAPPAutoLists,
|
removeQAPPAutoLists: removeQAPPAutoLists,
|
||||||
addTabInfo: addTabInfo,
|
addTabInfo: addTabInfo,
|
||||||
setTabNotifications: setTabNotifications,
|
setTabNotifications: setTabNotifications,
|
||||||
setNewTab: setNewTab,
|
setNewTab: setNewTab,
|
||||||
setNewNotification: setNewNotification,
|
setNewNotification: setNewNotification,
|
||||||
setSideEffectAction: setSideEffectAction,
|
setSideEffectAction: setSideEffectAction,
|
||||||
allowQAPPAutoFriendsList: allowQAPPAutoFriendsList,
|
allowQAPPAutoFriendsList: allowQAPPAutoFriendsList,
|
||||||
removeQAPPAutoFriendsList: removeQAPPAutoFriendsList,
|
removeQAPPAutoFriendsList: removeQAPPAutoFriendsList,
|
||||||
allowShowSyncIndicator: allowShowSyncIndicator,
|
allowShowSyncIndicator: allowShowSyncIndicator,
|
||||||
removeShowSyncIndicator: removeShowSyncIndicator
|
removeShowSyncIndicator: removeShowSyncIndicator
|
||||||
}
|
}
|
||||||
|
|
||||||
const animationDuration = 0.7 // Seconds
|
const animationDuration = 0.7 // Seconds
|
||||||
|
|
||||||
class LoginView extends connect(store)(LitElement) {
|
class LoginView extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
loggedIn: { type: Boolean },
|
loggedIn: { type: Boolean },
|
||||||
selectedPage: { type: String },
|
selectedPage: { type: String },
|
||||||
pages: { type: Object },
|
pages: { type: Object },
|
||||||
rippleIsOpen: { type: Boolean },
|
rippleIsOpen: { type: Boolean },
|
||||||
config: { type: Object },
|
config: { type: Object },
|
||||||
rippleLoadingMessage: { type: String },
|
rippleLoadingMessage: { type: String },
|
||||||
selectedPageElement: {},
|
selectedPageElement: {},
|
||||||
nodeConfig: { type: Object },
|
nodeConfig: { type: Object },
|
||||||
theme: { type: String, reflect: true }
|
theme: { type: String, reflect: true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
constructor() {
|
||||||
return [
|
super()
|
||||||
css``
|
this.selectedPage = this.getPreSelectedPage()
|
||||||
]
|
this.selectedPageElement = {}
|
||||||
}
|
this.rippleIsOpen = false
|
||||||
|
this.pages = {
|
||||||
|
welcome: 0,
|
||||||
|
'create-account': 1,
|
||||||
|
login: 2
|
||||||
|
}
|
||||||
|
this.rippleLoadingMessage = 'Getting information'
|
||||||
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
|
}
|
||||||
|
|
||||||
getPreSelectedPage() {
|
render() {
|
||||||
return 'welcome'
|
return html`
|
||||||
}
|
<style>
|
||||||
|
|
||||||
constructor() {
|
canvas {
|
||||||
super()
|
display: block;
|
||||||
this.selectedPage = this.getPreSelectedPage()
|
vertical-align: bottom;
|
||||||
this.selectedPageElement = {}
|
}
|
||||||
this.rippleIsOpen = false
|
|
||||||
this.pages = {
|
|
||||||
welcome: 0,
|
|
||||||
'create-account': 1,
|
|
||||||
login: 2
|
|
||||||
}
|
|
||||||
this.rippleLoadingMessage = 'Getting information'
|
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
|
||||||
}
|
|
||||||
|
|
||||||
firstUpdated() {
|
.login-page {
|
||||||
|
background: var(--background);
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-attachment: fixed;
|
||||||
|
background-position: center;
|
||||||
|
height: var(--window-height);
|
||||||
|
width: 100vw;
|
||||||
|
max-width: 100vw;
|
||||||
|
max-height: var(--window-height);
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
z-index: 1;
|
||||||
|
}
|
||||||
|
|
||||||
stateAwait(state => {
|
.login-card-container {
|
||||||
return 'primary' in state.config.styles.theme.colors
|
max-width: 1240px;
|
||||||
}).catch(e => console.error(e))
|
max-height: var(--window-height);
|
||||||
|
margin-right: auto;
|
||||||
|
margin-left: auto;
|
||||||
|
width: calc(100vw);
|
||||||
|
}
|
||||||
|
|
||||||
const loginContainerPages = this.shadowRoot.querySelector('#loginContainerPages')
|
.qortal-logo {
|
||||||
const loginCard = this.shadowRoot.querySelector('#login-card')
|
margin-left: auto;
|
||||||
const navigate = e => {
|
margin-right: auto;
|
||||||
this.selectPage(e.detail.page)
|
width: 200px;
|
||||||
}
|
max-width: 40%;
|
||||||
const updatedProperty = e => {
|
z-index: 1;
|
||||||
// ...
|
}
|
||||||
const selectedPageElement = this.selectedPageElement
|
|
||||||
this.selectedPageElement = {}
|
|
||||||
setTimeout(() => { this.selectedPageElement = selectedPageElement }, 1) // Yuck
|
|
||||||
}
|
|
||||||
loginContainerPages.addEventListener('selected-item-changed', () => {
|
|
||||||
|
|
||||||
if (!loginContainerPages.selectedItem) {
|
.login-card-center-container {
|
||||||
|
max-width: 100%;
|
||||||
|
max-height: var(--window-height);
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
height: var(--window-height);
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
if (this.selectedPageElement.removeEventListener) {
|
#loginContainerPages {
|
||||||
this.selectedPageElement.removeEventListener('navigate', navigate)
|
display: inline;
|
||||||
this.selectedPageElement.removeEventListener('updatedProperty', updatedProperty)
|
}
|
||||||
}
|
|
||||||
this.selectedPageElement = {}
|
|
||||||
loginCard.classList.remove('animated')
|
|
||||||
loginCard.className += ' animated'
|
|
||||||
} else {
|
|
||||||
setTimeout(() => {
|
|
||||||
|
|
||||||
this.selectedPageElement = loginContainerPages.selectedItem
|
#loginContainerPages [page] {
|
||||||
|
background: none;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
this.selectedPageElement.addEventListener('navigate', navigate)
|
.login-card {
|
||||||
this.selectedPageElement.addEventListener('updatedProperty', updatedProperty)
|
min-width: 340px;
|
||||||
setTimeout(() => loginCard.classList.remove('animated'), animationDuration * 1000)
|
border-bottom: 2px solid var(--mdc-theme-primary);
|
||||||
}, 1)
|
border-top: 2px solid var(--mdc-theme-primary);
|
||||||
}
|
text-align: center;
|
||||||
})
|
z-index: 0;
|
||||||
}
|
padding: 0;
|
||||||
|
border: 0;
|
||||||
|
border-radius: 4px;
|
||||||
|
}
|
||||||
|
|
||||||
render() {
|
.login-card p {
|
||||||
return html`
|
margin-top: 0;
|
||||||
<style>
|
font-size: 1rem;
|
||||||
canvas {
|
font-style: italic;
|
||||||
display: block;
|
}
|
||||||
vertical-align: bottom;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-page {
|
.login-card h1 {
|
||||||
background: var(--background);
|
margin-bottom: 12px;
|
||||||
background-repeat: no-repeat;
|
font-size: 64px;
|
||||||
background-attachment: fixed;
|
}
|
||||||
background-position: center;
|
|
||||||
height: var(--window-height);
|
|
||||||
width:100vw;
|
|
||||||
max-width:100vw;
|
|
||||||
max-height:var(--window-height);
|
|
||||||
position:absolute;
|
|
||||||
top:0;
|
|
||||||
left:0;
|
|
||||||
z-index:1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-card-container {
|
.login-card h5 {
|
||||||
max-width:1240px;
|
margin-top: -16px;
|
||||||
max-height:var(--window-height);
|
margin-left: 100px;
|
||||||
margin-right: auto;
|
font-size: 14px;
|
||||||
margin-left: auto;
|
color: var(--black);
|
||||||
width: calc(100vw);
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.qortal-logo {
|
.login-card h6 {
|
||||||
margin-left: auto;
|
font-size: 12px;
|
||||||
margin-right: auto;
|
color: var(--mdc-theme-primary);
|
||||||
width:200px;
|
}
|
||||||
max-width:40%;
|
|
||||||
z-index:1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-card-center-container {
|
.login-card iron-pages {
|
||||||
max-width:100%;
|
height: 100%;
|
||||||
max-height:var(--window-height);
|
margin-top: -16px;
|
||||||
display: flex;
|
}
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
height: var(--window-height);
|
|
||||||
overflow:hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
#loginContainerPages {
|
.backButton {
|
||||||
display:inline;
|
padding-top: 18px;
|
||||||
}
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
#loginContainerPages [page] {
|
#login-pages-nav {
|
||||||
background: none;
|
text-align: left;
|
||||||
padding:0;
|
padding: 12px 0 8px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-card {
|
#nav-next {
|
||||||
min-width: 340px;
|
float: right;
|
||||||
border-bottom: 2px solid var(--mdc-theme-primary);
|
}
|
||||||
border-top: 2px solid var(--mdc-theme-primary);
|
|
||||||
text-align:center;
|
|
||||||
z-index:0;
|
|
||||||
padding:0;
|
|
||||||
border: 0;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-card p {
|
@media only screen and (min-width: ${getComputedStyle(document.body).getPropertyValue('--layout-breakpoint-tablet')}) {
|
||||||
margin-top: 0;
|
|
||||||
font-size: 1rem;
|
|
||||||
font-style: italic;
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-card h1 {
|
/* Desktop/tablet */
|
||||||
margin-bottom:12px;
|
.login-card {
|
||||||
font-size:64px;
|
max-width: 460px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.login-card h5 {
|
#loginContainerPages [page] {
|
||||||
margin-top: -16px;
|
border-radius: 4px;
|
||||||
margin-left: 100px;
|
}
|
||||||
font-size: 14px;
|
|
||||||
color: var(--black);
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-card h6 {
|
#loginContainerPages [page="welcome"] {}
|
||||||
font-size: 12px;
|
}
|
||||||
color: var(--mdc-theme-primary);
|
|
||||||
}
|
|
||||||
|
|
||||||
.login-card iron-pages {
|
@media only screen and (max-width: ${getComputedStyle(document.body).getPropertyValue('--layout-breakpoint-tablet')}) {
|
||||||
height:100%;
|
|
||||||
margin-top: -16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.backButton {
|
/* Mobile */
|
||||||
padding-top:18px;
|
.qortal-logo {
|
||||||
text-align:center;
|
display: none;
|
||||||
}
|
visibility: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
#login-pages-nav {
|
.login-card {
|
||||||
text-align: left;
|
width: 100%;
|
||||||
padding: 12px 0 8px 0;
|
margin: 0;
|
||||||
}
|
top: 0;
|
||||||
|
max-width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
#nav-next {
|
.backButton {
|
||||||
float: right;
|
text-align: left;
|
||||||
}
|
padding-left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
@media only screen and (min-width: ${getComputedStyle(document.body).getPropertyValue('--layout-breakpoint-tablet')}) {
|
.login-card h5 {
|
||||||
/* Desktop/tablet */
|
margin-top: 0px;
|
||||||
.login-card {
|
margin-left: 0px;
|
||||||
max-width:460px;
|
font-size: 14px;
|
||||||
}
|
color: var(--black);
|
||||||
#loginContainerPages [page] {
|
}
|
||||||
border-radius: 4px;
|
}
|
||||||
}
|
|
||||||
#loginContainerPages [page="welcome"] {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media only screen and (max-width: ${getComputedStyle(document.body).getPropertyValue('--layout-breakpoint-tablet')}) {
|
@keyframes fade {
|
||||||
/* Mobile */
|
from {
|
||||||
.qortal-logo {
|
opacity: 0;
|
||||||
display:none;
|
transform: translateX(-20%);
|
||||||
visibility:hidden;
|
}
|
||||||
}
|
|
||||||
.login-card {
|
|
||||||
width:100%;
|
|
||||||
margin:0;
|
|
||||||
top:0;
|
|
||||||
max-width:100%;
|
|
||||||
}
|
|
||||||
.backButton {
|
|
||||||
text-align: left;
|
|
||||||
padding-left:12px;
|
|
||||||
}
|
|
||||||
.login-card h5 {
|
|
||||||
margin-top: 0px;
|
|
||||||
margin-left: 0px;
|
|
||||||
font-size: 14px;
|
|
||||||
color: var(--black);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes fade {
|
to {
|
||||||
from {
|
opacity: 1;
|
||||||
opacity: 0;
|
transform: translateX(0);
|
||||||
transform: translateX(-20%);
|
}
|
||||||
}
|
}
|
||||||
to {
|
|
||||||
opacity: 1;
|
|
||||||
transform: translateX(0);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes grow-up {
|
@keyframes grow-up {
|
||||||
from {
|
from {
|
||||||
overflow:hidden;
|
overflow: hidden;
|
||||||
max-height:0;
|
max-height: 0;
|
||||||
}
|
}
|
||||||
to {
|
|
||||||
overflow:hidden;
|
|
||||||
max-height:var(--window-height);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
iron-pages .animated, .animated {
|
to {
|
||||||
animation-duration: ${animationDuration}s;
|
overflow: hidden;
|
||||||
animation-name: grow-up;
|
max-height: var(--window-height);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
div[page] > paper-icon-button {
|
iron-pages .animated,
|
||||||
margin:12px;
|
.animated {
|
||||||
}
|
animation-duration: ${animationDuration}s;
|
||||||
|
animation-name: grow-up;
|
||||||
|
}
|
||||||
|
|
||||||
.corner-box {
|
div[page]>paper-icon-button {
|
||||||
border-color: var(--mdc-theme-primary) !important;
|
margin: 12px;
|
||||||
}
|
}
|
||||||
|
|
||||||
[hidden] {
|
.corner-box {
|
||||||
visibility: hidden;
|
border-color: var(--mdc-theme-primary) !important;
|
||||||
display: none;
|
}
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<div class="login-page" ?hidden=${this.loggedIn}>
|
|
||||||
<mwc-fab icon="settings" style="position:fixed; right:24px; bottom:24px;" @click=${() => settings.show()}></mwc-fab>
|
|
||||||
<span style="position:fixed; left:24px; bottom:24px;"><qort-theme-toggle></qort-theme-toggle></span>
|
|
||||||
<div class="login-card-container">
|
|
||||||
<div class="login-card-center-container">
|
|
||||||
<div class="login-card" id="login-card">
|
|
||||||
<img class="qortal-logo" src="${this.config.coin.logo}">
|
|
||||||
<h5 ?hidden="${this.selectedPage != "welcome"}">UI: v${this.nodeConfig.version ? this.nodeConfig.version : ''}</h5>
|
|
||||||
${this.renderSelectedNodeOnStart()}
|
|
||||||
<iron-pages selected="${this.selectedPage}" attr-for-selected="page" id="loginContainerPages">
|
|
||||||
<welcome-page @next=${e => this.selectedPageElement.next(e)} page="welcome"></welcome-page>
|
|
||||||
<create-account-section @next=${e => this.selectedPageElement.next(e)} page="create-account"></create-account-section>
|
|
||||||
<login-section @next=${e => this.selectedPageElement.next(e)} page="login"></login-section>
|
|
||||||
</iron-pages>
|
|
||||||
<div id="login-pages-nav" ?hidden="${this.selectedPageElement.hideNav}">
|
|
||||||
<mwc-button @click=${e => this.selectedPageElement.back(e)} id="nav-back" ?hidden="${this.selectedPageElement.backHidden}" ?disabled="${this.selectedPageElement.backDisabled}">
|
|
||||||
<mwc-icon>keyboard_arrow_left</mwc-icon>${this.selectedPageElement.backText}
|
|
||||||
</mwc-button>
|
|
||||||
<mwc-button @click=${e => this.selectedPageElement.next(e)} id="nav-next" ?hidden="${this.selectedPageElement.nextHidden}" ?disabled="${this.selectedPageElement.nextDisabled}">
|
|
||||||
${this.selectedPageElement.nextText}<mwc-icon>keyboard_arrow_right</mwc-icon>
|
|
||||||
</mwc-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
renderSelectedNodeOnStart() {
|
[hidden] {
|
||||||
const selectedNodeIndexOnStart = localStorage.getItem('mySelectedNode')
|
visibility: hidden;
|
||||||
const catchSavedNodes = JSON.parse(localStorage.getItem('myQortalNodes'))
|
display: none;
|
||||||
const selectedNodeOnStart = catchSavedNodes[selectedNodeIndexOnStart]
|
}
|
||||||
const selectedNameOnStart = `${selectedNodeOnStart.name}`
|
</style>
|
||||||
const selectedNodeUrlOnStart = `${selectedNodeOnStart.protocol + '://' + selectedNodeOnStart.domain +':' + selectedNodeOnStart.port}`
|
<div class="login-page" ?hidden=${this.loggedIn}>
|
||||||
|
<mwc-fab icon="settings" style="position:fixed; right:24px; bottom:24px;" @click=${() => settings.show()}></mwc-fab>
|
||||||
|
<span style="position:fixed; left:24px; bottom:24px;">
|
||||||
|
<qort-theme-toggle></qort-theme-toggle>
|
||||||
|
</span>
|
||||||
|
<div class="login-card-container">
|
||||||
|
<div class="login-card-center-container">
|
||||||
|
<div class="login-card" id="login-card">
|
||||||
|
<img class="qortal-logo" src="${this.config.coin.logo}">
|
||||||
|
<h5 ?hidden="${this.selectedPage != "welcome"}">UI: v${this.nodeConfig.version ? this.nodeConfig.version : ''}</h5>
|
||||||
|
${this.renderSelectedNodeOnStart()}
|
||||||
|
<iron-pages selected="${this.selectedPage}" attr-for-selected="page" id="loginContainerPages">
|
||||||
|
<welcome-page @next=${e => this.selectedPageElement.next(e)} page="welcome"></welcome-page>
|
||||||
|
<create-account-section @next=${e => this.selectedPageElement.next(e)} page="create-account"></create-account-section>
|
||||||
|
<login-section @next=${e => this.selectedPageElement.next(e)} page="login"></login-section>
|
||||||
|
</iron-pages>
|
||||||
|
<div id="login-pages-nav" ?hidden="${this.selectedPageElement.hideNav}">
|
||||||
|
<mwc-button
|
||||||
|
@click=${e => this.selectedPageElement.back(e)}
|
||||||
|
id="nav-back"
|
||||||
|
?hidden="${this.selectedPageElement.backHidden}"
|
||||||
|
?disabled="${this.selectedPageElement.backDisabled}"
|
||||||
|
>
|
||||||
|
<mwc-icon>keyboard_arrow_left</mwc-icon>
|
||||||
|
${this.selectedPageElement.backText}
|
||||||
|
</mwc-button>
|
||||||
|
<mwc-button
|
||||||
|
@click=${e => this.selectedPageElement.next(e)}
|
||||||
|
id="nav-next"
|
||||||
|
?hidden="${this.selectedPageElement.nextHidden}"
|
||||||
|
?disabled="${this.selectedPageElement.nextDisabled}"
|
||||||
|
>
|
||||||
|
${this.selectedPageElement.nextText}
|
||||||
|
<mwc-icon>keyboard_arrow_right</mwc-icon>
|
||||||
|
</mwc-button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
let connectString = get('settings.snack2')
|
firstUpdated() {
|
||||||
|
stateAwait(state => {
|
||||||
|
return 'primary' in state.config.styles.theme.colors
|
||||||
|
}).catch(e => console.error(e))
|
||||||
|
|
||||||
return html`<h6>${connectString} : ${selectedNameOnStart} ${selectedNodeUrlOnStart}</h6>`
|
const loginContainerPages = this.shadowRoot.querySelector('#loginContainerPages')
|
||||||
}
|
const loginCard = this.shadowRoot.querySelector('#login-card')
|
||||||
|
|
||||||
selectPage(newPage) {
|
const navigate = e => {
|
||||||
this.selectedPage = newPage
|
this.selectPage(e.detail.page)
|
||||||
}
|
}
|
||||||
|
|
||||||
stateChanged(state) {
|
const updatedProperty = e => {
|
||||||
if (this.loggedIn && !state.app.loggedIn) this.cleanup()
|
const selectedPageElement = this.selectedPageElement
|
||||||
this.loggedIn = state.app.loggedIn
|
|
||||||
this.config = state.config
|
|
||||||
this.nodeConfig = state.app.nodeConfig
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanup() {
|
this.selectedPageElement = {}
|
||||||
this.selectedPage = 'welcome'
|
|
||||||
}
|
setTimeout(() => { this.selectedPageElement = selectedPageElement }, 1)
|
||||||
|
}
|
||||||
|
|
||||||
|
loginContainerPages.addEventListener('selected-item-changed', () => {
|
||||||
|
if (!loginContainerPages.selectedItem) {
|
||||||
|
|
||||||
|
if (this.selectedPageElement.removeEventListener) {
|
||||||
|
this.selectedPageElement.removeEventListener('navigate', navigate)
|
||||||
|
this.selectedPageElement.removeEventListener('updatedProperty', updatedProperty)
|
||||||
|
}
|
||||||
|
|
||||||
|
this.selectedPageElement = {}
|
||||||
|
|
||||||
|
loginCard.classList.remove('animated')
|
||||||
|
loginCard.className += ' animated'
|
||||||
|
} else {
|
||||||
|
setTimeout(() => {
|
||||||
|
this.selectedPageElement = loginContainerPages.selectedItem
|
||||||
|
this.selectedPageElement.addEventListener('navigate', navigate)
|
||||||
|
this.selectedPageElement.addEventListener('updatedProperty', updatedProperty)
|
||||||
|
|
||||||
|
setTimeout(() => loginCard.classList.remove('animated'), animationDuration * 1000)
|
||||||
|
}, 1)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getPreSelectedPage() {
|
||||||
|
return 'welcome'
|
||||||
|
}
|
||||||
|
|
||||||
|
renderSelectedNodeOnStart() {
|
||||||
|
const selectedNodeIndexOnStart = localStorage.getItem('mySelectedNode')
|
||||||
|
const catchSavedNodes = JSON.parse(localStorage.getItem('myQortalNodes'))
|
||||||
|
const selectedNodeOnStart = catchSavedNodes[selectedNodeIndexOnStart]
|
||||||
|
const selectedNameOnStart = `${selectedNodeOnStart.name}`
|
||||||
|
const selectedNodeUrlOnStart = `${selectedNodeOnStart.protocol + '://' + selectedNodeOnStart.domain + ':' + selectedNodeOnStart.port}`
|
||||||
|
|
||||||
|
let connectString = get('settings.snack2')
|
||||||
|
|
||||||
|
return html`<h6>${connectString} : ${selectedNameOnStart} ${selectedNodeUrlOnStart}</h6>`
|
||||||
|
}
|
||||||
|
|
||||||
|
selectPage(newPage) {
|
||||||
|
this.selectedPage = newPage
|
||||||
|
}
|
||||||
|
|
||||||
|
stateChanged(state) {
|
||||||
|
if (this.loggedIn && !state.app.loggedIn) this.cleanup()
|
||||||
|
|
||||||
|
this.loggedIn = state.app.loggedIn
|
||||||
|
this.config = state.config
|
||||||
|
this.nodeConfig = state.app.nodeConfig
|
||||||
|
}
|
||||||
|
|
||||||
|
cleanup() {
|
||||||
|
this.selectedPage = 'welcome'
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('login-view', LoginView)
|
window.customElements.define('login-view', LoginView)
|
@ -1,76 +1,44 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {translate} from '../../../translate'
|
import { welcomePageStyles } from '../../styles/core-css'
|
||||||
|
|
||||||
import '@material/mwc-button'
|
import '@material/mwc-button'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { translate } from '../../../translate'
|
||||||
|
|
||||||
class WelcomePage extends LitElement {
|
class WelcomePage extends LitElement {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
nextHidden: { type: Boolean, notify: true },
|
hideNav: { type: Boolean, notify: true },
|
||||||
nextEnabled: { type: Boolean, notify: true },
|
theme: { type: String, reflect: true }
|
||||||
nextText: { type: String, notify: true },
|
}
|
||||||
backHidden: { type: Boolean, notify: true },
|
}
|
||||||
backDisabled: { type: Boolean, notify: true },
|
|
||||||
backText: { type: String, notify: true },
|
|
||||||
hideNav: { type: Boolean, notify: true },
|
|
||||||
welcomeMessage: { type: String },
|
|
||||||
theme: { type: String, reflect: true }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return css`
|
return [welcomePageStyles]
|
||||||
* {
|
}
|
||||||
--mdc-theme-primary: var(--login-button);
|
|
||||||
--mdc-theme-secondary: var(--mdc-theme-primary);
|
|
||||||
--mdc-button-outline-color: var(--general-color-blue);
|
|
||||||
}
|
|
||||||
|
|
||||||
.button-outline {
|
constructor() {
|
||||||
margin: 6px;
|
super()
|
||||||
width: 90%;
|
this.hideNav = true
|
||||||
max-width:90vw;
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
border-top: 0;
|
}
|
||||||
border-bottom: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.welcome-page {
|
render() {
|
||||||
padding: 12px 0;
|
return html`
|
||||||
overflow: hidden;
|
<div class="welcome-page">
|
||||||
}
|
<mwc-button class="button-outline" @click=${() => this.navigate('login')} outlined>${translate("login.login")}</mwc-button>
|
||||||
`
|
<mwc-button class="button-outline" @click=${() => this.navigate('create-account')} outlined>${translate("login.createaccount")}</mwc-button>
|
||||||
}
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
navigate(page) {
|
||||||
super()
|
this.dispatchEvent(new CustomEvent('navigate', {
|
||||||
this.hideNav = true
|
detail: { page },
|
||||||
this.nextText = ''
|
bubbles: true,
|
||||||
this.welcomeMessage = 'Welcome to Qortal'
|
composed: true
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated() {}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return html`
|
|
||||||
<div class="welcome-page">
|
|
||||||
<mwc-button class="button-outline" @click=${() => this.navigate('login')} outlined>${translate("login.login")}</mwc-button>
|
|
||||||
<mwc-button class="button-outline" @click=${() => this.navigate('create-account')} outlined>${translate("login.createaccount")}</mwc-button>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
back() {}
|
|
||||||
|
|
||||||
next() {}
|
|
||||||
|
|
||||||
navigate(page) {
|
|
||||||
this.dispatchEvent(new CustomEvent('navigate', {
|
|
||||||
detail: { page },
|
|
||||||
bubbles: true,
|
|
||||||
composed: true
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('welcome-page', WelcomePage)
|
window.customElements.define('welcome-page', WelcomePage)
|
@ -1,72 +1,61 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers'
|
import { connect } from 'pwa-helpers'
|
||||||
import {store} from '../../store.js'
|
import { store } from '../../store.js'
|
||||||
import {doLogout} from '../../redux/app/app-actions.js'
|
import { doLogout } from '../../redux/app/app-actions.js'
|
||||||
import {translate} from '../../../translate'
|
import { logoutViewStyles } from '../../styles/core-css'
|
||||||
|
|
||||||
import '@polymer/paper-dialog/paper-dialog.js'
|
|
||||||
import '@material/mwc-button'
|
import '@material/mwc-button'
|
||||||
|
import '@polymer/paper-dialog/paper-dialog.js'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { translate } from '../../../translate'
|
||||||
|
|
||||||
class LogoutView extends connect(store)(LitElement) {
|
class LogoutView extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
theme: { type: String, reflect: true }
|
theme: { type: String, reflect: true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return css`
|
return [logoutViewStyles]
|
||||||
* {
|
}
|
||||||
--mdc-theme-primary: rgb(3, 169, 244);
|
|
||||||
--mdc-theme-secondary: var(--mdc-theme-primary);
|
|
||||||
--mdc-theme-surface: var(--white);
|
|
||||||
--mdc-dialog-content-ink-color: var(--black);
|
|
||||||
}
|
|
||||||
|
|
||||||
.decline {
|
constructor() {
|
||||||
--mdc-theme-primary: var(--mdc-theme-error)
|
super()
|
||||||
}
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
|
}
|
||||||
|
|
||||||
.buttons {
|
render() {
|
||||||
text-align:right;
|
return html`
|
||||||
}
|
<paper-dialog style="background: var(--white);" id="userLogoutDialog" modal>
|
||||||
`
|
<div style="text-align: center;">
|
||||||
}
|
<h2 style="color: var(--black);">Qortal UI</h2>
|
||||||
|
<hr>
|
||||||
|
</div>
|
||||||
|
<div style="text-align: center;">
|
||||||
|
<h2 style="color: var(--black);">${translate("logout.confirmlogout")}</h2>
|
||||||
|
</div>
|
||||||
|
<div class="buttons">
|
||||||
|
<mwc-button class='decline' @click=${() => this.decline()} 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>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
openLogout() {
|
||||||
super()
|
this.shadowRoot.getElementById('userLogoutDialog').open()
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
}
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
async confirm(e) {
|
||||||
return html`
|
store.dispatch(doLogout())
|
||||||
<paper-dialog style="background: var(--white);" id="userLogoutDialog" modal>
|
e.stopPropagation()
|
||||||
<div style="text-align: center;">
|
}
|
||||||
<h2 style="color: var(--black);">Qortal UI</h2>
|
|
||||||
<hr>
|
|
||||||
</div>
|
|
||||||
<div style="text-align: center;">
|
|
||||||
<h2 style="color: var(--black);">${translate("logout.confirmlogout")}</h2>
|
|
||||||
</div>
|
|
||||||
<div class="buttons">
|
|
||||||
<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>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
openLogout() {
|
decline() {
|
||||||
this.shadowRoot.getElementById('userLogoutDialog').open()
|
this.shadowRoot.getElementById('userLogoutDialog').close()
|
||||||
}
|
this.requestUpdate()
|
||||||
|
}
|
||||||
async confirm(e) {
|
|
||||||
store.dispatch(doLogout())
|
|
||||||
}
|
|
||||||
|
|
||||||
decline(e) {
|
|
||||||
this.shadowRoot.getElementById('userLogoutDialog').close()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('logout-view', LogoutView)
|
window.customElements.define('logout-view', LogoutView)
|
@ -1,77 +1,66 @@
|
|||||||
import {html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {installRouter} from 'pwa-helpers/router.js'
|
import { connect } from 'pwa-helpers'
|
||||||
import {connect} from 'pwa-helpers'
|
import { store } from '../store'
|
||||||
import {store} from '../store.js'
|
import { installRouter } from 'pwa-helpers/router'
|
||||||
import {doNavigate} from '../redux/app/app-actions.js'
|
import { doNavigate } from '../redux/app/app-actions'
|
||||||
|
import { loadPlugins } from '../plugins/load-plugins'
|
||||||
import isElectron from 'is-electron'
|
import isElectron from 'is-electron'
|
||||||
import '../plugins/streams.js'
|
import './login-view/login-view'
|
||||||
|
import './app-view'
|
||||||
import {loadPlugins} from '../plugins/load-plugins.js'
|
import '../plugins/streams'
|
||||||
|
import '../styles/app-styles'
|
||||||
import '../styles/app-styles.js'
|
|
||||||
import './login-view/login-view.js'
|
|
||||||
import './app-view.js'
|
|
||||||
|
|
||||||
installRouter((location) => store.dispatch(doNavigate(location)))
|
installRouter((location) => store.dispatch(doNavigate(location)))
|
||||||
|
|
||||||
class MainApp extends connect(store)(LitElement) {
|
class MainApp extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
name: { type: String },
|
name: { type: String },
|
||||||
loggedIn: { type: Boolean }
|
loggedIn: { type: Boolean }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
render() {
|
||||||
return []
|
return html`${this.renderViews(this.loggedIn)}`
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
connectedCallback() {
|
||||||
return html`${this.renderViews(this.loggedIn)}`
|
super.connectedCallback()
|
||||||
}
|
this.initial = 0
|
||||||
|
|
||||||
/**
|
if (!isElectron()) {
|
||||||
* Dynamic renderViews method to introduce conditional rendering of views based on user's logged in state.
|
} else {
|
||||||
* @param {Boolean} isLoggedIn
|
window.addEventListener('contextmenu', (event) => {
|
||||||
*/
|
event.preventDefault()
|
||||||
|
window.electronAPI.showMyMenu()
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
renderViews(isLoggedIn) {
|
/**
|
||||||
if (isLoggedIn) {
|
* Dynamic renderViews method to introduce conditional rendering of views based on user's logged in state.
|
||||||
return html`
|
* @param {Boolean} isLoggedIn
|
||||||
<app-view></app-view>
|
*/
|
||||||
`
|
renderViews(isLoggedIn) {
|
||||||
} else {
|
if (isLoggedIn) {
|
||||||
return html`
|
return html`<app-view></app-view>`
|
||||||
<login-view></login-view>
|
} else {
|
||||||
`
|
return html`<login-view></login-view>`
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
stateChanged(state) {
|
_loadPlugins() {
|
||||||
this.loggedIn = state.app.loggedIn
|
loadPlugins()
|
||||||
if (this.loggedIn === true && this.initial === 0) {
|
}
|
||||||
this.initial = this.initial + 1
|
|
||||||
this._loadPlugins()
|
|
||||||
}
|
|
||||||
document.title = state.config.coin.name
|
|
||||||
}
|
|
||||||
|
|
||||||
_loadPlugins() {
|
stateChanged(state) {
|
||||||
loadPlugins()
|
this.loggedIn = state.app.loggedIn
|
||||||
}
|
if (this.loggedIn === true && this.initial === 0) {
|
||||||
|
this.initial = this.initial + 1
|
||||||
connectedCallback() {
|
this._loadPlugins()
|
||||||
super.connectedCallback()
|
}
|
||||||
this.initial = 0
|
document.title = state.config.coin.name
|
||||||
|
}
|
||||||
if (!isElectron()) {
|
|
||||||
} else {
|
|
||||||
window.addEventListener('contextmenu', (event) => {
|
|
||||||
event.preventDefault()
|
|
||||||
window.electronAPI.showMyMenu()
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('main-app', MainApp)
|
window.customElements.define('main-app', MainApp)
|
@ -1,140 +1,114 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {registerTranslateConfig, translate, use} from '../../translate'
|
import { newSelectorStyles } from '../styles/core-css'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { registerTranslateConfig, translate, use } from '../../translate'
|
||||||
|
|
||||||
registerTranslateConfig({
|
registerTranslateConfig({
|
||||||
loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
|
loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
|
||||||
})
|
})
|
||||||
|
|
||||||
const checkLanguage = localStorage.getItem('qortalLanguage')
|
const checkLanguage = localStorage.getItem('qortalLanguage')
|
||||||
|
|
||||||
if (checkLanguage === null || checkLanguage.length === 0) {
|
if (checkLanguage === null || checkLanguage.length === 0) {
|
||||||
localStorage.setItem('qortalLanguage', 'us')
|
localStorage.setItem('qortalLanguage', 'us')
|
||||||
use('us')
|
use('us')
|
||||||
} else {
|
} else {
|
||||||
use(checkLanguage)
|
use(checkLanguage)
|
||||||
}
|
}
|
||||||
|
|
||||||
class NewSelector extends LitElement {
|
class NewSelector extends LitElement {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
theme: { type: String, reflect: true }
|
theme: { type: String, reflect: true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return [
|
return [newSelectorStyles]
|
||||||
css`
|
}
|
||||||
select {
|
|
||||||
width: auto;
|
|
||||||
height: auto;
|
|
||||||
position: absolute;
|
|
||||||
top: 50px;
|
|
||||||
padding: 5px 5px 5px 5px;
|
|
||||||
font-size: 16px;
|
|
||||||
border: 1px solid var(--black);
|
|
||||||
border-radius: 3px;
|
|
||||||
color: var(--black);
|
|
||||||
background: var(--white);
|
|
||||||
overflow: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
*:focus {
|
constructor() {
|
||||||
outline: none;
|
super()
|
||||||
}
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
|
}
|
||||||
|
|
||||||
select option {
|
render() {
|
||||||
color: var(--black);
|
return html`
|
||||||
background: var(--white);
|
<div style="display: inline;">
|
||||||
line-height: 34px;
|
<span>
|
||||||
}
|
<img src="/img/${translate("selectmenu.languageflag")}-flag-round-icon-32.png" style="width: 24px; height: 24px; padding-top: 4px;" @click=${() => this.toggleMenu()}>
|
||||||
|
</span>
|
||||||
|
<select id="languageNew" style="display: none;" size="20" tabindex="0" @change="${this.changeLanguage}">
|
||||||
|
<option value="us">US - ${translate("selectmenu.english")}</option>
|
||||||
|
<option value="de">DE - ${translate("selectmenu.german")}</option>
|
||||||
|
<option value="es">ES - ${translate("selectmenu.spanish")}</option>
|
||||||
|
<option value="et">ET - ${translate("selectmenu.estonian")}</option>
|
||||||
|
<option value="fi">FI - ${translate("selectmenu.finnish")}</option>
|
||||||
|
<option value="fr">FR - ${translate("selectmenu.french")}</option>
|
||||||
|
<option value="hr">HR - ${translate("selectmenu.croatian")}</option>
|
||||||
|
<option value="hu">HU - ${translate("selectmenu.hungarian")}</option>
|
||||||
|
<option value="hindi">IN - ${translate("selectmenu.hindi")}</option>
|
||||||
|
<option value="it">IT - ${translate("selectmenu.italian")}</option>
|
||||||
|
<option value="jp">JP - ${translate("selectmenu.japanese")}</option>
|
||||||
|
<option value="ko">KO - ${translate("selectmenu.korean")}</option>
|
||||||
|
<option value="nl">NL - ${translate("selectmenu.dutch")}</option>
|
||||||
|
<option value="no">NO - ${translate("selectmenu.norwegian")}</option>
|
||||||
|
<option value="pl">PL - ${translate("selectmenu.polish")}</option>
|
||||||
|
<option value="pt">PT - ${translate("selectmenu.portuguese")}</option>
|
||||||
|
<option value="rs">RS - ${translate("selectmenu.serbian")}</option>
|
||||||
|
<option value="ro">RO - ${translate("selectmenu.romanian")}</option>
|
||||||
|
<option value="ru">RU - ${translate("selectmenu.russian")}</option>
|
||||||
|
<option value="zht">ZHT - ${translate("selectmenu.chinese2")}</option>
|
||||||
|
<option value="zhc">ZHC - ${translate("selectmenu.chinese1")}</option>
|
||||||
|
</select>
|
||||||
|
</div>
|
||||||
|
|
||||||
select option:hover {
|
`
|
||||||
color: var(--white);
|
}
|
||||||
background: var(--black);
|
|
||||||
line-height: 34px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
firstUpdated() {
|
||||||
super()
|
const myElement = this.shadowRoot.getElementById('languageNew')
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
myElement.addEventListener('change', () => {
|
||||||
return html`
|
this.selectElement()
|
||||||
<div style="display: inline;">
|
})
|
||||||
<span>
|
|
||||||
<img src="/img/${translate("selectmenu.languageflag")}-flag-round-icon-32.png" style="width: 24px; height: 24px; padding-top: 4px;" @click=${() => this.toggleMenu()}>
|
|
||||||
</span>
|
|
||||||
<select id="languageNew" style="display: none;" size="20" tabindex="0" @change="${this.changeLanguage}">
|
|
||||||
<option value="us">US - ${translate("selectmenu.english")}</option>
|
|
||||||
<option value="de">DE - ${translate("selectmenu.german")}</option>
|
|
||||||
<option value="es">ES - ${translate("selectmenu.spanish")}</option>
|
|
||||||
<option value="et">ET - ${translate("selectmenu.estonian")}</option>
|
|
||||||
<option value="fi">FI - ${translate("selectmenu.finnish")}</option>
|
|
||||||
<option value="fr">FR - ${translate("selectmenu.french")}</option>
|
|
||||||
<option value="hr">HR - ${translate("selectmenu.croatian")}</option>
|
|
||||||
<option value="hu">HU - ${translate("selectmenu.hungarian")}</option>
|
|
||||||
<option value="hindi">IN - ${translate("selectmenu.hindi")}</option>
|
|
||||||
<option value="it">IT - ${translate("selectmenu.italian")}</option>
|
|
||||||
<option value="jp">JP - ${translate("selectmenu.japanese")}</option>
|
|
||||||
<option value="ko">KO - ${translate("selectmenu.korean")}</option>
|
|
||||||
<option value="nl">NL - ${translate("selectmenu.dutch")}</option>
|
|
||||||
<option value="no">NO - ${translate("selectmenu.norwegian")}</option>
|
|
||||||
<option value="pl">PL - ${translate("selectmenu.polish")}</option>
|
|
||||||
<option value="pt">PT - ${translate("selectmenu.portuguese")}</option>
|
|
||||||
<option value="rs">RS - ${translate("selectmenu.serbian")}</option>
|
|
||||||
<option value="ro">RO - ${translate("selectmenu.romanian")}</option>
|
|
||||||
<option value="ru">RU - ${translate("selectmenu.russian")}</option>
|
|
||||||
<option value="zht">ZHT - ${translate("selectmenu.chinese2")}</option>
|
|
||||||
<option value="zhc">ZHC - ${translate("selectmenu.chinese1")}</option>
|
|
||||||
</select>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
`
|
myElement.addEventListener('click', () => {
|
||||||
}
|
const element1 = localStorage.getItem('qortalLanguage')
|
||||||
|
const element2 = this.shadowRoot.getElementById('languageNew').value
|
||||||
|
|
||||||
firstUpdated() {
|
if (element1 === element2) {
|
||||||
const myElement = this.shadowRoot.getElementById('languageNew')
|
myElement.style.display = 'none'
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
myElement.addEventListener("change", () => {
|
this.selectElement()
|
||||||
this.selectElement()
|
}
|
||||||
})
|
|
||||||
|
|
||||||
myElement.addEventListener("click", () => {
|
selectElement() {
|
||||||
const element1 = localStorage.getItem('qortalLanguage')
|
const selectedLanguage = localStorage.getItem('qortalLanguage')
|
||||||
const element2 = this.shadowRoot.getElementById('languageNew').value
|
|
||||||
if (element1 === element2) {
|
|
||||||
myElement.style.display = "none"
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
this.selectElement()
|
let element = this.shadowRoot.getElementById('languageNew')
|
||||||
}
|
|
||||||
|
|
||||||
selectElement() {
|
element.value = selectedLanguage
|
||||||
const selectedLanguage = localStorage.getItem('qortalLanguage')
|
element.style.display = 'none'
|
||||||
let element = this.shadowRoot.getElementById('languageNew')
|
}
|
||||||
element.value = selectedLanguage
|
|
||||||
element.style.display = "none"
|
|
||||||
}
|
|
||||||
|
|
||||||
changeLanguage(event) {
|
changeLanguage(event) {
|
||||||
use(event.target.value)
|
use(event.target.value)
|
||||||
localStorage.setItem('qortalLanguage', event.target.value)
|
localStorage.setItem('qortalLanguage', event.target.value)
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleMenu() {
|
toggleMenu() {
|
||||||
let mySwitchDisplay = this.shadowRoot.getElementById('languageNew')
|
let mySwitchDisplay = this.shadowRoot.getElementById('languageNew')
|
||||||
if(mySwitchDisplay.style.display == "none") {
|
|
||||||
mySwitchDisplay.style.display = "block"
|
if (mySwitchDisplay.style.display == 'none') {
|
||||||
} else {
|
mySwitchDisplay.style.display = 'block'
|
||||||
mySwitchDisplay.style.display = "none"
|
} else {
|
||||||
}
|
mySwitchDisplay.style.display = 'none'
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('new-selector', NewSelector)
|
window.customElements.define('new-selector', NewSelector)
|
@ -1,163 +1,71 @@
|
|||||||
import {css, html, LitElement} from 'lit';
|
import { html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers';
|
import { repeat } from 'lit/directives/repeat.js'
|
||||||
|
import { connect } from 'pwa-helpers'
|
||||||
import '@vaadin/item';
|
import { store } from '../../store'
|
||||||
import '@vaadin/list-box';
|
import { setNewNotification } from '../../redux/app/app-actions'
|
||||||
import '@polymer/paper-icon-button/paper-icon-button.js';
|
import { notificationBellGeneralStyles, notificationItemTxStyles } from '../../styles/core-css'
|
||||||
import '@polymer/iron-icons/iron-icons.js';
|
import './popover.js'
|
||||||
import {store} from '../../store.js';
|
import '../../../../plugins/plugins/core/components/TimeAgo'
|
||||||
import {setNewNotification} from '../../redux/app/app-actions.js';
|
import '@material/mwc-icon'
|
||||||
import '@material/mwc-icon';
|
import '@polymer/paper-icon-button/paper-icon-button.js'
|
||||||
import {get, translate} from '../../../translate'
|
import '@polymer/iron-icons/iron-icons.js'
|
||||||
import {repeat} from 'lit/directives/repeat.js';
|
import '@vaadin/item'
|
||||||
import '../../../../plugins/plugins/core/components/TimeAgo.js';
|
import '@vaadin/list-box'
|
||||||
import './popover.js';
|
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { get, translate } from '../../../translate'
|
||||||
|
|
||||||
class NotificationBellGeneral extends connect(store)(LitElement) {
|
class NotificationBellGeneral extends connect(store)(LitElement) {
|
||||||
static properties = {
|
static get properties() {
|
||||||
notifications: { type: Array },
|
return {
|
||||||
showNotifications: { type: Boolean },
|
notifications: { type: Array },
|
||||||
notificationCount: { type: Boolean },
|
showNotifications: { type: Boolean },
|
||||||
theme: { type: String, reflect: true },
|
notificationCount: { type: Boolean },
|
||||||
currentNotification: { type: Object },
|
currentNotification: { type: Object },
|
||||||
};
|
theme: { type: String, reflect: true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return [notificationBellGeneralStyles]
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super()
|
||||||
this.notifications = [];
|
this.notifications = []
|
||||||
this.showNotifications = false;
|
this.showNotifications = false
|
||||||
this.notificationCount = false;
|
this.notificationCount = false
|
||||||
this.initialFetch = false;
|
this.initialFetch = false
|
||||||
this.theme = localStorage.getItem('qortalTheme')
|
this.currentNotification = null
|
||||||
? localStorage.getItem('qortalTheme')
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
: 'light';
|
|
||||||
this.currentNotification = null;
|
|
||||||
}
|
|
||||||
|
|
||||||
firstUpdated() {
|
|
||||||
try {
|
|
||||||
let value = JSON.parse(localStorage.getItem('isFirstTimeUser'));
|
|
||||||
if (!value && value !== false) {
|
|
||||||
value = true;
|
|
||||||
}
|
|
||||||
this.isFirstTimeUser = value;
|
|
||||||
} catch (error) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
async stateChanged(state) {
|
|
||||||
if (state.app.newNotification) {
|
|
||||||
const newNotification = state.app.newNotification;
|
|
||||||
this.notifications = [newNotification, ...this.notifications];
|
|
||||||
store.dispatch(setNewNotification(null));
|
|
||||||
if (this.isFirstTimeUser) {
|
|
||||||
const target = this.shadowRoot.getElementById(
|
|
||||||
'popover-notification'
|
|
||||||
);
|
|
||||||
const popover =
|
|
||||||
this.shadowRoot.querySelector('popover-component');
|
|
||||||
if (popover) {
|
|
||||||
popover.openPopover(target);
|
|
||||||
}
|
|
||||||
|
|
||||||
localStorage.setItem('isFirstTimeUser', JSON.stringify(false));
|
|
||||||
this.isFirstTimeUser = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
handleBlur() {
|
|
||||||
setTimeout(() => {
|
|
||||||
if (!this.shadowRoot.contains(document.activeElement)) {
|
|
||||||
this.showNotifications = false;
|
|
||||||
}
|
|
||||||
}, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
changeStatus(signature, statusTx) {
|
|
||||||
const copyNotifications = [...this.notifications];
|
|
||||||
const findNotification = this.notifications.findIndex(
|
|
||||||
(notification) => notification.reference.signature === signature
|
|
||||||
);
|
|
||||||
if (findNotification !== -1) {
|
|
||||||
copyNotifications[findNotification] = {
|
|
||||||
...copyNotifications[findNotification],
|
|
||||||
status: statusTx,
|
|
||||||
};
|
|
||||||
this.notifications = copyNotifications;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const hasOngoing = this.notifications.find(
|
const hasOngoing = this.notifications.find(
|
||||||
(notification) => notification.status !== 'confirmed'
|
(notification) => notification.status !== 'confirmed'
|
||||||
);
|
)
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<div class="layout">
|
<div class="layout">
|
||||||
<popover-component
|
<popover-component for="popover-notification" message=${get('notifications.explanation')}></popover-component>
|
||||||
for="popover-notification"
|
<div id="popover-notification" @click=${() => this._toggleNotifications()}>
|
||||||
message=${get('notifications.explanation')}
|
${hasOngoing ? html`
|
||||||
></popover-component>
|
<mwc-icon id="notification-general-icon" style="color: green;cursor:pointer;user-select:none">notifications</mwc-icon>
|
||||||
<div
|
<vaadin-tooltip for="notification-general-icon" position="bottom" hover-delay=${400} hide-delay=${1} text=${get('notifications.notify4')}></vaadin-tooltip>
|
||||||
id="popover-notification"
|
` : html`
|
||||||
@click=${() => this._toggleNotifications()}
|
<mwc-icon id="notification-general-icon" style="color: var(--black); cursor:pointer;user-select:none">notifications</mwc-icon>
|
||||||
>
|
<vaadin-tooltip for="notification-general-icon" position="bottom" hover-delay=${400} hide-delay=${1}text=${get('notifications.notify4')}></vaadin-tooltip>
|
||||||
${hasOngoing
|
`}
|
||||||
? html`
|
|
||||||
<mwc-icon id="notification-general-icon" style="color: green;cursor:pointer;user-select:none"
|
|
||||||
>notifications</mwc-icon
|
|
||||||
>
|
|
||||||
<vaadin-tooltip
|
|
||||||
for="notification-general-icon"
|
|
||||||
position="bottom"
|
|
||||||
hover-delay=${400}
|
|
||||||
hide-delay=${1}
|
|
||||||
text=${get('notifications.notify4')}>
|
|
||||||
</vaadin-tooltip>
|
|
||||||
`
|
|
||||||
: html`
|
|
||||||
<mwc-icon
|
|
||||||
id="notification-general-icon"
|
|
||||||
style="color: var(--black); cursor:pointer;user-select:none"
|
|
||||||
>notifications</mwc-icon
|
|
||||||
>
|
|
||||||
<vaadin-tooltip
|
|
||||||
for="notification-general-icon"
|
|
||||||
position="bottom"
|
|
||||||
hover-delay=${400}
|
|
||||||
hide-delay=${1}
|
|
||||||
text=${get('notifications.notify4')}>
|
|
||||||
</vaadin-tooltip>
|
|
||||||
`}
|
|
||||||
</div>
|
</div>
|
||||||
${hasOngoing
|
${hasOngoing ? html`
|
||||||
? html`
|
<span class="count" style="cursor:pointer" @click=${() => this._toggleNotifications()}>
|
||||||
<span
|
<mwc-icon style="color: var(--black);font-size:18px">pending</mwc-icon>
|
||||||
class="count"
|
</span>
|
||||||
style="cursor:pointer"
|
` : ''}
|
||||||
@click=${() => this._toggleNotifications()}
|
<div id="notification-panel" class="popover-panel" style="visibility:${this.showNotifications ? 'visibile' : 'hidden'}" tabindex="0" @blur=${this.handleBlur}>
|
||||||
>
|
|
||||||
<mwc-icon
|
|
||||||
style="color: var(--black);font-size:18px"
|
|
||||||
>pending</mwc-icon
|
|
||||||
>
|
|
||||||
</span>
|
|
||||||
`
|
|
||||||
: ''}
|
|
||||||
|
|
||||||
<div
|
|
||||||
id="notification-panel"
|
|
||||||
class="popover-panel"
|
|
||||||
style="visibility:${this.showNotifications
|
|
||||||
? 'visibile'
|
|
||||||
: 'hidden'}"
|
|
||||||
tabindex="0"
|
|
||||||
@blur=${this.handleBlur}
|
|
||||||
>
|
|
||||||
<div class="notifications-list">
|
<div class="notifications-list">
|
||||||
${this.notifications.length === 0 ? html`
|
${this.notifications.length === 0 ? html`
|
||||||
<p style="font-size: 16px; width: 100%; text-align:center;margin-top:20px;">${translate('notifications.notify3')}</p>
|
<p style="font-size: 16px; width: 100%; text-align:center;margin-top:20px;">${translate('notifications.notify3')}</p>
|
||||||
` : ''}
|
` : ''}
|
||||||
${repeat(
|
${repeat(
|
||||||
this.notifications,
|
this.notifications,
|
||||||
@ -166,18 +74,82 @@ class NotificationBellGeneral extends connect(store)(LitElement) {
|
|||||||
<notification-item-tx
|
<notification-item-tx
|
||||||
.changeStatus=${(val1, val2) =>
|
.changeStatus=${(val1, val2) =>
|
||||||
this.changeStatus(val1, val2)}
|
this.changeStatus(val1, val2)}
|
||||||
status=${notification.status}
|
status=${notification.status}
|
||||||
timestamp=${notification.timestamp}
|
timestamp=${notification.timestamp}
|
||||||
type=${notification.type}
|
type=${notification.type}
|
||||||
signature=${notification.reference
|
signature=${notification.reference
|
||||||
.signature}
|
.signature
|
||||||
|
}
|
||||||
></notification-item-tx>
|
></notification-item-tx>
|
||||||
`
|
`
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated() {
|
||||||
|
try {
|
||||||
|
let value = JSON.parse(localStorage.getItem('isFirstTimeUser'))
|
||||||
|
|
||||||
|
if (!value && value !== false) {
|
||||||
|
value = true
|
||||||
|
}
|
||||||
|
|
||||||
|
this.isFirstTimeUser = value
|
||||||
|
} catch (error) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
async stateChanged(state) {
|
||||||
|
if (state.app.newNotification) {
|
||||||
|
const newNotification = state.app.newNotification
|
||||||
|
|
||||||
|
this.notifications = [newNotification, ...this.notifications]
|
||||||
|
|
||||||
|
store.dispatch(setNewNotification(null))
|
||||||
|
|
||||||
|
if (this.isFirstTimeUser) {
|
||||||
|
const target = this.shadowRoot.getElementById(
|
||||||
|
'popover-notification'
|
||||||
|
)
|
||||||
|
|
||||||
|
const popover = this.shadowRoot.querySelector('popover-component')
|
||||||
|
|
||||||
|
if (popover) {
|
||||||
|
popover.openPopover(target)
|
||||||
|
}
|
||||||
|
|
||||||
|
localStorage.setItem('isFirstTimeUser', JSON.stringify(false))
|
||||||
|
|
||||||
|
this.isFirstTimeUser = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
handleBlur() {
|
||||||
|
setTimeout(() => {
|
||||||
|
if (!this.shadowRoot.contains(document.activeElement)) {
|
||||||
|
this.showNotifications = false
|
||||||
|
}
|
||||||
|
}, 0)
|
||||||
|
}
|
||||||
|
|
||||||
|
changeStatus(signature, statusTx) {
|
||||||
|
const copyNotifications = [...this.notifications]
|
||||||
|
|
||||||
|
const findNotification = this.notifications.findIndex(
|
||||||
|
(notification) => notification.reference.signature === signature
|
||||||
|
)
|
||||||
|
|
||||||
|
if (findNotification !== -1) {
|
||||||
|
copyNotifications[findNotification] = {
|
||||||
|
...copyNotifications[findNotification],
|
||||||
|
status: statusTx
|
||||||
|
}
|
||||||
|
|
||||||
|
this.notifications = copyNotifications
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_toggleNotifications() {
|
_toggleNotifications() {
|
||||||
@ -188,153 +160,34 @@ class NotificationBellGeneral extends connect(store)(LitElement) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = css`
|
|
||||||
.layout {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.count {
|
|
||||||
position: absolute;
|
|
||||||
top: -5px;
|
|
||||||
right: -5px;
|
|
||||||
font-size: 12px;
|
|
||||||
background-color: red;
|
|
||||||
color: white;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nocount {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover-panel {
|
|
||||||
position: absolute;
|
|
||||||
width: 200px;
|
|
||||||
padding: 10px;
|
|
||||||
background-color: var(--white);
|
|
||||||
border: 1px solid var(--black);
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
top: 40px;
|
|
||||||
max-height: 350px;
|
|
||||||
overflow: auto;
|
|
||||||
scrollbar-width: thin;
|
|
||||||
scrollbar-color: #6a6c75 #a1a1a1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover-panel::-webkit-scrollbar {
|
|
||||||
width: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover-panel::-webkit-scrollbar-track {
|
|
||||||
background: #a1a1a1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover-panel::-webkit-scrollbar-thumb {
|
|
||||||
background-color: #6a6c75;
|
|
||||||
border-radius: 6px;
|
|
||||||
border: 3px solid #a1a1a1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notifications-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notification-item {
|
|
||||||
padding: 5px;
|
|
||||||
border-bottom: 1px solid;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: 0.2s all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notification-item:hover {
|
|
||||||
background: var(--nav-color-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 14px;
|
|
||||||
color: var(--black);
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('notification-bell-general', NotificationBellGeneral);
|
window.customElements.define('notification-bell-general', NotificationBellGeneral)
|
||||||
|
|
||||||
class NotificationItemTx extends connect(store)(LitElement) {
|
class NotificationItemTx extends connect(store)(LitElement) {
|
||||||
static properties = {
|
static get properties() {
|
||||||
status: { type: String },
|
return {
|
||||||
type: { type: String },
|
status: { type: String },
|
||||||
timestamp: { type: Number },
|
type: { type: String },
|
||||||
signature: { type: String },
|
timestamp: { type: Number },
|
||||||
changeStatus: { attribute: false },
|
signature: { type: String },
|
||||||
};
|
changeStatus: { attribute: false }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return [notificationItemTxStyles]
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super()
|
||||||
this.nodeUrl = this.getNodeUrl();
|
this.nodeUrl = this.getNodeUrl()
|
||||||
this.myNode = this.getMyNode();
|
this.myNode = this.getMyNode()
|
||||||
}
|
|
||||||
|
|
||||||
getNodeUrl() {
|
|
||||||
const myNode =
|
|
||||||
store.getState().app.nodeConfig.knownNodes[
|
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
]
|
|
||||||
|
|
||||||
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
|
||||||
}
|
|
||||||
getMyNode() {
|
|
||||||
return store.getState().app.nodeConfig.knownNodes[
|
|
||||||
window.parent.reduxStore.getState().app.nodeConfig.node
|
|
||||||
]
|
|
||||||
}
|
|
||||||
|
|
||||||
async getStatus() {
|
|
||||||
let interval = null;
|
|
||||||
let stop = false;
|
|
||||||
const getAnswer = async () => {
|
|
||||||
const getTx = async (minterAddr) => {
|
|
||||||
const url = `${this.nodeUrl}/transactions/signature/${this.signature}`
|
|
||||||
const res = await fetch(url)
|
|
||||||
return await res.json()
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!stop) {
|
|
||||||
stop = true;
|
|
||||||
try {
|
|
||||||
const txTransaction = await getTx();
|
|
||||||
if (!txTransaction.error && txTransaction.signature && txTransaction.blockHeight) {
|
|
||||||
clearInterval(interval);
|
|
||||||
this.changeStatus(this.signature, 'confirmed');
|
|
||||||
}
|
|
||||||
} catch (error) {}
|
|
||||||
stop = false;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
interval = setInterval(getAnswer, 20000);
|
|
||||||
}
|
|
||||||
|
|
||||||
firstUpdated() {
|
|
||||||
this.getStatus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div class="notification-item" @click=${() => {}}>
|
<div class="notification-item" @click=${() => { }}>
|
||||||
<div>
|
<div>
|
||||||
<p style="margin-bottom:10px; font-weight:bold">
|
<p style="margin-bottom:10px; font-weight:bold">
|
||||||
${translate('transpage.tchange1')}
|
${translate('transpage.tchange1')}
|
||||||
@ -345,187 +198,66 @@ class NotificationItemTx extends connect(store)(LitElement) {
|
|||||||
${translate('walletpage.wchange35')}: ${this.type}
|
${translate('walletpage.wchange35')}: ${this.type}
|
||||||
</p>
|
</p>
|
||||||
<p style="margin-bottom:5px">
|
<p style="margin-bottom:5px">
|
||||||
${translate('tubespage.schange28')}:
|
${translate('tubespage.schange28')}: ${this.status === 'confirming' ? translate('notifications.notify1') : translate('notifications.notify2')}
|
||||||
${this.status === 'confirming'
|
|
||||||
? translate('notifications.notify1')
|
|
||||||
: translate('notifications.notify2')}
|
|
||||||
</p>
|
</p>
|
||||||
${this.status !== 'confirmed'
|
${this.status !== 'confirmed' ? html`<div class="centered"><div class="loader">Loading...</div></div>` : ''}
|
||||||
? html`
|
<div style="display:flex;justify-content:space-between;align-items:center">
|
||||||
<div class="centered">
|
<message-time timestamp=${this.timestamp} style="color:red;font-size:12px"></message-time>
|
||||||
<div class="loader">Loading...</div>
|
${this.status === 'confirmed' ? html`<mwc-icon style="color: green;">done</mwc-icon>` : ''}
|
||||||
</div>
|
|
||||||
`
|
|
||||||
: ''}
|
|
||||||
<div
|
|
||||||
style="display:flex;justify-content:space-between;align-items:center"
|
|
||||||
>
|
|
||||||
<message-time
|
|
||||||
timestamp=${this.timestamp}
|
|
||||||
style="color:red;font-size:12px"
|
|
||||||
></message-time>
|
|
||||||
${this.status === 'confirmed'
|
|
||||||
? html`
|
|
||||||
<mwc-icon style="color: green;"
|
|
||||||
>done</mwc-icon
|
|
||||||
>
|
|
||||||
`
|
|
||||||
: ''}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
`;
|
`
|
||||||
|
}
|
||||||
|
|
||||||
|
firstUpdated() {
|
||||||
|
this.getStatus()
|
||||||
|
}
|
||||||
|
|
||||||
|
getNodeUrl() {
|
||||||
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
return myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
|
}
|
||||||
|
|
||||||
|
getMyNode() {
|
||||||
|
return store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
}
|
||||||
|
|
||||||
|
async getStatus() {
|
||||||
|
let interval = null
|
||||||
|
let stop = false
|
||||||
|
|
||||||
|
const getAnswer = async () => {
|
||||||
|
const getTx = async (minterAddr) => {
|
||||||
|
const url = `${this.nodeUrl}/transactions/signature/${this.signature}`
|
||||||
|
const res = await fetch(url)
|
||||||
|
|
||||||
|
return await res.json()
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!stop) {
|
||||||
|
stop = true
|
||||||
|
|
||||||
|
try {
|
||||||
|
const txTransaction = await getTx()
|
||||||
|
|
||||||
|
if (!txTransaction.error && txTransaction.signature && txTransaction.blockHeight) {
|
||||||
|
clearInterval(interval)
|
||||||
|
this.changeStatus(this.signature, 'confirmed')
|
||||||
|
}
|
||||||
|
} catch (error) { }
|
||||||
|
|
||||||
|
stop = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
interval = setInterval(getAnswer, 20000)
|
||||||
}
|
}
|
||||||
|
|
||||||
_toggleNotifications() {
|
_toggleNotifications() {
|
||||||
if (this.notifications.length === 0) return;
|
if (this.notifications.length === 0) return
|
||||||
this.showNotifications = !this.showNotifications;
|
this.showNotifications = !this.showNotifications
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = css`
|
|
||||||
.centered {
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.layout {
|
|
||||||
width: 100px;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.count {
|
|
||||||
position: absolute;
|
|
||||||
top: -5px;
|
|
||||||
right: -5px;
|
|
||||||
font-size: 12px;
|
|
||||||
background-color: red;
|
|
||||||
color: white;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nocount {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover-panel {
|
|
||||||
position: absolute;
|
|
||||||
width: 200px;
|
|
||||||
padding: 10px;
|
|
||||||
background-color: var(--white);
|
|
||||||
border: 1px solid var(--black);
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
top: 40px;
|
|
||||||
max-height: 350px;
|
|
||||||
overflow: auto;
|
|
||||||
scrollbar-width: thin;
|
|
||||||
scrollbar-color: #6a6c75 #a1a1a1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover-panel::-webkit-scrollbar {
|
|
||||||
width: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover-panel::-webkit-scrollbar-track {
|
|
||||||
background: #a1a1a1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover-panel::-webkit-scrollbar-thumb {
|
|
||||||
background-color: #6a6c75;
|
|
||||||
border-radius: 6px;
|
|
||||||
border: 3px solid #a1a1a1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notifications-list {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notification-item {
|
|
||||||
padding: 5px;
|
|
||||||
border-bottom: 1px solid;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
cursor: default;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notification-item:hover {
|
|
||||||
background: var(--nav-color-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 14px;
|
|
||||||
color: var(--black);
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.loader,
|
|
||||||
.loader:before,
|
|
||||||
.loader:after {
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 10px;
|
|
||||||
height: 10px;
|
|
||||||
-webkit-animation-fill-mode: both;
|
|
||||||
animation-fill-mode: both;
|
|
||||||
-webkit-animation: load7 1.8s infinite ease-in-out;
|
|
||||||
animation: load7 1.8s infinite ease-in-out;
|
|
||||||
}
|
|
||||||
.loader {
|
|
||||||
color: var(--black);
|
|
||||||
font-size: 5px;
|
|
||||||
margin-bottom: 20px;
|
|
||||||
position: relative;
|
|
||||||
text-indent: -9999em;
|
|
||||||
-webkit-transform: translateZ(0);
|
|
||||||
-ms-transform: translateZ(0);
|
|
||||||
transform: translateZ(0);
|
|
||||||
-webkit-animation-delay: -0.16s;
|
|
||||||
animation-delay: -0.16s;
|
|
||||||
}
|
|
||||||
.loader:before,
|
|
||||||
.loader:after {
|
|
||||||
content: '';
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
.loader:before {
|
|
||||||
left: -3.5em;
|
|
||||||
-webkit-animation-delay: -0.32s;
|
|
||||||
animation-delay: -0.32s;
|
|
||||||
}
|
|
||||||
.loader:after {
|
|
||||||
left: 3.5em;
|
|
||||||
}
|
|
||||||
@-webkit-keyframes load7 {
|
|
||||||
0%,
|
|
||||||
80%,
|
|
||||||
100% {
|
|
||||||
box-shadow: 0 2.5em 0 -1.3em;
|
|
||||||
}
|
|
||||||
40% {
|
|
||||||
box-shadow: 0 2.5em 0 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes load7 {
|
|
||||||
0%,
|
|
||||||
80%,
|
|
||||||
100% {
|
|
||||||
box-shadow: 0 2.5em 0 -1.3em;
|
|
||||||
}
|
|
||||||
40% {
|
|
||||||
box-shadow: 0 2.5em 0 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('notification-item-tx', NotificationItemTx);
|
window.customElements.define('notification-item-tx', NotificationItemTx)
|
@ -1,329 +1,262 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { css, html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers'
|
import { connect } from 'pwa-helpers'
|
||||||
|
import { store } from '../../store'
|
||||||
|
import { setNewTab } from '../../redux/app/app-actions'
|
||||||
|
import { routes } from '../../plugins/routes'
|
||||||
|
import { notificationBellStyles } from '../../styles/core-css'
|
||||||
|
import config from '../../notifications/config'
|
||||||
|
import '../../../../plugins/plugins/core/components/TimeAgo'
|
||||||
|
import '@material/mwc-icon'
|
||||||
|
import '@polymer/paper-icon-button/paper-icon-button'
|
||||||
|
import '@polymer/iron-icons/iron-icons.js'
|
||||||
import '@vaadin/item'
|
import '@vaadin/item'
|
||||||
import '@vaadin/list-box'
|
import '@vaadin/list-box'
|
||||||
import '@polymer/paper-icon-button/paper-icon-button.js'
|
|
||||||
import '@polymer/iron-icons/iron-icons.js'
|
|
||||||
import {store} from '../../store.js'
|
|
||||||
import {setNewTab} from '../../redux/app/app-actions.js'
|
|
||||||
import {routes} from '../../plugins/routes.js'
|
|
||||||
import '@material/mwc-icon';
|
|
||||||
|
|
||||||
import config from '../../notifications/config.js'
|
|
||||||
import '../../../../plugins/plugins/core/components/TimeAgo.js'
|
|
||||||
|
|
||||||
class NotificationBell extends connect(store)(LitElement) {
|
class NotificationBell extends connect(store)(LitElement) {
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
notifications: { type: Array },
|
||||||
|
showNotifications: { type: Boolean },
|
||||||
|
notificationCount: { type: Boolean },
|
||||||
|
theme: { type: String, reflect: true }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static properties = {
|
static get styles() {
|
||||||
notifications: { type: Array },
|
return [notificationBellStyles]
|
||||||
showNotifications: { type: Boolean },
|
}
|
||||||
notificationCount: { type: Boolean },
|
|
||||||
theme: { type: String, reflect: true },
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
this.notifications = []
|
this.notifications = []
|
||||||
this.showNotifications = false
|
this.showNotifications = false
|
||||||
this.notificationCount = false
|
this.notificationCount = false
|
||||||
this.initialFetch = false
|
this.initialFetch = false
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated() {
|
render() {
|
||||||
this.getNotifications();
|
return html`
|
||||||
document.addEventListener('click', (event) => {
|
<div class="layout">
|
||||||
const path = event.composedPath()
|
${this.notificationCount ? html`
|
||||||
if (!path.includes(this)) {
|
<mwc-icon @click=${() => this._toggleNotifications()} id="notification-mail-icon" style="color: green;cursor:pointer;user-select:none">
|
||||||
this.showNotifications = false
|
mail
|
||||||
}
|
</mwc-icon>
|
||||||
})
|
<vaadin-tooltip
|
||||||
}
|
for="notification-mail-icon"
|
||||||
|
position="bottom"
|
||||||
|
hover-delay=${400}
|
||||||
|
hide-delay=${1}
|
||||||
|
text="Q-Mail">
|
||||||
|
</vaadin-tooltip>
|
||||||
|
` : html`
|
||||||
|
<mwc-icon @click=${() => this._openTabQmail()} id="notification-mail-icon" style="color: var(--black); cursor:pointer;user-select:none">
|
||||||
|
mail
|
||||||
|
</mwc-icon>
|
||||||
|
<vaadin-tooltip
|
||||||
|
for="notification-mail-icon"
|
||||||
|
position="bottom"
|
||||||
|
hover-delay=${400}
|
||||||
|
hide-delay=${1}
|
||||||
|
text="Q-Mail">
|
||||||
|
</vaadin-tooltip>
|
||||||
|
`}
|
||||||
|
${this.notificationCount ? html`
|
||||||
|
<span class="count">${this.notifications.length}</span>
|
||||||
|
` : ''}
|
||||||
|
<div class="popover-panel" ?hidden=${!this.showNotifications}>
|
||||||
|
<div class="notifications-list">
|
||||||
|
${this.notifications.map(notification => html`
|
||||||
|
<div
|
||||||
|
class="notification-item"
|
||||||
|
@click=${() => {
|
||||||
|
const query = `?service=APP&name=Q-Mail`
|
||||||
|
store.dispatch(setNewTab({
|
||||||
|
url: `qdn/browser/index.html${query}`,
|
||||||
|
id: 'q-mail-notification',
|
||||||
|
myPlugObj: {
|
||||||
|
"url": "myapp",
|
||||||
|
"domain": "core",
|
||||||
|
"page": `qdn/browser/index.html${query}`,
|
||||||
|
"title": "Q-Mail",
|
||||||
|
"icon": "vaadin:mailbox",
|
||||||
|
"mwcicon": "mail_outline",
|
||||||
|
"menus": [],
|
||||||
|
"parent": false
|
||||||
|
}
|
||||||
|
}))
|
||||||
|
this.showNotifications = false
|
||||||
|
this.notifications = []
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<p>Q-Mail</p>
|
||||||
|
<message-time timestamp=${notification.created} style="color:red;font-size:12px"></message-time>
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
<p>${notification.name}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
getApiKey() {
|
firstUpdated() {
|
||||||
const apiNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
|
this.getNotifications()
|
||||||
|
|
||||||
|
document.addEventListener('click', (event) => {
|
||||||
|
const path = event.composedPath()
|
||||||
|
if (!path.includes(this)) {
|
||||||
|
this.showNotifications = false
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
getApiKey() {
|
||||||
|
const apiNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
return apiNode.apiKey
|
return apiNode.apiKey
|
||||||
}
|
}
|
||||||
|
|
||||||
async getNotifications() {
|
async getNotifications() {
|
||||||
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
|
|
||||||
let interval = null
|
let interval = null
|
||||||
let stop = false
|
let stop = false
|
||||||
|
|
||||||
const getNewMail = async () => {
|
const getNewMail = async () => {
|
||||||
|
const getMail = async (recipientName, recipientAddress) => {
|
||||||
|
const query = `qortal_qmail_${recipientName.slice(
|
||||||
|
0,
|
||||||
|
20
|
||||||
|
)}_${recipientAddress.slice(-6)}_mail_`
|
||||||
|
|
||||||
const getMail = async (recipientName, recipientAddress) => {
|
const url = `${nodeUrl}/arbitrary/resources/search?service=MAIL_PRIVATE&query=${query}&limit=10&includemetadata=false&offset=0&reverse=true&excludeblocked=true`
|
||||||
const query = `qortal_qmail_${recipientName.slice(
|
|
||||||
0,
|
const response = await fetch(url, {
|
||||||
20
|
method: 'GET',
|
||||||
)}_${recipientAddress.slice(-6)}_mail_`
|
headers: {
|
||||||
const url = `${nodeUrl}/arbitrary/resources/search?service=MAIL_PRIVATE&query=${query}&limit=10&includemetadata=false&offset=0&reverse=true&excludeblocked=true`
|
'Content-Type': 'application/json'
|
||||||
const response = await fetch(url, {
|
}
|
||||||
method: 'GET',
|
})
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json'
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return await response.json()
|
return await response.json()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!stop && !this.showNotifications) {
|
if (!stop && !this.showNotifications) {
|
||||||
stop = true
|
stop = true
|
||||||
try {
|
|
||||||
const address = window.parent.reduxStore.getState().app?.selectedAddress?.address;
|
|
||||||
const name = window.parent.reduxStore.getState().app?.accountInfo?.names[0]?.name
|
|
||||||
|
|
||||||
if (!name || !address) return
|
try {
|
||||||
const mailArray = await getMail(name, address)
|
const address = window.parent.reduxStore.getState().app?.selectedAddress?.address;
|
||||||
let notificationsToShow = []
|
const name = window.parent.reduxStore.getState().app?.accountInfo?.names[0]?.name
|
||||||
if (mailArray.length > 0) {
|
|
||||||
const lastVisited = localStorage.getItem("Q-Mail-last-visited")
|
|
||||||
|
|
||||||
if (lastVisited) {
|
if (!name || !address) return
|
||||||
mailArray.forEach((mail) => {
|
|
||||||
if (mail.created > lastVisited) notificationsToShow.push(mail)
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
notificationsToShow = mailArray
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
const mailArray = await getMail(name, address)
|
||||||
if (!this.initialFetch && notificationsToShow.length > 0) {
|
|
||||||
const mail = notificationsToShow[0]
|
|
||||||
const urlPic = `${nodeUrl}/arbitrary/THUMBNAIL/${mail.name}/qortal_avatar?async=true&apiKey=${this.getApiKey()}`
|
|
||||||
await routes.showNotification({
|
|
||||||
data: {
|
|
||||||
title: "New Q-Mail",
|
|
||||||
type: "qapp",
|
|
||||||
sound: config.messageAlert,
|
|
||||||
url: "",
|
|
||||||
options: {
|
|
||||||
body: `You have an unread mail from ${mail.name}`,
|
|
||||||
icon: urlPic,
|
|
||||||
badge: urlPic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else if (notificationsToShow.length > 0) {
|
|
||||||
if (notificationsToShow[0].created > (this.notifications[0]?.created || 0)) {
|
|
||||||
const mail = notificationsToShow[0]
|
|
||||||
const urlPic = `${nodeUrl}/arbitrary/THUMBNAIL/${mail.name}/qortal_avatar?async=true&apiKey=${this.getApiKey()}`
|
|
||||||
await routes.showNotification({
|
|
||||||
data: {
|
|
||||||
title: "New Q-Mail",
|
|
||||||
type: "qapp",
|
|
||||||
sound: config.messageAlert,
|
|
||||||
url: "",
|
|
||||||
options: {
|
|
||||||
body: `You have an unread mail from ${mail.name}`,
|
|
||||||
icon: urlPic,
|
|
||||||
badge: urlPic
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
this.notifications = notificationsToShow
|
|
||||||
|
|
||||||
this.notificationCount = this.notifications.length !== 0;
|
let notificationsToShow = []
|
||||||
|
|
||||||
if (!this.initialFetch) this.initialFetch = true
|
if (mailArray.length > 0) {
|
||||||
} catch (error) {
|
const lastVisited = localStorage.getItem("Q-Mail-last-visited")
|
||||||
console.error(error)
|
|
||||||
}
|
|
||||||
stop = false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
|
|
||||||
setTimeout(() => {
|
if (lastVisited) {
|
||||||
getNewMail()
|
mailArray.forEach((mail) => {
|
||||||
}, 5000)
|
if (mail.created > lastVisited) notificationsToShow.push(mail)
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
notificationsToShow = mailArray
|
||||||
|
}
|
||||||
|
|
||||||
interval = setInterval(getNewMail, 60000)
|
}
|
||||||
} catch (error) {
|
|
||||||
console.error(error)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
if (!this.initialFetch && notificationsToShow.length > 0) {
|
||||||
return html`
|
const mail = notificationsToShow[0]
|
||||||
<div class="layout">
|
const urlPic = `${nodeUrl}/arbitrary/THUMBNAIL/${mail.name}/qortal_avatar?async=true}`
|
||||||
${this.notificationCount ? html`
|
|
||||||
<mwc-icon @click=${() => this._toggleNotifications()} id="notification-mail-icon" style="color: green;cursor:pointer;user-select:none"
|
|
||||||
>mail</mwc-icon
|
|
||||||
>
|
|
||||||
<vaadin-tooltip
|
|
||||||
for="notification-mail-icon"
|
|
||||||
position="bottom"
|
|
||||||
hover-delay=${400}
|
|
||||||
hide-delay=${1}
|
|
||||||
text="Q-Mail">
|
|
||||||
</vaadin-tooltip>
|
|
||||||
|
|
||||||
` : html`
|
await routes.showNotification({
|
||||||
<mwc-icon @click=${() => this._openTabQmail()} id="notification-mail-icon" style="color: var(--black); cursor:pointer;user-select:none"
|
data: {
|
||||||
>mail</mwc-icon
|
title: 'New Q-Mail',
|
||||||
>
|
type: 'qapp',
|
||||||
<vaadin-tooltip
|
sound: config.messageAlert,
|
||||||
for="notification-mail-icon"
|
url: '',
|
||||||
position="bottom"
|
options: {
|
||||||
hover-delay=${400}
|
body: `You have an unread mail from ${mail.name}`,
|
||||||
hide-delay=${1}
|
icon: urlPic,
|
||||||
text="Q-Mail">
|
badge: urlPic
|
||||||
</vaadin-tooltip>
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if (notificationsToShow.length > 0) {
|
||||||
|
if (notificationsToShow[0].created > (this.notifications[0]?.created || 0)) {
|
||||||
|
const mail = notificationsToShow[0]
|
||||||
|
const urlPic = `${nodeUrl}/arbitrary/THUMBNAIL/${mail.name}/qortal_avatar?async=true}`
|
||||||
|
|
||||||
`}
|
await routes.showNotification({
|
||||||
|
data: {
|
||||||
|
title: 'New Q-Mail',
|
||||||
|
type: 'qapp',
|
||||||
|
sound: config.messageAlert,
|
||||||
|
url: '',
|
||||||
|
options: {
|
||||||
|
body: `You have an unread mail from ${mail.name}`,
|
||||||
|
icon: urlPic,
|
||||||
|
badge: urlPic
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
${this.notificationCount ? html`
|
this.notifications = notificationsToShow
|
||||||
<span class="count">${this.notifications.length}</span>
|
|
||||||
` : ''}
|
|
||||||
|
|
||||||
<div class="popover-panel" ?hidden=${!this.showNotifications}>
|
this.notificationCount = this.notifications.length !== 0
|
||||||
<div class="notifications-list">
|
|
||||||
${this.notifications.map(notification => html`
|
|
||||||
<div class="notification-item" @click=${() => {
|
|
||||||
const query = `?service=APP&name=Q-Mail`
|
|
||||||
store.dispatch(setNewTab({
|
|
||||||
url: `qdn/browser/index.html${query}`,
|
|
||||||
id: 'q-mail-notification',
|
|
||||||
myPlugObj: {
|
|
||||||
"url": "myapp",
|
|
||||||
"domain": "core",
|
|
||||||
"page": `qdn/browser/index.html${query}`,
|
|
||||||
"title": "Q-Mail",
|
|
||||||
"icon": "vaadin:mailbox",
|
|
||||||
"mwcicon": "mail_outline",
|
|
||||||
"menus": [],
|
|
||||||
"parent": false
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
this.showNotifications = false
|
|
||||||
this.notifications = []
|
|
||||||
}}>
|
|
||||||
<div>
|
|
||||||
<p>Q-Mail</p>
|
|
||||||
<message-time timestamp=${notification.created} style="color:red;font-size:12px"></message-time>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
<p>${notification.name}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
_toggleNotifications() {
|
if (!this.initialFetch) this.initialFetch = true
|
||||||
if (this.notifications.length === 0) return
|
} catch (error) {
|
||||||
this.showNotifications = !this.showNotifications
|
console.error(error)
|
||||||
}
|
}
|
||||||
_openTabQmail() {
|
|
||||||
const query = `?service=APP&name=Q-Mail`
|
|
||||||
store.dispatch(setNewTab({
|
|
||||||
url: `qdn/browser/index.html${query}`,
|
|
||||||
id: 'q-mail-notification',
|
|
||||||
myPlugObj: {
|
|
||||||
"url": "myapp",
|
|
||||||
"domain": "core",
|
|
||||||
"page": `qdn/browser/index.html${query}`,
|
|
||||||
"title": "Q-Mail",
|
|
||||||
"icon": "vaadin:mailbox",
|
|
||||||
"mwcicon": "mail_outline",
|
|
||||||
"menus": [],
|
|
||||||
"parent": false
|
|
||||||
}
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
|
|
||||||
static styles = css`
|
stop = false
|
||||||
.layout {
|
}
|
||||||
display: flex;
|
}
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.count {
|
try {
|
||||||
position: absolute;
|
setTimeout(() => {
|
||||||
top: -5px;
|
getNewMail()
|
||||||
right: -5px;
|
}, 5000)
|
||||||
font-size: 12px;
|
|
||||||
background-color: red;
|
|
||||||
color: white;
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 16px;
|
|
||||||
height: 16px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.nocount {
|
interval = setInterval(getNewMail, 60000)
|
||||||
display: none;
|
} catch (error) {
|
||||||
}
|
console.error(error)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.popover-panel {
|
_toggleNotifications() {
|
||||||
position: absolute;
|
if (this.notifications.length === 0) return
|
||||||
width: 200px;
|
this.showNotifications = !this.showNotifications
|
||||||
padding: 10px;
|
}
|
||||||
background-color: var(--white);
|
|
||||||
border: 1px solid var(--black);
|
|
||||||
border-radius: 4px;
|
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
top: 40px;
|
|
||||||
max-height: 350px;
|
|
||||||
overflow: auto;
|
|
||||||
scrollbar-width: thin;
|
|
||||||
scrollbar-color: #6a6c75 #a1a1a1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.popover-panel::-webkit-scrollbar {
|
_openTabQmail() {
|
||||||
width: 11px;
|
const query = `?service=APP&name=Q-Mail`
|
||||||
}
|
|
||||||
|
|
||||||
.popover-panel::-webkit-scrollbar-track {
|
store.dispatch(setNewTab({
|
||||||
background: #a1a1a1;
|
url: `qdn/browser/index.html${query}`,
|
||||||
}
|
id: 'q-mail-notification',
|
||||||
|
myPlugObj: {
|
||||||
.popover-panel::-webkit-scrollbar-thumb {
|
"url": "myapp",
|
||||||
background-color: #6a6c75;
|
"domain": "core",
|
||||||
border-radius: 6px;
|
"page": `qdn/browser/index.html${query}`,
|
||||||
border: 3px solid #a1a1a1;
|
"title": "Q-Mail",
|
||||||
}
|
"icon": "vaadin:mailbox",
|
||||||
|
"mwcicon": "mail_outline",
|
||||||
.notifications-list {
|
"menus": [],
|
||||||
display: flex;
|
"parent": false
|
||||||
flex-direction: column;
|
}
|
||||||
}
|
}))
|
||||||
|
}
|
||||||
.notification-item {
|
|
||||||
padding: 5px;
|
|
||||||
border-bottom: 1px solid;
|
|
||||||
display: flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: 0.2s all;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notification-item:hover {
|
|
||||||
background: var(--nav-color-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
p {
|
|
||||||
font-size: 14px;
|
|
||||||
color: var(--black);
|
|
||||||
margin: 0px;
|
|
||||||
padding: 0px;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('notification-bell', NotificationBell)
|
window.customElements.define('notification-bell', NotificationBell)
|
@ -1,76 +1,56 @@
|
|||||||
// popover-component.js
|
import { css, html, LitElement } from 'lit'
|
||||||
import {css, html, LitElement} from 'lit';
|
import { createPopper } from '@popperjs/core'
|
||||||
import {createPopper} from '@popperjs/core';
|
import { popoverComponentStyles } from '../../styles/core-css'
|
||||||
import '@material/mwc-icon'
|
import '@material/mwc-icon'
|
||||||
|
|
||||||
export class PopoverComponent extends LitElement {
|
export class PopoverComponent extends LitElement {
|
||||||
static styles = css`
|
static get properties() {
|
||||||
:host {
|
return {
|
||||||
display: none;
|
for: { type: String, reflect: true },
|
||||||
position: absolute;
|
message: { type: String }
|
||||||
background-color: var(--white);
|
}
|
||||||
border: 1px solid #ddd;
|
}
|
||||||
padding: 8px;
|
|
||||||
z-index: 10;
|
|
||||||
box-shadow: 0 2px 10px rgba(0, 0, 0, 0.1);
|
|
||||||
color: var(--black);
|
|
||||||
max-width: 250px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close-icon {
|
static get styles() {
|
||||||
cursor: pointer;
|
return [popoverComponentStyles]
|
||||||
float: right;
|
}
|
||||||
margin-left: 10px;
|
|
||||||
color: var(--black)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
constructor() {
|
||||||
|
super()
|
||||||
|
this.message = ''
|
||||||
|
}
|
||||||
|
|
||||||
`;
|
render() {
|
||||||
|
return html`
|
||||||
|
<span class="close-icon" @click="${this.closePopover}"><mwc-icon style="color: var(--black)">close</mwc-icon></span>
|
||||||
|
<div><mwc-icon style="color: var(--black)">info</mwc-icon> ${this.message} <slot></slot></div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
static properties = {
|
attachToTarget(target) {
|
||||||
for: { type: String, reflect: true },
|
if (!this.popperInstance && target) {
|
||||||
message: { type: String }
|
this.popperInstance = createPopper(target, this, {
|
||||||
};
|
placement: 'bottom',
|
||||||
|
strategy: 'fixed'
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
openPopover(target) {
|
||||||
super();
|
this.attachToTarget(target)
|
||||||
this.message = '';
|
this.style.display = 'block'
|
||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated() {
|
closePopover() {
|
||||||
// We'll defer the popper attachment to the openPopover() method to ensure target availability
|
this.style.display = 'none'
|
||||||
}
|
|
||||||
|
|
||||||
attachToTarget(target) {
|
if (this.popperInstance) {
|
||||||
if (!this.popperInstance && target) {
|
this.popperInstance.destroy()
|
||||||
this.popperInstance = createPopper(target, this, {
|
this.popperInstance = null
|
||||||
placement: 'bottom',
|
}
|
||||||
strategy: 'fixed'
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
openPopover(target) {
|
this.requestUpdate()
|
||||||
this.attachToTarget(target);
|
}
|
||||||
this.style.display = 'block';
|
|
||||||
}
|
|
||||||
|
|
||||||
closePopover() {
|
|
||||||
this.style.display = 'none';
|
|
||||||
if (this.popperInstance) {
|
|
||||||
this.popperInstance.destroy();
|
|
||||||
this.popperInstance = null;
|
|
||||||
}
|
|
||||||
this.requestUpdate();
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return html`
|
|
||||||
<span class="close-icon" @click="${this.closePopover}"><mwc-icon style="color: var(--black)">close</mwc-icon></span>
|
|
||||||
<div><mwc-icon style="color: var(--black)">info</mwc-icon> ${this.message} <slot></slot>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define('popover-component', PopoverComponent);
|
window.customElements.define('popover-component', PopoverComponent)
|
@ -1,134 +1,62 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {svgMoon, svgSun} from '../../assets/js/svg.js'
|
import { svgMoon, svgSun } from '../../assets/js/svg'
|
||||||
|
import { qortThemeToggleStyles } from '../styles/core-css'
|
||||||
|
|
||||||
class QortThemeToggle extends LitElement {
|
class QortThemeToggle extends LitElement {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
theme: {
|
theme: { type: String, reflect: true }
|
||||||
type: String,
|
}
|
||||||
reflect: true
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super()
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light';
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = [
|
static get styles() {
|
||||||
css`
|
return [qortThemeToggleStyles]
|
||||||
:host {
|
}
|
||||||
display: inline-block;
|
|
||||||
position: relative;
|
|
||||||
width: 54px;
|
|
||||||
height: 32px;
|
|
||||||
transform: translateY(-2px);
|
|
||||||
}
|
|
||||||
|
|
||||||
svg {
|
render() {
|
||||||
width: 32px;
|
return html`
|
||||||
height: 32px;
|
<input type="checkbox" @change=${() => this.toggleTheme()}/>
|
||||||
}
|
<div class="slider"></div>
|
||||||
|
<div class="icon">
|
||||||
|
<span class="sun">${svgSun}</span>
|
||||||
|
<span class="moon">${svgMoon}</span>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
input {
|
firstUpdated() {
|
||||||
cursor: pointer;
|
this.initTheme()
|
||||||
position: absolute;
|
}
|
||||||
z-index: 1;
|
|
||||||
opacity: 0;
|
|
||||||
width: 100%;
|
|
||||||
height: 100%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.slider {
|
|
||||||
position: absolute;
|
|
||||||
cursor: pointer;
|
|
||||||
width: 100%;
|
|
||||||
height: 16px;
|
|
||||||
top: 50%;
|
|
||||||
transform: translateY(-50%);
|
|
||||||
background-color: var(--switchbackground);
|
|
||||||
border: 2px solid var(--switchborder);
|
|
||||||
border-radius: 1rem;
|
|
||||||
transition: all .4s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
.icon {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
display: inline-block;
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
background: var(--switchbackground);
|
|
||||||
border: 2px solid var(--switchborder);
|
|
||||||
border-radius: 50%;
|
|
||||||
transition: transform 300ms ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host([theme="light"]) .icon {
|
|
||||||
transform: translate(0, -50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
input:checked ~ .icon,
|
|
||||||
:host([theme="dark"]) .icon {
|
|
||||||
transform: translate(calc(100% - 12px), -50%);
|
|
||||||
}
|
|
||||||
|
|
||||||
.moon {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.moon svg {
|
|
||||||
transform: scale(0.6);
|
|
||||||
}
|
|
||||||
|
|
||||||
:host([theme="dark"]) .sun {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host([theme="dark"]) .moon {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
];
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return html`
|
|
||||||
<input type="checkbox" @change=${() => this.toggleTheme()}/>
|
|
||||||
<div class="slider"></div>
|
|
||||||
<div class="icon">
|
|
||||||
<span class="sun">${svgSun}</span>
|
|
||||||
<span class="moon">${svgMoon}</span>
|
|
||||||
</div>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
firstUpdated() {
|
|
||||||
this.initTheme();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
toggleTheme() {
|
toggleTheme() {
|
||||||
if (this.theme === 'light') {
|
if (this.theme === 'light') {
|
||||||
this.theme = 'dark';
|
this.theme = 'dark'
|
||||||
} else {
|
} else {
|
||||||
this.theme = 'light';
|
this.theme = 'light'
|
||||||
}
|
}
|
||||||
this.dispatchEvent(
|
|
||||||
new CustomEvent('qort-theme-change', {
|
|
||||||
bubbles: true,
|
|
||||||
composed: true,
|
|
||||||
detail: this.theme,
|
|
||||||
}),
|
|
||||||
);
|
|
||||||
|
|
||||||
window.localStorage.setItem('qortalTheme', this.theme);
|
this.dispatchEvent(
|
||||||
this.initTheme();
|
new CustomEvent('qort-theme-change', {
|
||||||
}
|
bubbles: true,
|
||||||
|
composed: true,
|
||||||
|
detail: this.theme
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
initTheme() {
|
window.localStorage.setItem('qortalTheme', this.theme)
|
||||||
document.querySelector('html').setAttribute('theme', this.theme);
|
|
||||||
}
|
this.initTheme()
|
||||||
|
}
|
||||||
|
|
||||||
|
initTheme() {
|
||||||
|
document.querySelector('html').setAttribute('theme', this.theme)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('qort-theme-toggle', QortThemeToggle);
|
window.customElements.define('qort-theme-toggle', QortThemeToggle)
|
@ -1,12 +1,14 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {get, translate} from '../../translate'
|
import { searchModalStyles } from '../styles/core-css'
|
||||||
import snackbar from '../functional-components/snackbar.js'
|
import snackbar from '../functional-components/snackbar'
|
||||||
|
|
||||||
import '@polymer/paper-icon-button/paper-icon-button.js'
|
import '@polymer/paper-icon-button/paper-icon-button.js'
|
||||||
import '@polymer/iron-icons/iron-icons.js'
|
import '@polymer/iron-icons/iron-icons.js'
|
||||||
import '@polymer/paper-dialog/paper-dialog.js'
|
import '@polymer/paper-dialog/paper-dialog.js'
|
||||||
import '@vaadin/text-field'
|
import '@vaadin/text-field'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { get, translate } from '../../translate'
|
||||||
|
|
||||||
class SearchModal extends LitElement {
|
class SearchModal extends LitElement {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
@ -15,56 +17,16 @@ class SearchModal extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return [searchModalStyles]
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
this.searchContentString = ''
|
this.searchContentString = ''
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
}
|
}
|
||||||
|
|
||||||
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);
|
|
||||||
--item-selected-color: var(--nav-selected-color);
|
|
||||||
--item-selected-color-text: var(--nav-selected-color-text);
|
|
||||||
--item-color-active: var(--nav-color-active);
|
|
||||||
--item-color-hover: var(--nav-color-hover);
|
|
||||||
--item-text-color: var(--nav-text-color);
|
|
||||||
--item-icon-color: var(--nav-icon-color);
|
|
||||||
--item-border-color: var(--nav-border-color);
|
|
||||||
--item-border-selected-color: var(--nav-border-selected-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
paper-dialog.searchSettings {
|
|
||||||
min-width: 525px;
|
|
||||||
max-width: 525px;
|
|
||||||
min-height: auto;
|
|
||||||
max-height: 150px;
|
|
||||||
background-color: var(--white);
|
|
||||||
color: var(--black);
|
|
||||||
line-height: 1.6;
|
|
||||||
overflow: hidden;
|
|
||||||
border: 1px solid var(--black);
|
|
||||||
border-radius: 10px;
|
|
||||||
padding: 15px;
|
|
||||||
box-shadow: 0px 10px 15px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
|
|
||||||
.search {
|
|
||||||
display: inline;
|
|
||||||
width: 50%;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div style="display: inline;">
|
<div style="display: inline;">
|
||||||
@ -92,6 +54,7 @@ class SearchModal extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated() {
|
firstUpdated() {
|
||||||
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
openSearch() {
|
openSearch() {
|
||||||
@ -110,23 +73,28 @@ class SearchModal extends LitElement {
|
|||||||
|
|
||||||
openUserInfo() {
|
openUserInfo() {
|
||||||
const checkvalue = this.shadowRoot.getElementById('searchContent').value
|
const checkvalue = this.shadowRoot.getElementById('searchContent').value
|
||||||
|
|
||||||
if (checkvalue.length < 3) {
|
if (checkvalue.length < 3) {
|
||||||
let snackbar1string = get("publishpage.pchange20")
|
let snackbar1string = get("publishpage.pchange20")
|
||||||
let snackbar2string = get("welcomepage.wcchange4")
|
let snackbar2string = get("welcomepage.wcchange4")
|
||||||
|
|
||||||
snackbar.add({
|
snackbar.add({
|
||||||
labelText: `${snackbar1string} ${snackbar2string}`,
|
labelText: `${snackbar1string} ${snackbar2string}`,
|
||||||
dismiss: true
|
dismiss: true
|
||||||
})
|
})
|
||||||
this.shadowRoot.getElementById('searchContent').value = this.searchContentString
|
|
||||||
|
|
||||||
|
this.shadowRoot.getElementById('searchContent').value = this.searchContentString
|
||||||
} else {
|
} else {
|
||||||
let sendInfoAddress = this.shadowRoot.getElementById('searchContent').value
|
let sendInfoAddress = this.shadowRoot.getElementById('searchContent').value
|
||||||
|
|
||||||
const infoDialog = document.getElementById('main-app').shadowRoot.querySelector('app-view').shadowRoot.querySelector('user-info-view')
|
const infoDialog = document.getElementById('main-app').shadowRoot.querySelector('app-view').shadowRoot.querySelector('user-info-view')
|
||||||
|
|
||||||
infoDialog.openUserInfo(sendInfoAddress)
|
infoDialog.openUserInfo(sendInfoAddress)
|
||||||
|
|
||||||
this.shadowRoot.getElementById('searchContent').value = this.searchContentString
|
this.shadowRoot.getElementById('searchContent').value = this.searchContentString
|
||||||
this.shadowRoot.getElementById('searchSettingsDialog').close()
|
this.shadowRoot.getElementById('searchSettingsDialog').close()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('search-modal', SearchModal)
|
window.customElements.define('search-modal', SearchModal)
|
@ -1,138 +1,92 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers'
|
import { connect } from 'pwa-helpers'
|
||||||
import {store} from '../../store.js'
|
import { store } from '../../store'
|
||||||
import {get, translate} from '../../../translate'
|
import { accountViewStyles } from '../../styles/core-css'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { get, translate } from '../../../translate'
|
||||||
|
|
||||||
class AccountView extends connect(store)(LitElement) {
|
class AccountView extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
accountInfo: { type: Object },
|
accountInfo: { type: Object },
|
||||||
theme: { type: String, reflect: true },
|
switchAvatar: { type: String },
|
||||||
switchAvatar: { type: String }
|
theme: { type: String, reflect: true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return css`
|
return [accountViewStyles]
|
||||||
|
}
|
||||||
|
|
||||||
.sub-main {
|
constructor() {
|
||||||
position: relative;
|
super()
|
||||||
text-align: center;
|
this.accountInfo = store.getState().app.accountInfo
|
||||||
}
|
this.switchAvatar = ''
|
||||||
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
|
}
|
||||||
|
|
||||||
.center-box {
|
render() {
|
||||||
position: relative;
|
return html`
|
||||||
top: 45%;
|
<div class="sub-main">
|
||||||
left: 50%;
|
<div class="center-box">
|
||||||
transform: translate(-50%, 0%);
|
<div class="img-icon">${this.getAvatar()}</div>
|
||||||
text-align: center;
|
<span id="accountName">
|
||||||
}
|
${this.accountInfo.names.length !== 0 ? this.accountInfo.names[0].name : get("chatpage.cchange15")}
|
||||||
|
</span>
|
||||||
|
<div class="content-box">
|
||||||
|
<span class="title">${translate("settings.address")}: </span>
|
||||||
|
<span class="value">${store.getState().app.selectedAddress.address}</span>
|
||||||
|
<br/>
|
||||||
|
<span class="title">${translate("settings.publickey")}: </span>
|
||||||
|
<span class="value">${store.getState().app.selectedAddress.base58PublicKey}</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
.img-icon {
|
firstUpdated() {
|
||||||
display: block;
|
this.getSwitchAvatar()
|
||||||
margin-top: 10px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-box {
|
setInterval(() => {
|
||||||
border: 1px solid #a1a1a1;
|
this.getSwitchAvatar()
|
||||||
padding: 10px 25px;
|
}, 10000)
|
||||||
text-align: left;
|
}
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
getAvatar() {
|
||||||
font-weight: 600;
|
if (this.switchAvatar === 'light') {
|
||||||
font-size: 15px;
|
if (this.accountInfo.names.length === 0) {
|
||||||
display: block;
|
return html`<img src="/img/noavatar_light.png" style="width:150px; height:150px; border-radius: 25%;">`
|
||||||
line-height: 32px;
|
} else {
|
||||||
opacity: 0.66;
|
const avatarName = this.accountInfo.names[0].name
|
||||||
}
|
const avatarNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
const avatarUrl = avatarNode.protocol + '://' + avatarNode.domain + ':' + avatarNode.port
|
||||||
|
const url = `${avatarUrl}/arbitrary/THUMBNAIL/${avatarName}/qortal_avatar?async=true`
|
||||||
|
|
||||||
.value {
|
return html`<img src="${url}" style="width:150px; height:150px; border-radius: 25%;" onerror="this.src='/img/noavatar_light.png';">`
|
||||||
font-size: 16px;
|
}
|
||||||
display: inline-block;
|
} else if (this.switchAvatar === 'dark') {
|
||||||
}
|
if (this.accountInfo.names.length === 0) {
|
||||||
|
return html`<img src="/img/noavatar_dark.png" style="width:150px; height:150px; border-radius: 25%;">`
|
||||||
|
} else {
|
||||||
|
const avatarName = this.accountInfo.names[0].name
|
||||||
|
const avatarNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
|
const avatarUrl = avatarNode.protocol + '://' + avatarNode.domain + ':' + avatarNode.port
|
||||||
|
const url = `${avatarUrl}/arbitrary/THUMBNAIL/${avatarName}/qortal_avatar?async=true`
|
||||||
|
|
||||||
#accountName {
|
return html`<img src="${url}" style="width:150px; height:150px; border-radius: 25%;" onerror="this.src='/img/noavatar_dark.png';">`
|
||||||
margin: 0;
|
}
|
||||||
font-size: 24px;
|
}
|
||||||
font-weight:500;
|
}
|
||||||
display: inline-block;
|
|
||||||
width:100%;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
getSwitchAvatar() {
|
||||||
super()
|
this.switchAvatar = localStorage.getItem('qortalTheme')
|
||||||
this.accountInfo = store.getState().app.accountInfo
|
}
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
|
||||||
this.switchAvatar = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
stateChanged(state) {
|
||||||
return html`
|
this.accountInfo = state.app.accountInfo
|
||||||
<div class="sub-main">
|
}
|
||||||
<div class="center-box">
|
|
||||||
<div class="img-icon">${this.getAvatar()}</div>
|
|
||||||
<span id="accountName">
|
|
||||||
${this.accountInfo.names.length !== 0 ? this.accountInfo.names[0].name : get("chatpage.cchange15")}
|
|
||||||
</span>
|
|
||||||
<div class="content-box">
|
|
||||||
<span class="title">${translate("settings.address")}: </span>
|
|
||||||
<span class="value">${store.getState().app.selectedAddress.address}</span>
|
|
||||||
<br/>
|
|
||||||
<span class="title">${translate("settings.publickey")}: </span>
|
|
||||||
<span class="value">${store.getState().app.selectedAddress.base58PublicKey}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
firstUpdated() {
|
|
||||||
this.getSwitchAvatar()
|
|
||||||
setInterval(() => {
|
|
||||||
this.getSwitchAvatar()
|
|
||||||
}, 2000)
|
|
||||||
}
|
|
||||||
|
|
||||||
getAvatar() {
|
|
||||||
if (this.switchAvatar === 'light') {
|
|
||||||
if (this.accountInfo.names.length === 0) {
|
|
||||||
return html`<img src="/img/noavatar_light.png" style="width:150px; height:150px; border-radius: 25%;">`
|
|
||||||
} else {
|
|
||||||
const avatarName = this.accountInfo.names[0].name
|
|
||||||
const avatarNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
|
||||||
const avatarUrl = avatarNode.protocol + '://' + avatarNode.domain + ':' + avatarNode.port
|
|
||||||
const url = `${avatarUrl}/arbitrary/THUMBNAIL/${avatarName}/qortal_avatar?async=true&apiKey=${this.getApiKey()}`
|
|
||||||
return html`<img src="${url}" style="width:150px; height:150px; border-radius: 25%;" onerror="this.src='/img/noavatar_light.png';">`
|
|
||||||
}
|
|
||||||
} else if (this.switchAvatar === 'dark') {
|
|
||||||
if (this.accountInfo.names.length === 0) {
|
|
||||||
return html`<img src="/img/noavatar_dark.png" style="width:150px; height:150px; border-radius: 25%;">`
|
|
||||||
} else {
|
|
||||||
const avatarName = this.accountInfo.names[0].name
|
|
||||||
const avatarNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
|
||||||
const avatarUrl = avatarNode.protocol + '://' + avatarNode.domain + ':' + avatarNode.port
|
|
||||||
const url = `${avatarUrl}/arbitrary/THUMBNAIL/${avatarName}/qortal_avatar?async=true&apiKey=${this.getApiKey()}`
|
|
||||||
return html`<img src="${url}" style="width:150px; height:150px; border-radius: 25%;" onerror="this.src='/img/noavatar_dark.png';">`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getSwitchAvatar() {
|
|
||||||
this.switchAvatar = localStorage.getItem('qortalTheme')
|
|
||||||
}
|
|
||||||
|
|
||||||
getApiKey() {
|
|
||||||
const apiNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
|
||||||
return apiNode.apiKey
|
|
||||||
}
|
|
||||||
|
|
||||||
stateChanged(state) {
|
|
||||||
this.accountInfo = state.app.accountInfo
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('account-view', AccountView)
|
window.customElements.define('account-view', AccountView)
|
@ -1,597 +1,423 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers'
|
import { connect } from 'pwa-helpers'
|
||||||
import {store} from '../../store.js'
|
import { store } from '../../store'
|
||||||
import {Epml} from '../../epml.js'
|
import { Epml } from '../../epml'
|
||||||
import {addTradeBotRoutes} from '../../tradebot/addTradeBotRoutes.js'
|
import { addTradeBotRoutes } from '../../tradebot/addTradeBotRoutes'
|
||||||
import {get, translate} from '../../../translate'
|
import { exportKeysStyles } from '../../styles/core-css'
|
||||||
import snackbar from '../../functional-components/snackbar.js'
|
|
||||||
import FileSaver from 'file-saver'
|
import FileSaver from 'file-saver'
|
||||||
|
import snackbar from '../../functional-components/snackbar'
|
||||||
import '@material/mwc-dialog'
|
|
||||||
import '@material/mwc-button'
|
import '@material/mwc-button'
|
||||||
|
import '@material/mwc-dialog'
|
||||||
import '@material/mwc-icon'
|
import '@material/mwc-icon'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { get, translate } from '../../../translate'
|
||||||
|
|
||||||
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
|
const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
|
||||||
|
|
||||||
class ExportKeys extends connect(store)(LitElement) {
|
class ExportKeys extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
theme: { type: String, reflect: true },
|
theme: { type: String, reflect: true },
|
||||||
backupErrorMessage: { type: String },
|
backupErrorMessage: { type: String },
|
||||||
btcPMK: { type: String },
|
btcPMK: { type: String },
|
||||||
ltcPMK: { type: String },
|
ltcPMK: { type: String },
|
||||||
dogePMK: { type: String },
|
dogePMK: { type: String },
|
||||||
dgbPMK: { type: String },
|
dgbPMK: { type: String },
|
||||||
rvnPMK: { type: String },
|
rvnPMK: { type: String },
|
||||||
arrrPMK: { type: String },
|
arrrPMK: { type: String },
|
||||||
btcWALLET: { type: String },
|
btcWALLET: { type: String },
|
||||||
ltcWALLET: { type: String },
|
ltcWALLET: { type: String },
|
||||||
dogeWALLET: { type: String },
|
dogeWALLET: { type: String },
|
||||||
dgbWALLET: { type: String },
|
dgbWALLET: { type: String },
|
||||||
rvnWALLET: { type: String },
|
rvnWALLET: { type: String },
|
||||||
arrrWALLET: { type: String },
|
arrrWALLET: { type: String },
|
||||||
btcName: { type: String },
|
btcName: { type: String },
|
||||||
ltcName: { type: String },
|
ltcName: { type: String },
|
||||||
dogeName: { type: String },
|
dogeName: { type: String },
|
||||||
dgbName: { type: String },
|
dgbName: { type: String },
|
||||||
rvnName: { type: String },
|
rvnName: { type: String },
|
||||||
arrrName: { type: String },
|
arrrName: { type: String },
|
||||||
btcShort: { type: String },
|
btcShort: { type: String },
|
||||||
ltcShort: { type: String },
|
ltcShort: { type: String },
|
||||||
dogeShort: { type: String },
|
dogeShort: { type: String },
|
||||||
dgbShort: { type: String },
|
dgbShort: { type: String },
|
||||||
rvnShort: { type: String },
|
rvnShort: { type: String },
|
||||||
arrrShort: { type: String },
|
arrrShort: { type: String },
|
||||||
enableArrr: { type: Boolean },
|
enableArrr: { type: Boolean },
|
||||||
dWalletAddress: { type: String },
|
dWalletAddress: { type: String },
|
||||||
dPrivateKey: { type: String },
|
dPrivateKey: { type: String },
|
||||||
dCoinName: { type: String },
|
dCoinName: { type: String },
|
||||||
dCoinShort: { type: String }
|
dCoinShort: { type: String }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return css`
|
return [exportKeysStyles]
|
||||||
* {
|
}
|
||||||
--mdc-theme-primary: rgb(3, 169, 244);
|
|
||||||
--mdc-theme-surface: var(--white);
|
|
||||||
--mdc-dialog-content-ink-color: var(--black);
|
|
||||||
--mdc-dialog-min-width: 500px;
|
|
||||||
--mdc-dialog-max-width: 750px;
|
|
||||||
--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 {
|
constructor() {
|
||||||
position: relative;
|
super()
|
||||||
top: 45%;
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
left: 50%;
|
this.backupErrorMessage = ''
|
||||||
transform: translate(-50%, 0%);
|
this.btcPMK = store.getState().app.selectedAddress.btcWallet.derivedMasterPrivateKey
|
||||||
text-align: center;
|
this.btcWALLET = store.getState().app.selectedAddress.btcWallet.address
|
||||||
}
|
this.btcName = 'Bitcoin'
|
||||||
|
this.btcShort = 'btc'
|
||||||
|
this.ltcPMK = store.getState().app.selectedAddress.ltcWallet.derivedMasterPrivateKey
|
||||||
|
this.ltcWALLET = store.getState().app.selectedAddress.ltcWallet.address
|
||||||
|
this.ltcName = 'Litecoin'
|
||||||
|
this.ltcShort = 'ltc'
|
||||||
|
this.dogePMK = store.getState().app.selectedAddress.dogeWallet.derivedMasterPrivateKey
|
||||||
|
this.dogeWALLET = store.getState().app.selectedAddress.dogeWallet.address
|
||||||
|
this.dogeName = 'Dogecoin'
|
||||||
|
this.dogeShort = 'doge'
|
||||||
|
this.dgbPMK = store.getState().app.selectedAddress.dgbWallet.derivedMasterPrivateKey
|
||||||
|
this.dgbWALLET = store.getState().app.selectedAddress.dgbWallet.address
|
||||||
|
this.dgbName = 'Digibyte'
|
||||||
|
this.dgbShort = 'dgb'
|
||||||
|
this.rvnPMK = store.getState().app.selectedAddress.rvnWallet.derivedMasterPrivateKey
|
||||||
|
this.rvnWALLET = store.getState().app.selectedAddress.rvnWallet.address
|
||||||
|
this.rvnName = 'Ravencoin'
|
||||||
|
this.rvnShort = 'rvn'
|
||||||
|
this.arrrPMK = ''
|
||||||
|
this.arrrWALLET = ''
|
||||||
|
this.arrrName = 'Pirate Chain'
|
||||||
|
this.arrrShort = 'arrr'
|
||||||
|
this.enableArrr = false
|
||||||
|
this.dWalletAddress = ''
|
||||||
|
this.dPrivateKey = ''
|
||||||
|
this.dCoinName = ''
|
||||||
|
this.dCoinShort = 'btc'
|
||||||
|
}
|
||||||
|
|
||||||
.sub-main {
|
render() {
|
||||||
position: relative;
|
return html`
|
||||||
text-align: center;
|
<div style="position: relative;">
|
||||||
height: auto;
|
<div class="center-box">
|
||||||
width: 100%;
|
<p>
|
||||||
}
|
${translate("settings.exp4")}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<div class="sub-main">
|
||||||
|
<div class="center-box">
|
||||||
|
<div class="content-box">
|
||||||
|
<div style="display: flex; align-items: center; justify-content: center;">
|
||||||
|
<img src="/img/btc.png" style="width: 32px; height: 32px;"> ${this.btcWALLET}<br>
|
||||||
|
</div>
|
||||||
|
<div @click=${() => this.checkForPmkDownload(this.btcWALLET, this.btcPMK, this.btcName, this.btcShort)} class="export-button"> ${translate("settings.exp2")} </div>
|
||||||
|
</div>
|
||||||
|
<div class="content-box">
|
||||||
|
<div style="display: flex; align-items: center; justify-content: center;">
|
||||||
|
<img src="/img/ltc.png" style="width: 32px; height: 32px;"> ${this.ltcWALLET}<br>
|
||||||
|
</div>
|
||||||
|
<div @click=${() => this.checkForPmkDownload(this.ltcWALLET, this.ltcPMK, this.ltcName, this.ltcShort)} class="export-button"> ${translate("settings.exp2")} </div>
|
||||||
|
</div>
|
||||||
|
<div class="content-box">
|
||||||
|
<div style="display: flex; align-items: center; justify-content: center;">
|
||||||
|
<img src="/img/doge.png" style="width: 32px; height: 32px;"> ${this.dogeWALLET}<br>
|
||||||
|
</div>
|
||||||
|
<div @click=${() => this.checkForPmkDownload(this.dogeWALLET, this.dogePMK, this.dogeName, this.dogeShort)} class="export-button"> ${translate("settings.exp2")} </div>
|
||||||
|
</div>
|
||||||
|
<div class="content-box">
|
||||||
|
<div style="display: flex; align-items: center; justify-content: center;">
|
||||||
|
<img src="/img/dgb.png" style="width: 32px; height: 32px;"> ${this.dgbWALLET}<br>
|
||||||
|
</div>
|
||||||
|
<div @click=${() => this.checkForPmkDownload(this.dgbWALLET, this.dgbPMK, this.dgbName, this.dgbShort)} class="export-button"> ${translate("settings.exp2")} </div>
|
||||||
|
</div>
|
||||||
|
<div class="content-box">
|
||||||
|
<div style="display: flex; align-items: center; justify-content: center;">
|
||||||
|
<img src="/img/rvn.png" style="width: 32px; height: 32px;"> ${this.rvnWALLET}<br>
|
||||||
|
</div>
|
||||||
|
<div @click=${() => this.checkForPmkDownload(this.rvnWALLET, this.rvnPMK, this.rvnName, this.rvnShort)} class="export-button"> ${translate("settings.exp2")} </div>
|
||||||
|
</div>
|
||||||
|
<div class="content-box" style="display:${this.enableArrr ? 'block' : 'none'}">
|
||||||
|
<div style="display: flex; align-items: center; justify-content: center;">
|
||||||
|
<img src="/img/arrr.png" style="width: 32px; height: 32px;"> ${this.arrrWALLET}<br>
|
||||||
|
</div>
|
||||||
|
<div @click=${() => this.checkForPmkDownload(this.arrrWALLET, this.arrrPMK, this.arrrName, this.arrrShort)} class="export-button"> ${translate("settings.exp2")} </div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr style="margin-top: 20px;">
|
||||||
|
<div class="button-row">
|
||||||
|
<button class="repair-button" title="${translate('nodepage.nchange38')}" @click="${() => this.openRepairLTCDialog()}">${translate("nodepage.nchange38")}</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<mwc-dialog id="savePkmDialog" scrimClickAction="" escapeKeyAction="">
|
||||||
|
<img src="/img/${this.dCoinShort}.png" style="width: 32px; height: 32px;">
|
||||||
|
<h3>${this.dCoinName} ${translate("settings.exp2")}</h3>
|
||||||
|
<hr>
|
||||||
|
<h4>${translate("settings.address")}: ${this.dWalletAddress}</h4>
|
||||||
|
<mwc-button
|
||||||
|
slot="primaryAction"
|
||||||
|
@click="${() => this.closeSavePkmDialog()}"
|
||||||
|
class="red"
|
||||||
|
>
|
||||||
|
${translate("general.close")}
|
||||||
|
</mwc-button>
|
||||||
|
<mwc-button
|
||||||
|
slot="secondaryAction"
|
||||||
|
@click="${() => this.exportKey(this.dPrivateKey, this.dCoinName, this.dWalletAddress)}"
|
||||||
|
>
|
||||||
|
${translate("settings.exp3")}
|
||||||
|
</mwc-button>
|
||||||
|
</mwc-dialog>
|
||||||
|
<mwc-dialog id="arrrWalletNotSynced" scrimClickAction="" escapeKeyAction="">
|
||||||
|
<img src="/img/arrr.png" style="width: 32px; height: 32px;">
|
||||||
|
<h3>${translate("settings.arrr1")}</h3>
|
||||||
|
<hr>
|
||||||
|
<h4>${translate("settings.arrr2")}</h4>
|
||||||
|
<mwc-button
|
||||||
|
slot="primaryAction"
|
||||||
|
@click="${() => this.closeArrrWalletNotSynced()}"
|
||||||
|
class="red"
|
||||||
|
>
|
||||||
|
${translate("general.close")}
|
||||||
|
</mwc-button>
|
||||||
|
</mwc-dialog>
|
||||||
|
<mwc-dialog id="needCoreUpdate" scrimClickAction="" escapeKeyAction="">
|
||||||
|
<img src="/img/arrr.png" style="width: 32px; height: 32px;">
|
||||||
|
<h3>${translate("settings.arrr3")}</h3>
|
||||||
|
<hr>
|
||||||
|
<h4>${translate("settings.arrr4")}</h4>
|
||||||
|
<mwc-button
|
||||||
|
slot="primaryAction"
|
||||||
|
@click="${() => this.closeNeedCoreUpdate()}"
|
||||||
|
class="red"
|
||||||
|
>
|
||||||
|
${translate("general.close")}
|
||||||
|
</mwc-button>
|
||||||
|
</mwc-dialog>
|
||||||
|
<mwc-dialog id="repairLTCDialog" scrimClickAction="" escapeKeyAction="">
|
||||||
|
<img src="/img/ltc.png" style="width: 32px; height: 32px;">
|
||||||
|
<h3>${translate("nodepage.nchange38")}</h3>
|
||||||
|
<hr>
|
||||||
|
<h4>${translate("nodepage.nchange39")}</h4>
|
||||||
|
<h4>${translate("nodepage.nchange40")}</h4>
|
||||||
|
<mwc-button slot="primaryAction" @click="${() => this.repairLtcWallet()}" class="green">
|
||||||
|
${translate("general.continue")}
|
||||||
|
</mwc-button>
|
||||||
|
<mwc-button slot="secondaryAction" @click="${() => this.closeRepairLTCDialog()}" class="red">
|
||||||
|
${translate("login.lp4")}
|
||||||
|
</mwc-button>
|
||||||
|
</mwc-dialog>
|
||||||
|
<mwc-dialog id="pleaseWaitDialog" scrimClickAction="" escapeKeyAction="">
|
||||||
|
<div class="lds-roller">
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
<div></div>
|
||||||
|
</div>
|
||||||
|
<h2>${translate("nodepage.nchange41")}</h2>
|
||||||
|
</mwc-dialog>
|
||||||
|
<mwc-dialog id="okDialog" scrimClickAction="" escapeKeyAction="">
|
||||||
|
<img src="/img/ltc.png" style="width: 32px; height: 32px;">
|
||||||
|
<h3>${translate("nodepage.nchange38")}</h3>
|
||||||
|
<hr>
|
||||||
|
<h3>${translate("nodepage.nchange42")}</h3>
|
||||||
|
</mwc-dialog>
|
||||||
|
<mwc-dialog id="errorDialog" scrimClickAction="" escapeKeyAction="">
|
||||||
|
<img src="/img/ltc.png" style="width: 32px; height: 32px;">
|
||||||
|
<h3>${translate("nodepage.nchange38")}</h3>
|
||||||
|
<hr>
|
||||||
|
<h3>${translate("nodepage.nchange43")}</h3>
|
||||||
|
</mwc-dialog>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
.content-box {
|
async firstUpdated() {
|
||||||
text-align: center;
|
addTradeBotRoutes(parentEpml)
|
||||||
display: inline-block;
|
parentEpml.imReady()
|
||||||
min-width: 400px;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
margin-left: 10px;
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.export-button {
|
await this.fetchArrrWalletAddress()
|
||||||
display: inline-flex;
|
await this.checkArrrWalletPrivateKey()
|
||||||
flex-direction: column;
|
}
|
||||||
justify-content: center;
|
|
||||||
align-content: center;
|
|
||||||
border: none;
|
|
||||||
border-radius: 20px;
|
|
||||||
padding-left: 10px;
|
|
||||||
padding-right: 10px;
|
|
||||||
color: white;
|
|
||||||
background: #03a9f4;
|
|
||||||
width: 75%;
|
|
||||||
font-size: 16px;
|
|
||||||
cursor: pointer;
|
|
||||||
height: 40px;
|
|
||||||
margin-top: 1rem;
|
|
||||||
text-transform: uppercase;
|
|
||||||
text-decoration: none;
|
|
||||||
transition: all .2s;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
|
|
||||||
.red {
|
async fetchArrrWalletAddress() {
|
||||||
--mdc-theme-primary: #F44336;
|
let resAD = await parentEpml.request('apiCall', {
|
||||||
}
|
url: `/crosschain/arrr/walletaddress?apiKey=${this.getApiKey()}`,
|
||||||
|
method: 'POST',
|
||||||
|
body: `${store.getState().app.selectedAddress.arrrWallet.seed58}`
|
||||||
|
})
|
||||||
|
|
||||||
.green {
|
if (resAD != null && resAD.error != 1201) {
|
||||||
--mdc-theme-primary: #198754;
|
this.arrrWALLET = ''
|
||||||
}
|
this.enableArrr = true
|
||||||
|
this.arrrWALLET = resAD
|
||||||
|
} else {
|
||||||
|
this.arrrWALLET = ''
|
||||||
|
this.enableArrr = false
|
||||||
|
this.shadowRoot.querySelector('#arrrWalletNotSynced').show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.button-row {
|
async checkArrrWalletPrivateKey() {
|
||||||
position: relative;
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
display: flex;
|
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
align-items: center;
|
const privateKeyUrl = `${nodeUrl}/crosschain/arrr/walletprivatekey?apiKey=${this.getApiKey()}`
|
||||||
align-content: center;
|
|
||||||
font-family: Montserrat, sans-serif;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--black);
|
|
||||||
margin-top: 20px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.repair-button {
|
await fetch(privateKeyUrl, {
|
||||||
height: 40px;
|
method: 'POST',
|
||||||
padding: 10px 10px;
|
body: `${store.getState().app.selectedAddress.arrrWallet.seed58}`
|
||||||
font-size: 16px;
|
}).then(res => {
|
||||||
font-weight: 500;
|
if (res.status === 404) {
|
||||||
background-color: #03a9f4;
|
this.arrrPMK = ''
|
||||||
color: white;
|
this.enableArrr = false
|
||||||
border: 1px solid transparent;
|
this.shadowRoot.querySelector('#needCoreUpdate').show()
|
||||||
border-radius: 20px;
|
} else {
|
||||||
text-decoration: none;
|
this.fetchArrrWalletPrivateKey()
|
||||||
text-transform: uppercase;
|
}
|
||||||
cursor: pointer;
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
.repair-button:hover {
|
async fetchArrrWalletPrivateKey() {
|
||||||
opacity: 0.8;
|
let resPK = await parentEpml.request('apiCall', {
|
||||||
cursor: pointer;
|
url: `/crosschain/arrr/walletprivatekey?apiKey=${this.getApiKey()}`,
|
||||||
}
|
method: 'POST',
|
||||||
|
body: `${store.getState().app.selectedAddress.arrrWallet.seed58}`
|
||||||
|
})
|
||||||
|
|
||||||
.lds-roller {
|
if (resPK != null && resPK.error != 1201) {
|
||||||
display: inline-block;
|
this.arrrPMK = ''
|
||||||
position: relative;
|
this.enableArrr = true
|
||||||
width: 80px;
|
this.arrrPMK = resPK
|
||||||
height: 80px;
|
} else {
|
||||||
}
|
this.arrrPMK = ''
|
||||||
|
this.enableArrr = false
|
||||||
|
this.shadowRoot.querySelector('#arrrWalletNotSynced').show()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.lds-roller div {
|
closeArrrWalletNotSynced() {
|
||||||
animation: lds-roller 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
|
this.shadowRoot.querySelector('#arrrWalletNotSynced').close()
|
||||||
transform-origin: 40px 40px;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.lds-roller div:after {
|
closeNeedCoreUpdate() {
|
||||||
content: " ";
|
this.arrrPMK = ''
|
||||||
display: block;
|
this.enableArrr = false
|
||||||
position: absolute;
|
this.shadowRoot.querySelector('#needCoreUpdate').close()
|
||||||
width: 7px;
|
}
|
||||||
height: 7px;
|
|
||||||
border-radius: 50%;
|
|
||||||
background: var(--black);
|
|
||||||
margin: -4px 0 0 -4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lds-roller div:nth-child(1) {
|
closeSavePkmDialog() {
|
||||||
animation-delay: -0.036s;
|
this.shadowRoot.querySelector('#savePkmDialog').close()
|
||||||
}
|
}
|
||||||
|
|
||||||
.lds-roller div:nth-child(1):after {
|
openRepairLTCDialog() {
|
||||||
top: 63px;
|
this.shadowRoot.querySelector('#repairLTCDialog').show()
|
||||||
left: 63px;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.lds-roller div:nth-child(2) {
|
closeRepairLTCDialog() {
|
||||||
animation-delay: -0.072s;
|
this.shadowRoot.querySelector('#repairLTCDialog').close()
|
||||||
}
|
}
|
||||||
|
|
||||||
.lds-roller div:nth-child(2):after {
|
async repairLtcWallet() {
|
||||||
top: 68px;
|
this.shadowRoot.querySelector('#repairLTCDialog').close()
|
||||||
left: 56px;
|
this.shadowRoot.querySelector('#pleaseWaitDialog').show()
|
||||||
}
|
|
||||||
|
|
||||||
.lds-roller div:nth-child(3) {
|
let resRepair = await parentEpml.request('apiCall', {
|
||||||
animation-delay: -0.108s;
|
url: `/crosschain/ltc/repair?apiKey=${this.getApiKey()}`,
|
||||||
}
|
method: 'POST',
|
||||||
|
body: `${store.getState().app.selectedAddress.ltcWallet.derivedMasterPrivateKey}`
|
||||||
|
})
|
||||||
|
|
||||||
.lds-roller div:nth-child(3):after {
|
if (resRepair != null && resRepair.error != 128) {
|
||||||
top: 71px;
|
this.shadowRoot.querySelector('#pleaseWaitDialog').close()
|
||||||
left: 48px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lds-roller div:nth-child(4) {
|
await this.openOkDialog()
|
||||||
animation-delay: -0.144s;
|
} else {
|
||||||
}
|
this.shadowRoot.querySelector('#pleaseWaitDialog').close()
|
||||||
|
|
||||||
.lds-roller div:nth-child(4):after {
|
await this.openErrorDialog()
|
||||||
top: 72px;
|
}
|
||||||
left: 40px;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.lds-roller div:nth-child(5) {
|
async openOkDialog() {
|
||||||
animation-delay: -0.18s;
|
const okDelay = ms => new Promise(res => setTimeout(res, ms))
|
||||||
}
|
|
||||||
|
|
||||||
.lds-roller div:nth-child(5):after {
|
this.shadowRoot.querySelector('#okDialog').show()
|
||||||
top: 71px;
|
|
||||||
left: 32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lds-roller div:nth-child(6) {
|
await okDelay(3000)
|
||||||
animation-delay: -0.216s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lds-roller div:nth-child(6):after {
|
this.shadowRoot.querySelector('#okDialog').close()
|
||||||
top: 68px;
|
}
|
||||||
left: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lds-roller div:nth-child(7) {
|
async openErrorDialog() {
|
||||||
animation-delay: -0.252s;
|
const errorDelay = ms => new Promise(res => setTimeout(res, ms))
|
||||||
}
|
|
||||||
|
|
||||||
.lds-roller div:nth-child(7):after {
|
this.shadowRoot.querySelector('#errorDialog').show()
|
||||||
top: 63px;
|
|
||||||
left: 17px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lds-roller div:nth-child(8) {
|
await errorDelay(3000)
|
||||||
animation-delay: -0.288s;
|
|
||||||
}
|
|
||||||
|
|
||||||
.lds-roller div:nth-child(8):after {
|
this.shadowRoot.querySelector('#errorDialog').close()
|
||||||
top: 56px;
|
}
|
||||||
left: 12px;
|
|
||||||
}
|
|
||||||
|
|
||||||
@keyframes lds-roller {
|
checkForPmkDownload(wAddress, wPkm, wName, wShort) {
|
||||||
0% {
|
this.dWalletAddress = ''
|
||||||
transform: rotate(0deg);
|
this.dPrivateKey = ''
|
||||||
}
|
this.dCoinName = ''
|
||||||
100% {
|
this.dCoinShort = ''
|
||||||
transform: rotate(360deg);
|
this.dWalletAddress = wAddress
|
||||||
}
|
this.dPrivateKey = wPkm
|
||||||
}
|
this.dCoinName = wName
|
||||||
`
|
this.dCoinShort = wShort
|
||||||
}
|
this.shadowRoot.querySelector('#savePkmDialog').show()
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
async exportKey(cMasterKey, cName, cAddress) {
|
||||||
super()
|
let exportname = ''
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
|
||||||
this.backupErrorMessage = ''
|
|
||||||
this.btcPMK = store.getState().app.selectedAddress.btcWallet.derivedMasterPrivateKey
|
|
||||||
this.btcWALLET = store.getState().app.selectedAddress.btcWallet.address
|
|
||||||
this.btcName = 'Bitcoin'
|
|
||||||
this.btcShort = 'btc'
|
|
||||||
this.ltcPMK = store.getState().app.selectedAddress.ltcWallet.derivedMasterPrivateKey
|
|
||||||
this.ltcWALLET = store.getState().app.selectedAddress.ltcWallet.address
|
|
||||||
this.ltcName = 'Litecoin'
|
|
||||||
this.ltcShort = 'ltc'
|
|
||||||
this.dogePMK = store.getState().app.selectedAddress.dogeWallet.derivedMasterPrivateKey
|
|
||||||
this.dogeWALLET = store.getState().app.selectedAddress.dogeWallet.address
|
|
||||||
this.dogeName = 'Dogecoin'
|
|
||||||
this.dogeShort = 'doge'
|
|
||||||
this.dgbPMK = store.getState().app.selectedAddress.dgbWallet.derivedMasterPrivateKey
|
|
||||||
this.dgbWALLET = store.getState().app.selectedAddress.dgbWallet.address
|
|
||||||
this.dgbName = 'Digibyte'
|
|
||||||
this.dgbShort = 'dgb'
|
|
||||||
this.rvnPMK = store.getState().app.selectedAddress.rvnWallet.derivedMasterPrivateKey
|
|
||||||
this.rvnWALLET = store.getState().app.selectedAddress.rvnWallet.address
|
|
||||||
this.rvnName = 'Ravencoin'
|
|
||||||
this.rvnShort = 'rvn'
|
|
||||||
this.arrrPMK = ''
|
|
||||||
this.arrrWALLET = ''
|
|
||||||
this.arrrName = 'Pirate Chain'
|
|
||||||
this.arrrShort = 'arrr'
|
|
||||||
this.enableArrr = false
|
|
||||||
this.dWalletAddress = ''
|
|
||||||
this.dPrivateKey = ''
|
|
||||||
this.dCoinName = ''
|
|
||||||
this.dCoinShort = 'btc'
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
const myPrivateMasterKey = cMasterKey
|
||||||
return html`
|
const myCoinName = cName
|
||||||
<div style="position: relative;">
|
const myCoinAddress = cAddress
|
||||||
<div class="center-box">
|
const blob = new Blob([`${myPrivateMasterKey}`], { type: 'text/plain;charset=utf-8' })
|
||||||
<p>
|
|
||||||
${translate("settings.exp4")}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div class="sub-main">
|
|
||||||
<div class="center-box">
|
|
||||||
<div class="content-box">
|
|
||||||
<div style="display: flex; align-items: center; justify-content: center;">
|
|
||||||
<img src="/img/btc.png" style="width: 32px; height: 32px;"> ${this.btcWALLET}<br>
|
|
||||||
</div>
|
|
||||||
<div @click=${() => this.checkForPmkDownload(this.btcWALLET, this.btcPMK, this.btcName, this.btcShort)} class="export-button"> ${translate("settings.exp2")} </div>
|
|
||||||
</div>
|
|
||||||
<div class="content-box">
|
|
||||||
<div style="display: flex; align-items: center; justify-content: center;">
|
|
||||||
<img src="/img/ltc.png" style="width: 32px; height: 32px;"> ${this.ltcWALLET}<br>
|
|
||||||
</div>
|
|
||||||
<div @click=${() => this.checkForPmkDownload(this.ltcWALLET, this.ltcPMK, this.ltcName, this.ltcShort)} class="export-button"> ${translate("settings.exp2")} </div>
|
|
||||||
</div>
|
|
||||||
<div class="content-box">
|
|
||||||
<div style="display: flex; align-items: center; justify-content: center;">
|
|
||||||
<img src="/img/doge.png" style="width: 32px; height: 32px;"> ${this.dogeWALLET}<br>
|
|
||||||
</div>
|
|
||||||
<div @click=${() => this.checkForPmkDownload(this.dogeWALLET, this.dogePMK, this.dogeName, this.dogeShort)} class="export-button"> ${translate("settings.exp2")} </div>
|
|
||||||
</div>
|
|
||||||
<div class="content-box">
|
|
||||||
<div style="display: flex; align-items: center; justify-content: center;">
|
|
||||||
<img src="/img/dgb.png" style="width: 32px; height: 32px;"> ${this.dgbWALLET}<br>
|
|
||||||
</div>
|
|
||||||
<div @click=${() => this.checkForPmkDownload(this.dgbWALLET, this.dgbPMK, this.dgbName, this.dgbShort)} class="export-button"> ${translate("settings.exp2")} </div>
|
|
||||||
</div>
|
|
||||||
<div class="content-box">
|
|
||||||
<div style="display: flex; align-items: center; justify-content: center;">
|
|
||||||
<img src="/img/rvn.png" style="width: 32px; height: 32px;"> ${this.rvnWALLET}<br>
|
|
||||||
</div>
|
|
||||||
<div @click=${() => this.checkForPmkDownload(this.rvnWALLET, this.rvnPMK, this.rvnName, this.rvnShort)} class="export-button"> ${translate("settings.exp2")} </div>
|
|
||||||
</div>
|
|
||||||
<div class="content-box" style="display:${this.enableArrr ? 'block' : 'none'}">
|
|
||||||
<div style="display: flex; align-items: center; justify-content: center;">
|
|
||||||
<img src="/img/arrr.png" style="width: 32px; height: 32px;"> ${this.arrrWALLET}<br>
|
|
||||||
</div>
|
|
||||||
<div @click=${() => this.checkForPmkDownload(this.arrrWALLET, this.arrrPMK, this.arrrName, this.arrrShort)} class="export-button"> ${translate("settings.exp2")} </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr style="margin-top: 20px;">
|
|
||||||
<div class="button-row">
|
|
||||||
<button class="repair-button" title="${translate('nodepage.nchange38')}" @click="${() => this.openRepairLTCDialog()}">${translate("nodepage.nchange38")}</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<mwc-dialog id="savePkmDialog" scrimClickAction="" escapeKeyAction="">
|
|
||||||
<img src="/img/${this.dCoinShort}.png" style="width: 32px; height: 32px;">
|
|
||||||
<h3>${this.dCoinName} ${translate("settings.exp2")}</h3>
|
|
||||||
<hr>
|
|
||||||
<h4>${translate("settings.address")}: ${this.dWalletAddress}</h4>
|
|
||||||
<mwc-button
|
|
||||||
slot="primaryAction"
|
|
||||||
@click="${() => this.closeSavePkmDialog()}"
|
|
||||||
class="red"
|
|
||||||
>
|
|
||||||
${translate("general.close")}
|
|
||||||
</mwc-button>
|
|
||||||
<mwc-button
|
|
||||||
slot="secondaryAction"
|
|
||||||
@click="${() => this.exportKey(this.dPrivateKey, this.dCoinName, this.dWalletAddress)}"
|
|
||||||
>
|
|
||||||
${translate("settings.exp3")}
|
|
||||||
</mwc-button>
|
|
||||||
</mwc-dialog>
|
|
||||||
<mwc-dialog id="arrrWalletNotSynced" scrimClickAction="" escapeKeyAction="">
|
|
||||||
<img src="/img/arrr.png" style="width: 32px; height: 32px;">
|
|
||||||
<h3>${translate("settings.arrr1")}</h3>
|
|
||||||
<hr>
|
|
||||||
<h4>${translate("settings.arrr2")}</h4>
|
|
||||||
<mwc-button
|
|
||||||
slot="primaryAction"
|
|
||||||
@click="${() => this.closeArrrWalletNotSynced()}"
|
|
||||||
class="red"
|
|
||||||
>
|
|
||||||
${translate("general.close")}
|
|
||||||
</mwc-button>
|
|
||||||
</mwc-dialog>
|
|
||||||
<mwc-dialog id="needCoreUpdate" scrimClickAction="" escapeKeyAction="">
|
|
||||||
<img src="/img/arrr.png" style="width: 32px; height: 32px;">
|
|
||||||
<h3>${translate("settings.arrr3")}</h3>
|
|
||||||
<hr>
|
|
||||||
<h4>${translate("settings.arrr4")}</h4>
|
|
||||||
<mwc-button
|
|
||||||
slot="primaryAction"
|
|
||||||
@click="${() => this.closeNeedCoreUpdate()}"
|
|
||||||
class="red"
|
|
||||||
>
|
|
||||||
${translate("general.close")}
|
|
||||||
</mwc-button>
|
|
||||||
</mwc-dialog>
|
|
||||||
<mwc-dialog id="repairLTCDialog" scrimClickAction="" escapeKeyAction="">
|
|
||||||
<img src="/img/ltc.png" style="width: 32px; height: 32px;">
|
|
||||||
<h3>${translate("nodepage.nchange38")}</h3>
|
|
||||||
<hr>
|
|
||||||
<h4>${translate("nodepage.nchange39")}</h4>
|
|
||||||
<h4>${translate("nodepage.nchange40")}</h4>
|
|
||||||
<mwc-button slot="primaryAction" @click="${() => this.repairLtcWallet()}" class="green">
|
|
||||||
${translate("general.continue")}
|
|
||||||
</mwc-button>
|
|
||||||
<mwc-button slot="secondaryAction" @click="${() => this.closeRepairLTCDialog()}" class="red">
|
|
||||||
${translate("login.lp4")}
|
|
||||||
</mwc-button>
|
|
||||||
</mwc-dialog>
|
|
||||||
<mwc-dialog id="pleaseWaitDialog" scrimClickAction="" escapeKeyAction="">
|
|
||||||
<div class="lds-roller"><div></div><div></div><div></div><div></div><div></div><div></div><div></div><div></div></div>
|
|
||||||
<h2>${translate("nodepage.nchange41")}</h2>
|
|
||||||
</mwc-dialog>
|
|
||||||
<mwc-dialog id="okDialog" scrimClickAction="" escapeKeyAction="">
|
|
||||||
<img src="/img/ltc.png" style="width: 32px; height: 32px;">
|
|
||||||
<h3>${translate("nodepage.nchange38")}</h3>
|
|
||||||
<hr>
|
|
||||||
<h3>${translate("nodepage.nchange42")}</h3>
|
|
||||||
</mwc-dialog>
|
|
||||||
<mwc-dialog id="errorDialog" scrimClickAction="" escapeKeyAction="">
|
|
||||||
<img src="/img/ltc.png" style="width: 32px; height: 32px;">
|
|
||||||
<h3>${translate("nodepage.nchange38")}</h3>
|
|
||||||
<hr>
|
|
||||||
<h3>${translate("nodepage.nchange43")}</h3>
|
|
||||||
</mwc-dialog>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
async firstUpdated() {
|
exportname = 'Private_Master_Key_' + myCoinName + '_' + myCoinAddress + '.txt'
|
||||||
addTradeBotRoutes(parentEpml)
|
|
||||||
parentEpml.imReady()
|
|
||||||
await this.fetchArrrWalletAddress()
|
|
||||||
await this.checkArrrWalletPrivateKey()
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchArrrWalletAddress() {
|
await this.saveFileToDisk(blob, exportname)
|
||||||
let resAD = await parentEpml.request('apiCall', {
|
}
|
||||||
url: `/crosschain/arrr/walletaddress?apiKey=${this.getApiKey()}`,
|
|
||||||
method: 'POST',
|
|
||||||
body: `${store.getState().app.selectedAddress.arrrWallet.seed58}`
|
|
||||||
})
|
|
||||||
|
|
||||||
if (resAD != null && resAD.error != 1201) {
|
async saveFileToDisk(blob, fileName) {
|
||||||
this.arrrWALLET = ''
|
try {
|
||||||
this.enableArrr = true
|
const fileHandle = await self.showSaveFilePicker({
|
||||||
this.arrrWALLET = resAD
|
suggestedName: fileName,
|
||||||
} else {
|
types: [{
|
||||||
this.arrrWALLET = ''
|
description: "File"
|
||||||
this.enableArrr = false
|
}]
|
||||||
this.shadowRoot.querySelector('#arrrWalletNotSynced').show()
|
})
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async checkArrrWalletPrivateKey() {
|
const writeFile = async (fileHandle, contents) => {
|
||||||
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
const writable = await fileHandle.createWritable()
|
||||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
|
||||||
const privateKeyUrl = `${nodeUrl}/crosschain/arrr/walletprivatekey?apiKey=${this.getApiKey()}`
|
|
||||||
|
|
||||||
await fetch(privateKeyUrl, {
|
await writable.write(contents)
|
||||||
method: 'POST',
|
await writable.close()
|
||||||
body: `${store.getState().app.selectedAddress.arrrWallet.seed58}`
|
}
|
||||||
}).then(res => {
|
|
||||||
if (res.status === 404) {
|
|
||||||
this.arrrPMK = ''
|
|
||||||
this.enableArrr = false
|
|
||||||
this.shadowRoot.querySelector('#needCoreUpdate').show()
|
|
||||||
} else {
|
|
||||||
this.fetchArrrWalletPrivateKey()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async fetchArrrWalletPrivateKey() {
|
writeFile(fileHandle, blob).then(() => console.log("FILE SAVED"))
|
||||||
let resPK = await parentEpml.request('apiCall', {
|
|
||||||
url: `/crosschain/arrr/walletprivatekey?apiKey=${this.getApiKey()}`,
|
|
||||||
method: 'POST',
|
|
||||||
body: `${store.getState().app.selectedAddress.arrrWallet.seed58}`
|
|
||||||
})
|
|
||||||
|
|
||||||
if (resPK != null && resPK.error != 1201) {
|
let snack4string = get("general.save")
|
||||||
this.arrrPMK = ''
|
|
||||||
this.enableArrr = true
|
|
||||||
this.arrrPMK = resPK
|
|
||||||
} else {
|
|
||||||
this.arrrPMK = ''
|
|
||||||
this.enableArrr = false
|
|
||||||
this.shadowRoot.querySelector('#arrrWalletNotSynced').show()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closeArrrWalletNotSynced() {
|
snackbar.add({
|
||||||
this.shadowRoot.querySelector('#arrrWalletNotSynced').close()
|
labelText: `${snack4string} ${fileName} ✅`,
|
||||||
}
|
dismiss: true
|
||||||
|
})
|
||||||
|
} catch (error) {
|
||||||
|
if (error.name === 'AbortError') {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
closeNeedCoreUpdate() {
|
FileSaver.saveAs(blob, fileName)
|
||||||
this.arrrPMK = ''
|
}
|
||||||
this.enableArrr = false
|
}
|
||||||
this.shadowRoot.querySelector('#needCoreUpdate').close()
|
|
||||||
}
|
|
||||||
|
|
||||||
closeSavePkmDialog() {
|
getApiKey() {
|
||||||
this.shadowRoot.querySelector('#savePkmDialog').close()
|
const apiNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
}
|
|
||||||
|
|
||||||
openRepairLTCDialog() {
|
|
||||||
this.shadowRoot.querySelector('#repairLTCDialog').show()
|
|
||||||
}
|
|
||||||
|
|
||||||
closeRepairLTCDialog() {
|
|
||||||
this.shadowRoot.querySelector('#repairLTCDialog').close()
|
|
||||||
}
|
|
||||||
|
|
||||||
async repairLtcWallet() {
|
|
||||||
this.shadowRoot.querySelector('#repairLTCDialog').close()
|
|
||||||
this.shadowRoot.querySelector('#pleaseWaitDialog').show()
|
|
||||||
let resRepair = await parentEpml.request('apiCall', {
|
|
||||||
url: `/crosschain/ltc/repair?apiKey=${this.getApiKey()}`,
|
|
||||||
method: 'POST',
|
|
||||||
body: `${store.getState().app.selectedAddress.ltcWallet.derivedMasterPrivateKey}`
|
|
||||||
})
|
|
||||||
|
|
||||||
if (resRepair != null && resRepair.error != 128) {
|
|
||||||
this.shadowRoot.querySelector('#pleaseWaitDialog').close()
|
|
||||||
await this.openOkDialog()
|
|
||||||
} else {
|
|
||||||
this.shadowRoot.querySelector('#pleaseWaitDialog').close()
|
|
||||||
await this.openErrorDialog()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
async openOkDialog() {
|
|
||||||
const okDelay = ms => new Promise(res => setTimeout(res, ms))
|
|
||||||
this.shadowRoot.querySelector('#okDialog').show()
|
|
||||||
await okDelay(3000)
|
|
||||||
this.shadowRoot.querySelector('#okDialog').close()
|
|
||||||
}
|
|
||||||
|
|
||||||
async openErrorDialog() {
|
|
||||||
const errorDelay = ms => new Promise(res => setTimeout(res, ms))
|
|
||||||
this.shadowRoot.querySelector('#errorDialog').show()
|
|
||||||
await errorDelay(3000)
|
|
||||||
this.shadowRoot.querySelector('#errorDialog').close()
|
|
||||||
}
|
|
||||||
|
|
||||||
checkForPmkDownload(wAddress, wPkm, wName, wShort) {
|
|
||||||
this.dWalletAddress = ''
|
|
||||||
this.dPrivateKey = ''
|
|
||||||
this.dCoinName = ''
|
|
||||||
this.dCoinShort = ''
|
|
||||||
this.dWalletAddress = wAddress
|
|
||||||
this.dPrivateKey = wPkm
|
|
||||||
this.dCoinName = wName
|
|
||||||
this.dCoinShort = wShort
|
|
||||||
this.shadowRoot.querySelector('#savePkmDialog').show()
|
|
||||||
}
|
|
||||||
|
|
||||||
async exportKey(cMasterKey, cName, cAddress) {
|
|
||||||
let exportname = ""
|
|
||||||
const myPrivateMasterKey = cMasterKey
|
|
||||||
const myCoinName = cName
|
|
||||||
const myCoinAddress = cAddress
|
|
||||||
const blob = new Blob([`${myPrivateMasterKey}`], { type: 'text/plain;charset=utf-8' })
|
|
||||||
exportname = "Private_Master_Key_" + myCoinName + "_" + myCoinAddress + ".txt"
|
|
||||||
await this.saveFileToDisk(blob, exportname)
|
|
||||||
}
|
|
||||||
|
|
||||||
async saveFileToDisk(blob, fileName) {
|
|
||||||
try {
|
|
||||||
const fileHandle = await self.showSaveFilePicker({
|
|
||||||
suggestedName: fileName,
|
|
||||||
types: [{
|
|
||||||
description: "File",
|
|
||||||
}]
|
|
||||||
})
|
|
||||||
const writeFile = async (fileHandle, contents) => {
|
|
||||||
const writable = await fileHandle.createWritable()
|
|
||||||
await writable.write(contents)
|
|
||||||
await writable.close()
|
|
||||||
}
|
|
||||||
writeFile(fileHandle, blob).then(() => console.log("FILE SAVED"))
|
|
||||||
let snack4string = get("general.save")
|
|
||||||
snackbar.add({
|
|
||||||
labelText: `${snack4string} ${fileName} ✅`,
|
|
||||||
dismiss: true
|
|
||||||
})
|
|
||||||
} catch (error) {
|
|
||||||
if (error.name === 'AbortError') {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
FileSaver.saveAs(blob, fileName)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getApiKey() {
|
|
||||||
const apiNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
|
||||||
return apiNode.apiKey
|
return apiNode.apiKey
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('export-keys', ExportKeys)
|
window.customElements.define('export-keys', ExportKeys)
|
@ -1,258 +1,160 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers'
|
import { connect } from 'pwa-helpers'
|
||||||
import {store} from '../../store.js'
|
import { store } from '../../store'
|
||||||
import {allowShowSyncIndicator, removeShowSyncIndicator} from '../../redux/app/app-actions.js'
|
import { allowShowSyncIndicator, removeShowSyncIndicator } from '../../redux/app/app-actions'
|
||||||
import {doSetQChatNotificationConfig} from '../../redux/user/user-actions.js'
|
import { doSetQChatNotificationConfig } from '../../redux/user/user-actions'
|
||||||
import {translate} from '../../../translate'
|
import { notificationsViewStyles } from '../../styles/core-css'
|
||||||
import isElectron from 'is-electron'
|
import isElectron from 'is-electron'
|
||||||
|
|
||||||
import '@material/mwc-checkbox'
|
import '@material/mwc-checkbox'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { translate } from '../../../translate'
|
||||||
|
|
||||||
class NotificationsView extends connect(store)(LitElement) {
|
class NotificationsView extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
notificationConfig: { type: Object },
|
notificationConfig: { type: Object },
|
||||||
q_chatConfig: { type: Object },
|
q_chatConfig: { type: Object },
|
||||||
theme: { type: String, reflect: true },
|
theme: { type: String, reflect: true },
|
||||||
appNotificationList: { type: Array }
|
appNotificationList: { type: Array }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
static get styles() {
|
||||||
super()
|
return [notificationsViewStyles]
|
||||||
this.notificationConfig = {}
|
}
|
||||||
this.q_chatConfig = {}
|
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
|
||||||
this.appNotificationList = [] // Fetch the list of apps from local storage
|
|
||||||
}
|
|
||||||
|
|
||||||
firstUpdated() {
|
constructor() {
|
||||||
this.appNotificationList = this.getAppsFromStorage()
|
super()
|
||||||
}
|
this.notificationConfig = {}
|
||||||
|
this.q_chatConfig = {}
|
||||||
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
|
this.appNotificationList = []
|
||||||
|
}
|
||||||
|
|
||||||
static get styles() {
|
firstUpdated() {
|
||||||
return css`
|
this.appNotificationList = this.getAppsFromStorage()
|
||||||
.sub-main {
|
}
|
||||||
position: relative;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.notification-box {
|
render() {
|
||||||
display: block;
|
return html`
|
||||||
position: relative;
|
<div class="sub-main">
|
||||||
top: 45%;
|
<div class="notification-box">
|
||||||
left: 50%;
|
<div class="content-box">
|
||||||
transform: translate(-50%, 0%);
|
<h4>Q-Chat ${translate("settings.notifications")}</h4>
|
||||||
text-align: center;
|
<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()}
|
||||||
|
>
|
||||||
|
${translate("settings.playsound")}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div style="line-height: 3rem;">
|
||||||
|
<mwc-checkbox id="qChatShowNotification" @click=${e => this.setQChatNotificationConfig({ type: 'SHOW_NOTIFICATION', value: e.target.checked })} ?checked=${this.q_chatConfig.showNotification}></mwc-checkbox>
|
||||||
|
<label
|
||||||
|
for="qChatShowNotification"
|
||||||
|
@click=${() => this.shadowRoot.getElementById('qChatShowNotification').click()}
|
||||||
|
>
|
||||||
|
${translate("settings.shownotifications")}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="content-box">
|
||||||
|
<h4>${translate("settings.qappNotification1")}</h4>
|
||||||
|
${this.appNotificationList.map((app) => html`
|
||||||
|
<div style="display: flex; justify-content: space-between; margin-top: 10px;">
|
||||||
|
${app}
|
||||||
|
<button class="remove-button" @click=${() => this.removeApp(app)}>Remove</button>
|
||||||
|
</div>
|
||||||
|
`)}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox-row">
|
||||||
|
<label for="syncIndicator" id="syncIndicatorLabel" style="color: var(--black);">
|
||||||
|
${translate("settings.sync_indicator")}
|
||||||
|
</label>
|
||||||
|
<mwc-checkbox style="margin-right: -15px;" id="syncIndicator" @click=${(e) => this.checkForSyncMessages(e)} ?checked=${store.getState().app.showSyncIndicator}></mwc-checkbox>
|
||||||
|
</div>
|
||||||
|
${this.renderSetCoreButton()}
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
@media(min-width: 1400px) {
|
getAppsFromStorage() {
|
||||||
.notification-box {
|
const address = store.getState().app.selectedAddress.address
|
||||||
display: grid;
|
const id = `appNotificationList-${address}`
|
||||||
grid-template-columns: 1fr 1fr;
|
const data = localStorage.getItem(id)
|
||||||
grid-gap: 30px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox-row {
|
return data ? Object.keys(JSON.parse(data)) : []
|
||||||
position: relative;
|
}
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
align-content: center;
|
|
||||||
font-family: Montserrat, sans-serif;
|
|
||||||
font-weight: 600;
|
|
||||||
color: var(--black);
|
|
||||||
}
|
|
||||||
|
|
||||||
.content-box {
|
removeApp(appName) {
|
||||||
border: 1px solid #a1a1a1;
|
// Remove the app from local storage
|
||||||
padding: 10px 25px;
|
this.removeAppFromStorage(appName)
|
||||||
text-align: left;
|
|
||||||
display: inline-block;
|
|
||||||
min-width: 350px;
|
|
||||||
min-height: 150px;
|
|
||||||
margin: 20px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
h4 {
|
// Update the apps list in the component
|
||||||
margin-bottom: 0;
|
this.appNotificationList = this.appNotificationList.filter(app => app !== appName)
|
||||||
}
|
}
|
||||||
|
|
||||||
mwc-checkbox::shadow .mdc-checkbox::after, mwc-checkbox::shadow .mdc-checkbox::before {
|
removeAppFromStorage(appName) {
|
||||||
background-color:var(--mdc-theme-primary)
|
// Your method to remove the app from local storage
|
||||||
}
|
const address = store.getState().app.selectedAddress.address
|
||||||
|
const id = `appNotificationList-${address}`
|
||||||
|
const data = JSON.parse(localStorage.getItem(id) || '{}')
|
||||||
|
|
||||||
label:hover {
|
delete data[appName]
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.title {
|
localStorage.setItem(id, JSON.stringify(data));
|
||||||
font-weight: 600;
|
}
|
||||||
font-size: 15px;
|
|
||||||
display: block;
|
|
||||||
line-height: 32px;
|
|
||||||
opacity: 0.66;
|
|
||||||
}
|
|
||||||
|
|
||||||
.value {
|
renderSetCoreButton() {
|
||||||
font-size: 16px;
|
if (!isElectron()) {
|
||||||
display: inline-block;
|
return html``
|
||||||
}
|
} else {
|
||||||
|
return html`
|
||||||
|
<div style="max-width: 500px; display: flex; justify-content: center; margin: auto;">
|
||||||
|
<div @click=${() => this.checkCoreSettings()} class="q-button">${translate("settings.core")}</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.q-button {
|
checkCoreSettings() {
|
||||||
display: inline-flex;
|
window.electronAPI.setStartCore()
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.remove-button {
|
checkForSyncMessages(e) {
|
||||||
font-family: Roboto, sans-serif;
|
if (e.target.checked) {
|
||||||
font-size: 16px;
|
store.dispatch(removeShowSyncIndicator(false))
|
||||||
color: var(--mdc-theme-primary);
|
} else {
|
||||||
background-color: transparent;
|
store.dispatch(allowShowSyncIndicator(true))
|
||||||
padding: 8px 10px;
|
}
|
||||||
border-radius: 5px;
|
}
|
||||||
border: none;
|
|
||||||
transition: all 0.3s ease-in-out;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
stateChanged(state) {
|
||||||
return html`
|
this.notificationConfig = state.user.notifications
|
||||||
<div class="sub-main">
|
this.q_chatConfig = this.notificationConfig.q_chat
|
||||||
<div class="notification-box">
|
}
|
||||||
<div class="content-box">
|
|
||||||
<h4> Q-Chat ${translate("settings.notifications")} </h4>
|
|
||||||
|
|
||||||
<div style="line-height: 3rem;">
|
setQChatNotificationConfig(valueObject) {
|
||||||
<mwc-checkbox id="qChatPlaySound" @click=${e => this.setQChatNotificationConfig({ type: 'PLAY_SOUND', value: e.target.checked })} ?checked=${this.q_chatConfig.playSound}></mwc-checkbox>
|
if (valueObject.type === 'PLAY_SOUND') {
|
||||||
<label
|
let data = {
|
||||||
for="qChatPlaySound"
|
playSound: !valueObject.value,
|
||||||
@click=${() => this.shadowRoot.getElementById('qChatPlaySound').click()}
|
showNotification: this.q_chatConfig.showNotification
|
||||||
>
|
}
|
||||||
${translate("settings.playsound")}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="line-height: 3rem;">
|
store.dispatch(doSetQChatNotificationConfig(data))
|
||||||
<mwc-checkbox id="qChatShowNotification" @click=${e => this.setQChatNotificationConfig({ type: 'SHOW_NOTIFICATION', value: e.target.checked })} ?checked=${this.q_chatConfig.showNotification}></mwc-checkbox>
|
} if (valueObject.type === 'SHOW_NOTIFICATION') {
|
||||||
<label
|
let data = {
|
||||||
for="qChatShowNotification"
|
playSound: this.q_chatConfig.playSound,
|
||||||
@click=${() => this.shadowRoot.getElementById('qChatShowNotification').click()}
|
showNotification: !valueObject.value
|
||||||
>
|
}
|
||||||
${translate("settings.shownotifications")}
|
|
||||||
</label>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="content-box">
|
|
||||||
<h4>${translate("settings.qappNotification1")}</h4>
|
|
||||||
${this.appNotificationList.map((app) => html`
|
|
||||||
<div style="display: flex; justify-content: space-between; margin-top: 10px;">
|
|
||||||
${app}
|
|
||||||
<button class="remove-button" @click=${() => this.removeApp(app)}>Remove</button>
|
|
||||||
</div>
|
|
||||||
`)}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<div class="checkbox-row">
|
|
||||||
<label for="syncIndicator" id="syncIndicatorLabel" style="color: var(--black);">
|
|
||||||
${translate("settings.sync_indicator")}
|
|
||||||
</label>
|
|
||||||
<mwc-checkbox style="margin-right: -15px;" id="syncIndicator" @click=${(e) => this.checkForSyncMessages(e)} ?checked=${store.getState().app.showSyncIndicator}></mwc-checkbox>
|
|
||||||
</div>
|
|
||||||
${this.renderSetCoreButton()}
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
getAppsFromStorage() {
|
store.dispatch(doSetQChatNotificationConfig(data))
|
||||||
// Your method to fetch the list of apps from local storage
|
}
|
||||||
// Example:
|
}
|
||||||
const address = store.getState().app.selectedAddress.address
|
|
||||||
const id = `appNotificationList-${address}`
|
|
||||||
const data = localStorage.getItem(id)
|
|
||||||
return data ? Object.keys(JSON.parse(data)) : []
|
|
||||||
}
|
|
||||||
|
|
||||||
removeApp(appName) {
|
|
||||||
// Remove the app from local storage
|
|
||||||
this.removeAppFromStorage(appName);
|
|
||||||
// Update the apps list in the component
|
|
||||||
this.appNotificationList = this.appNotificationList.filter(app => app !== appName);
|
|
||||||
}
|
|
||||||
|
|
||||||
removeAppFromStorage(appName) {
|
|
||||||
// Your method to remove the app from local storage
|
|
||||||
const address= store.getState().app.selectedAddress.address
|
|
||||||
const id = `appNotificationList-${address}`;
|
|
||||||
const data = JSON.parse(localStorage.getItem(id) || '{}');
|
|
||||||
delete data[appName];
|
|
||||||
localStorage.setItem(id, JSON.stringify(data));
|
|
||||||
}
|
|
||||||
|
|
||||||
renderSetCoreButton() {
|
|
||||||
if (!isElectron()) {
|
|
||||||
return html``
|
|
||||||
} else {
|
|
||||||
return html`
|
|
||||||
<div style="max-width: 500px; display: flex; justify-content: center; margin: auto;">
|
|
||||||
<div @click=${() => this.checkCoreSettings()} class="q-button"> ${translate("settings.core")} </div>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkCoreSettings() {
|
|
||||||
window.electronAPI.setStartCore()
|
|
||||||
}
|
|
||||||
|
|
||||||
checkForSyncMessages(e) {
|
|
||||||
if (e.target.checked) {
|
|
||||||
store.dispatch(removeShowSyncIndicator(false))
|
|
||||||
} else {
|
|
||||||
store.dispatch(allowShowSyncIndicator(true))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
stateChanged(state) {
|
|
||||||
this.notificationConfig = state.user.notifications
|
|
||||||
this.q_chatConfig = this.notificationConfig.q_chat
|
|
||||||
}
|
|
||||||
|
|
||||||
setQChatNotificationConfig(valueObject) {
|
|
||||||
if (valueObject.type === 'PLAY_SOUND') {
|
|
||||||
let data = {
|
|
||||||
playSound: !valueObject.value,
|
|
||||||
showNotification: this.q_chatConfig.showNotification
|
|
||||||
}
|
|
||||||
store.dispatch(doSetQChatNotificationConfig(data))
|
|
||||||
} if (valueObject.type === 'SHOW_NOTIFICATION') {
|
|
||||||
|
|
||||||
let data = {
|
|
||||||
playSound: this.q_chatConfig.playSound,
|
|
||||||
showNotification: !valueObject.value
|
|
||||||
}
|
|
||||||
store.dispatch(doSetQChatNotificationConfig(data))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('notifications-view', NotificationsView)
|
window.customElements.define('notifications-view', NotificationsView)
|
@ -1,140 +1,91 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers'
|
import { connect } from 'pwa-helpers'
|
||||||
import {store} from '../../store.js'
|
import { store } from '../../store'
|
||||||
import {translate} from '../../../translate'
|
import { qrLoginViewStyles } from '../../styles/core-css'
|
||||||
|
import '../../../../plugins/plugins/core/components/QortalQrcodeGenerator'
|
||||||
import '@material/mwc-textfield'
|
|
||||||
import '@material/mwc-icon'
|
import '@material/mwc-icon'
|
||||||
|
import '@material/mwc-textfield'
|
||||||
import '@vaadin/password-field/vaadin-password-field.js'
|
import '@vaadin/password-field/vaadin-password-field.js'
|
||||||
import '../../../../plugins/plugins/core/components/QortalQrcodeGenerator.js'
|
|
||||||
|
// Multi language support
|
||||||
|
import { translate } from '../../../translate'
|
||||||
|
|
||||||
class QRLoginView extends connect(store)(LitElement) {
|
class QRLoginView extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
theme: { type: String, reflect: true },
|
theme: { type: String, reflect: true },
|
||||||
savedWalletDataJson: { type: String },
|
savedWalletDataJson: { type: String },
|
||||||
translateDescriptionKey: { type: String }, // Description text
|
translateDescriptionKey: { type: String },
|
||||||
translateButtonKey: { type: String }, // Button text
|
translateButtonKey: { type: String }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return css`
|
return [qrLoginViewStyles]
|
||||||
* {
|
}
|
||||||
--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 {
|
constructor() {
|
||||||
position: relative;
|
super()
|
||||||
top: 45%;
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
left: 50%;
|
this.translateDescriptionKey = 'settings.qr_login_description_' + (this.isWalletStored() ? '1' : '2')
|
||||||
transform: translate(-50%, 0%);
|
this.translateButtonKey = 'settings.qr_login_button_' + (this.isWalletStored() ? '1' : '2')
|
||||||
text-align: center;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.q-button {
|
render() {
|
||||||
display: inline-flex;
|
return html`
|
||||||
flex-direction: column;
|
<div style="position: relative;" >
|
||||||
justify-content: center;
|
<div class="center-box">
|
||||||
align-content: center;
|
<p>
|
||||||
border: none;
|
${translate(this.translateDescriptionKey)}
|
||||||
border-radius: 20px;
|
</p>
|
||||||
padding-left: 25px;
|
<div style="max-width: 500px; justify-content: center; margin: auto; display: ${this.isWalletStored() ? 'none' : 'flex'}">
|
||||||
padding-right: 25px;
|
<mwc-icon style="padding: 10px; padding-left:0; padding-top: 42px;">password</mwc-icon>
|
||||||
color: white;
|
<vaadin-password-field id="newWalletPassword" style="width: 100%; color: var(--black);" label="${translate("settings.password")}" autofocus></vaadin-password-field>
|
||||||
background: #03a9f4;
|
</div>
|
||||||
width: 50%;
|
<div style="max-width: 600px; display: flex; justify-content: center; margin: auto;">
|
||||||
font-size: 17px;
|
<div id="qr-toggle-button" @click=${() => this.showQRCode()} class="q-button outlined"> ${translate(this.translateButtonKey)} </div>
|
||||||
cursor: pointer;
|
</div>
|
||||||
height: 50px;
|
<div id="login-qr-code" style="display: none;">
|
||||||
margin-top: 1rem;
|
<qortal-qrcode-generator id="login-qr-code" data="${this.savedWalletDataJson}" mode="octet" format="html" auto></qortal-qrcode-generator>
|
||||||
text-transform: uppercase;
|
</div>
|
||||||
text-decoration: none;
|
</div>
|
||||||
transition: all .2s;
|
</div>
|
||||||
position: relative;
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
.q-button.outlined {
|
isWalletStored() {
|
||||||
background: unset;
|
const state = store.getState()
|
||||||
border: 1px solid #03a9f4;
|
const address0 = state.app.wallet._addresses[0].address
|
||||||
}
|
const savedWalletData = state.user.storedWallets && state.user.storedWallets[address0]
|
||||||
|
|
||||||
:host([theme="light"]) .q-button.outlined {
|
return !!savedWalletData
|
||||||
color: #03a9f4;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
#qr-toggle-button {
|
async setSavedWalletDataJson() {
|
||||||
margin-left: 12px;
|
const state = store.getState()
|
||||||
}
|
|
||||||
|
|
||||||
#login-qr-code {
|
let data
|
||||||
margin: auto;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
if (this.isWalletStored()) {
|
||||||
super()
|
const address0 = state.app.wallet._addresses[0].address
|
||||||
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() {
|
data = state.user.storedWallets[address0]
|
||||||
return html`
|
} else {
|
||||||
<div style="position: relative;" >
|
const password = this.shadowRoot.getElementById('newWalletPassword').value
|
||||||
<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;">
|
data = await state.app.wallet.generateSaveWalletData(password, state.config.crypto.kdfThreads, () => { })
|
||||||
<qortal-qrcode-generator id="login-qr-code" data="${this.savedWalletDataJson}" mode="octet" format="html" auto></qortal-qrcode-generator>
|
}
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
isWalletStored() {
|
this.savedWalletDataJson = JSON.stringify(data)
|
||||||
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() {
|
async showQRCode() {
|
||||||
const state = store.getState()
|
await this.setSavedWalletDataJson()
|
||||||
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() {
|
let el = this.shadowRoot.getElementById('login-qr-code')
|
||||||
await this.setSavedWalletDataJson()
|
|
||||||
let el = this.shadowRoot.getElementById('login-qr-code')
|
el.style.display = 'flex'
|
||||||
el.style.display = 'flex'
|
}
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('qr-login-view', QRLoginView)
|
window.customElements.define('qr-login-view', QRLoginView)
|
@ -1,6 +1,6 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers'
|
import { connect } from 'pwa-helpers'
|
||||||
import {store} from '../../store.js'
|
import { store } from '../../store'
|
||||||
import {
|
import {
|
||||||
allowQAPPAutoAuth,
|
allowQAPPAutoAuth,
|
||||||
allowQAPPAutoFriendsList,
|
allowQAPPAutoFriendsList,
|
||||||
@ -9,262 +9,194 @@ import {
|
|||||||
removeQAPPAutoFriendsList,
|
removeQAPPAutoFriendsList,
|
||||||
removeQAPPAutoLists,
|
removeQAPPAutoLists,
|
||||||
setIsOpenDevDialog
|
setIsOpenDevDialog
|
||||||
} from '../../redux/app/app-actions.js'
|
} from '../../redux/app/app-actions'
|
||||||
import {get, translate} from '../../../translate'
|
import { securityViewStyles } from '../../styles/core-css'
|
||||||
import snackbar from '../../functional-components/snackbar.js'
|
|
||||||
import FileSaver from 'file-saver'
|
import FileSaver from 'file-saver'
|
||||||
|
import snackbar from '../../functional-components/snackbar'
|
||||||
import '@material/mwc-checkbox'
|
import '@material/mwc-checkbox'
|
||||||
import '@material/mwc-textfield'
|
|
||||||
import '@material/mwc-icon'
|
import '@material/mwc-icon'
|
||||||
|
import '@material/mwc-textfield'
|
||||||
import '@vaadin/password-field/vaadin-password-field.js'
|
import '@vaadin/password-field/vaadin-password-field.js'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { get, translate } from '../../../translate'
|
||||||
|
|
||||||
class SecurityView extends connect(store)(LitElement) {
|
class SecurityView extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
theme: { type: String, reflect: true },
|
theme: { type: String, reflect: true },
|
||||||
backupErrorMessage: { type: String },
|
backupErrorMessage: { type: String },
|
||||||
closeSettings: {attribute: false}
|
closeSettings: { attribute: false }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return css`
|
return [securityViewStyles]
|
||||||
* {
|
}
|
||||||
--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);
|
|
||||||
--mdc-checkbox-unchecked-color: var(--black);
|
|
||||||
--mdc-theme-on-surface: var(--black);
|
|
||||||
--mdc-checkbox-disabled-color: var(--black);
|
|
||||||
--mdc-checkbox-ink-color: var(--black);
|
|
||||||
}
|
|
||||||
|
|
||||||
.center-box {
|
constructor() {
|
||||||
position: relative;
|
super()
|
||||||
top: 45%;
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
left: 50%;
|
this.backupErrorMessage = ''
|
||||||
transform: translate(-50%, 0%);
|
}
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.checkbox-row {
|
render() {
|
||||||
position: relative;
|
return html`
|
||||||
display: flex;
|
<div style="position: relative;" >
|
||||||
align-items: center;
|
<div class="center-box">
|
||||||
align-content: center;
|
<p>
|
||||||
font-family: Montserrat, sans-serif;
|
${translate("settings.choose")}
|
||||||
font-weight: 600;
|
</p>
|
||||||
color: var(--black);
|
<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="${translate("settings.password")}"
|
||||||
|
id="downloadBackupPassword"
|
||||||
|
helper-text="${translate("login.passwordhint")}"
|
||||||
|
autofocus
|
||||||
|
></vaadin-password-field>
|
||||||
|
</div>
|
||||||
|
<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="${translate("login.confirmpass")}"
|
||||||
|
id="rePassword"
|
||||||
|
></vaadin-password-field>
|
||||||
|
</div>
|
||||||
|
<div style="text-align: center; color: var(--mdc-theme-error); text-transform: uppercase; font-size: 15px;">
|
||||||
|
${this.backupErrorMessage}
|
||||||
|
</div>
|
||||||
|
<div style="max-width: 500px; display: flex; justify-content: center; margin: auto;">
|
||||||
|
<div @click=${() => this.checkForDownload()} class="q-button"> ${translate("settings.download")} </div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<hr style="margin-top: 20px;">
|
||||||
|
<div class="checkbox-row">
|
||||||
|
<label for="authButton" id="authButtonLabel" style="color: var(--black);">
|
||||||
|
${get('browserpage.bchange26')}
|
||||||
|
</label>
|
||||||
|
<mwc-checkbox style="margin-right: -15px;" id="authButton" @click=${(e) => this.checkForAuth(e)} ?checked=${store.getState().app.qAPPAutoAuth}></mwc-checkbox>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox-row">
|
||||||
|
<label for="authButton" id="authButtonLabel" style="color: var(--black);">
|
||||||
|
${get('browserpage.bchange39')}
|
||||||
|
</label>
|
||||||
|
<mwc-checkbox style="margin-right: -15px;" id="authButton" @click=${(e) => this.checkForLists(e)} ?checked=${store.getState().app.qAPPAutoLists}></mwc-checkbox>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox-row">
|
||||||
|
<label for="authButton" id="authButtonLabel" style="color: var(--black);">
|
||||||
|
${get('browserpage.bchange53')}
|
||||||
|
</label>
|
||||||
|
<mwc-checkbox style="margin-right: -15px;" id="authButton" @click=${(e) => this.checkForFriends(e)} ?checked=${store.getState().app.qAPPFriendsList}></mwc-checkbox>
|
||||||
|
</div>
|
||||||
|
<div class="checkbox-row">
|
||||||
|
<button class="add-dev-button" title="${translate('tabmenu.tm18')}" @click=${this.openDevDialog}>
|
||||||
|
${translate('tabmenu.tm38')}
|
||||||
|
</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
.q-button {
|
checkForAuth(e) {
|
||||||
display: inline-flex;
|
if (e.target.checked) {
|
||||||
flex-direction: column;
|
store.dispatch(removeQAPPAutoAuth(false))
|
||||||
justify-content: center;
|
} else {
|
||||||
align-content: center;
|
store.dispatch(allowQAPPAutoAuth(true))
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-dev-button {
|
checkForLists(e) {
|
||||||
margin-top: 4px;
|
if (e.target.checked) {
|
||||||
max-height: 28px;
|
store.dispatch(removeQAPPAutoLists(false))
|
||||||
padding: 5px 5px;
|
} else {
|
||||||
font-size: 14px;
|
store.dispatch(allowQAPPAutoLists(true))
|
||||||
background-color: #03a9f4;
|
}
|
||||||
color: white;
|
}
|
||||||
border: 1px solid transparent;
|
|
||||||
border-radius: 3px;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
.add-dev-button:hover {
|
checkForFriends(e) {
|
||||||
opacity: 0.8;
|
if (e.target.checked) {
|
||||||
cursor: pointer;
|
store.dispatch(removeQAPPAutoFriendsList(false))
|
||||||
}
|
} else {
|
||||||
`
|
store.dispatch(allowQAPPAutoFriendsList(true))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
checkForDownload() {
|
||||||
super()
|
const checkPass = this.shadowRoot.getElementById('downloadBackupPassword').value
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
const rePass = this.shadowRoot.getElementById('rePassword').value
|
||||||
this.backupErrorMessage = ''
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
if (checkPass === '') {
|
||||||
return html`
|
this.backupErrorMessage = get("login.pleaseenter")
|
||||||
<div style="position: relative;" >
|
} else if (checkPass.length < 5) {
|
||||||
<div class="center-box">
|
this.backupErrorMessage = get("login.lessthen8-2")
|
||||||
<p>
|
} else if (checkPass != rePass) {
|
||||||
${translate("settings.choose")}
|
this.backupErrorMessage = get("login.notmatch")
|
||||||
</p>
|
} else {
|
||||||
<div style="max-width: 500px; display: flex; justify-content: center; margin: auto;">
|
this.downloadBackup()
|
||||||
<mwc-icon style="padding: 10px; padding-left:0; padding-top: 42px;">password</mwc-icon>
|
}
|
||||||
<vaadin-password-field
|
}
|
||||||
style="width: 100%; color: var(--black);"
|
|
||||||
label="${translate("settings.password")}"
|
|
||||||
id="downloadBackupPassword"
|
|
||||||
helper-text="${translate("login.passwordhint")}"
|
|
||||||
autofocus
|
|
||||||
>
|
|
||||||
</vaadin-password-field>
|
|
||||||
</div>
|
|
||||||
<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="${translate("login.confirmpass")}"
|
|
||||||
id="rePassword"
|
|
||||||
>
|
|
||||||
</vaadin-password-field>
|
|
||||||
</div>
|
|
||||||
<div style="text-align: center; color: var(--mdc-theme-error); text-transform: uppercase; font-size: 15px;">
|
|
||||||
${this.backupErrorMessage}
|
|
||||||
</div>
|
|
||||||
<div style="max-width: 500px; display: flex; justify-content: center; margin: auto;">
|
|
||||||
<div @click=${() => this.checkForDownload()} class="q-button"> ${translate("settings.download")} </div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<hr style="margin-top: 20px;">
|
|
||||||
<div class="checkbox-row">
|
|
||||||
<label for="authButton" id="authButtonLabel" style="color: var(--black);">
|
|
||||||
${get('browserpage.bchange26')}
|
|
||||||
</label>
|
|
||||||
<mwc-checkbox style="margin-right: -15px;" id="authButton" @click=${(e) => this.checkForAuth(e)} ?checked=${store.getState().app.qAPPAutoAuth}></mwc-checkbox>
|
|
||||||
</div>
|
|
||||||
<div class="checkbox-row">
|
|
||||||
<label for="authButton" id="authButtonLabel" style="color: var(--black);">
|
|
||||||
${get('browserpage.bchange39')}
|
|
||||||
</label>
|
|
||||||
<mwc-checkbox style="margin-right: -15px;" id="authButton" @click=${(e) => this.checkForLists(e)} ?checked=${store.getState().app.qAPPAutoLists}></mwc-checkbox>
|
|
||||||
</div>
|
|
||||||
<div class="checkbox-row">
|
|
||||||
<label for="authButton" id="authButtonLabel" style="color: var(--black);">
|
|
||||||
${get('browserpage.bchange53')}
|
|
||||||
</label>
|
|
||||||
<mwc-checkbox style="margin-right: -15px;" id="authButton" @click=${(e) => this.checkForFriends(e)} ?checked=${store.getState().app.qAPPFriendsList}></mwc-checkbox>
|
|
||||||
</div>
|
|
||||||
<div class="checkbox-row">
|
|
||||||
<button
|
|
||||||
class="add-dev-button"
|
|
||||||
title="${translate('tabmenu.tm18')}"
|
|
||||||
@click=${this.openDevDialog}
|
|
||||||
>
|
|
||||||
${translate('tabmenu.tm38')}
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
stateChanged(state) {
|
openDevDialog() {
|
||||||
}
|
this.closeSettings()
|
||||||
|
store.dispatch(setIsOpenDevDialog(true))
|
||||||
|
}
|
||||||
|
|
||||||
checkForAuth(e) {
|
async downloadBackup() {
|
||||||
if (e.target.checked) {
|
let backupname = ''
|
||||||
store.dispatch(removeQAPPAutoAuth(false))
|
|
||||||
} else {
|
|
||||||
store.dispatch(allowQAPPAutoAuth(true))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkForLists(e) {
|
this.backupErrorMessage = ''
|
||||||
if (e.target.checked) {
|
|
||||||
store.dispatch(removeQAPPAutoLists(false))
|
|
||||||
} else {
|
|
||||||
store.dispatch(allowQAPPAutoLists(true))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkForFriends(e) {
|
const state = store.getState()
|
||||||
if (e.target.checked) {
|
const password = this.shadowRoot.getElementById('downloadBackupPassword').value
|
||||||
store.dispatch(removeQAPPAutoFriendsList(false))
|
const data = await state.app.wallet.generateSaveWalletData(password, state.config.crypto.kdfThreads, () => { })
|
||||||
} else {
|
const dataString = JSON.stringify(data)
|
||||||
store.dispatch(allowQAPPAutoFriendsList(true))
|
const blob = new Blob([dataString], { type: 'text/plain;charset=utf-8' })
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
checkForDownload() {
|
backupname = 'qortal_backup_' + state.app.selectedAddress.address + '.json'
|
||||||
const checkPass = this.shadowRoot.getElementById('downloadBackupPassword').value
|
|
||||||
const rePass = this.shadowRoot.getElementById('rePassword').value
|
|
||||||
|
|
||||||
if (checkPass === '') {
|
await this.saveFileToDisk(blob, backupname)
|
||||||
this.backupErrorMessage = get("login.pleaseenter")
|
}
|
||||||
} else if (checkPass.length < 5) {
|
|
||||||
this.backupErrorMessage = get("login.lessthen8-2")
|
|
||||||
} else if (checkPass != rePass) {
|
|
||||||
this.backupErrorMessage = get("login.notmatch")
|
|
||||||
} else {
|
|
||||||
this.downloadBackup()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
openDevDialog() {
|
async saveFileToDisk(blob, fileName) {
|
||||||
this.closeSettings()
|
try {
|
||||||
store.dispatch(setIsOpenDevDialog(true))
|
const fileHandle = await self.showSaveFilePicker({
|
||||||
}
|
suggestedName: fileName,
|
||||||
|
types: [{
|
||||||
|
description: "File"
|
||||||
|
}]
|
||||||
|
})
|
||||||
|
|
||||||
async downloadBackup() {
|
const writeFile = async (fileHandle, contents) => {
|
||||||
let backupname = ''
|
const writable = await fileHandle.createWritable()
|
||||||
this.backupErrorMessage = ''
|
|
||||||
const state = store.getState()
|
|
||||||
const password = this.shadowRoot.getElementById('downloadBackupPassword').value
|
|
||||||
const data = await state.app.wallet.generateSaveWalletData(password, state.config.crypto.kdfThreads, () => { })
|
|
||||||
const dataString = JSON.stringify(data)
|
|
||||||
const blob = new Blob([dataString], { type: 'text/plain;charset=utf-8' })
|
|
||||||
backupname = "qortal_backup_" + state.app.selectedAddress.address + ".json"
|
|
||||||
await this.saveFileToDisk(blob, backupname)
|
|
||||||
}
|
|
||||||
|
|
||||||
async saveFileToDisk(blob, fileName) {
|
await writable.write(contents)
|
||||||
try {
|
await writable.close()
|
||||||
const fileHandle = await self.showSaveFilePicker({
|
}
|
||||||
suggestedName: fileName,
|
|
||||||
types: [{
|
writeFile(fileHandle, blob).then(() => console.log("FILE SAVED"))
|
||||||
description: "File",
|
|
||||||
}]
|
let snack4string = get("general.save")
|
||||||
})
|
|
||||||
const writeFile = async (fileHandle, contents) => {
|
snackbar.add({
|
||||||
const writable = await fileHandle.createWritable()
|
labelText: `${snack4string} ${fileName} ✅`,
|
||||||
await writable.write(contents)
|
dismiss: true
|
||||||
await writable.close()
|
})
|
||||||
}
|
|
||||||
writeFile(fileHandle, blob).then(() => console.log("FILE SAVED"))
|
this.shadowRoot.getElementById('downloadBackupPassword').value = ''
|
||||||
let snack4string = get("general.save")
|
this.shadowRoot.getElementById('rePassword').value = ''
|
||||||
snackbar.add({
|
} catch (error) {
|
||||||
labelText: `${snack4string} ${fileName} ✅`,
|
if (error.name === 'AbortError') {
|
||||||
dismiss: true
|
return
|
||||||
})
|
}
|
||||||
this.shadowRoot.getElementById('downloadBackupPassword').value = ''
|
|
||||||
this.shadowRoot.getElementById('rePassword').value = ''
|
FileSaver.saveAs(blob, fileName)
|
||||||
} catch (error) {
|
this.shadowRoot.getElementById('downloadBackupPassword').value = ''
|
||||||
if (error.name === 'AbortError') {
|
this.shadowRoot.getElementById('rePassword').value = ''
|
||||||
return
|
}
|
||||||
}
|
}
|
||||||
FileSaver.saveAs(blob, fileName)
|
|
||||||
this.shadowRoot.getElementById('downloadBackupPassword').value = ''
|
|
||||||
this.shadowRoot.getElementById('rePassword').value = ''
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('security-view', SecurityView)
|
window.customElements.define('security-view', SecurityView)
|
@ -1,309 +1,128 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers'
|
import { connect } from 'pwa-helpers'
|
||||||
import {store} from '../../store.js'
|
import { store } from '../../store'
|
||||||
import {translate} from '../../../translate'
|
import { userSettingsStyles } from '../../styles/core-css'
|
||||||
|
import './account-view'
|
||||||
import '@polymer/paper-dialog/paper-dialog.js'
|
import './export-keys'
|
||||||
|
import './notifications-view'
|
||||||
|
import './qr-login-view'
|
||||||
|
import './security-view'
|
||||||
import '@material/mwc-button'
|
import '@material/mwc-button'
|
||||||
|
import '@polymer/paper-dialog/paper-dialog.js'
|
||||||
|
|
||||||
import './account-view.js'
|
// Multi language support
|
||||||
import './security-view.js'
|
import { translate } from '../../../translate'
|
||||||
import './notifications-view.js'
|
|
||||||
import './qr-login-view.js'
|
|
||||||
import './export-keys.js'
|
|
||||||
|
|
||||||
class UserSettings extends connect(store)(LitElement) {
|
class UserSettings extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
loggedIn: { type: Boolean },
|
loggedIn: { type: Boolean },
|
||||||
pages: { type: Array },
|
pages: { type: Array },
|
||||||
selectedView: { type: Object },
|
selectedView: { type: Object },
|
||||||
theme: { type: String, reflect: true }
|
theme: { type: String, reflect: true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return css`
|
return [userSettingsStyles]
|
||||||
:host {
|
}
|
||||||
margin: 0;
|
|
||||||
width: 100%;
|
|
||||||
max-width: 100vw;
|
|
||||||
height: 100%;
|
|
||||||
max-height: 100vh;
|
|
||||||
background-color: var(--white);
|
|
||||||
color: var(--black);
|
|
||||||
line-height: 1.6;
|
|
||||||
}
|
|
||||||
|
|
||||||
.decline {
|
constructor() {
|
||||||
--mdc-theme-primary: var(--mdc-theme-error)
|
super()
|
||||||
}
|
this.selectedView = { id: 'info', name: 'General Account Info' }
|
||||||
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
|
}
|
||||||
|
|
||||||
paper-dialog.userSettings {
|
render() {
|
||||||
width: 100%;
|
return html`
|
||||||
max-width: 100vw;
|
<paper-dialog id="userSettingsDialog" class="userSettings" modal>
|
||||||
height: 100%;
|
<div class="actions">
|
||||||
max-height: 100vh;
|
<h2></h2>
|
||||||
background-color: var(--white);
|
<mwc-icon class="close-icon" @click=${() => this.closeSettings()} title="Close Settings" >highlight_off</mwc-icon>
|
||||||
color: var(--black);
|
</div>
|
||||||
line-height: 1.6;
|
<div class="container">
|
||||||
overflow-y: auto;
|
<div class="wrapper">
|
||||||
}
|
<div class="leftBar" style="display: table; width: 100%;">
|
||||||
|
<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)">${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('export')} ><a class=${this.selectedView.id === 'export' ? 'active' : ''} href="javascript:void(0)">${translate("settings.exp1")}</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>
|
||||||
|
<div class="mainPage">
|
||||||
|
<h1>${this.renderHeaderViews()}</h1>
|
||||||
|
<hr>
|
||||||
|
${html`${this.renderSettingViews(this.selectedView)}`}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</paper-dialog>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
.actions {
|
stateChanged(state) {
|
||||||
display:flex;
|
this.loggedIn = state.app.loggedIn
|
||||||
justify-content: space-between;
|
}
|
||||||
padding: 0 4em;
|
|
||||||
margin: 15px 0 -2px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.close-icon {
|
renderSettingViews(selectedView) {
|
||||||
font-size: 36px;
|
if (selectedView.id === 'info') {
|
||||||
}
|
return html`<account-view></account-view>`
|
||||||
|
} else if (selectedView.id === 'security') {
|
||||||
|
return html`<security-view .closeSettings=${() => this.closeSettings()}></security-view>`
|
||||||
|
} else if (selectedView.id === 'export') {
|
||||||
|
return html`<export-keys></export-keys>`
|
||||||
|
} 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>`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.close-icon:hover {
|
renderHeaderViews() {
|
||||||
cursor: pointer;
|
if (this.selectedView.id === 'info') {
|
||||||
opacity: .6;
|
return html`${translate("settings.generalinfo")}`
|
||||||
}
|
} else if (this.selectedView.id === 'security') {
|
||||||
|
return html`${translate("settings.accountsecurity")}`
|
||||||
|
} else if (this.selectedView.id === 'export') {
|
||||||
|
return html`${translate("settings.exp1")}`
|
||||||
|
} 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")}`
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.buttons {
|
setSettingsView(pageId) {
|
||||||
text-align:right;
|
if (pageId === 'info') {
|
||||||
}
|
return this.selectedView = { id: 'info', name: 'General Account Info' }
|
||||||
|
} else if (pageId === 'security') {
|
||||||
|
return this.selectedView = { id: 'security', name: 'Account Security' }
|
||||||
|
} else if (pageId === 'export') {
|
||||||
|
return this.selectedView = { id: 'export', name: 'Export Master Keys' }
|
||||||
|
} 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' }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.container {
|
openSettings() {
|
||||||
max-width: 90vw;
|
if (this.loggedIn) {
|
||||||
margin-left: auto;
|
this.shadowRoot.getElementById('userSettingsDialog').open()
|
||||||
margin-right: auto;
|
}
|
||||||
margin-top: 20px;
|
}
|
||||||
padding: .6em;
|
|
||||||
}
|
|
||||||
|
|
||||||
ul {
|
closeSettings() {
|
||||||
list-style: none;
|
this.shadowRoot.getElementById('userSettingsDialog').close()
|
||||||
padding: 0;
|
this.cleanUp()
|
||||||
margin-bottom: 0;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
.leftBar {
|
cleanUp() {
|
||||||
background-color: var(--white);
|
this.selectedView = { id: 'info', name: 'General Account Info' }
|
||||||
color: var(--black);
|
}
|
||||||
border: 1px solid var(--border);
|
|
||||||
padding: 20px 0 0 0;
|
|
||||||
border-radius: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftBar img {
|
|
||||||
margin: 0 auto;
|
|
||||||
width: 75%;
|
|
||||||
height: 75%;
|
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftBar .slug {
|
|
||||||
text-align: center;
|
|
||||||
margin-top: 20px;
|
|
||||||
color: var(--black);
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 600;
|
|
||||||
margin-bottom: 7px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftBar ul li {
|
|
||||||
border-bottom: 1px solid var(--border);
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftBar ul li:last-child {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftBar ul li a {
|
|
||||||
color: var(--black);
|
|
||||||
font-size: 16px;
|
|
||||||
font-weight: 400;
|
|
||||||
text-decoration: none;
|
|
||||||
padding: .9em;
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftBar ul li a i {
|
|
||||||
margin-right: 8px;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftBar ul li a:hover {
|
|
||||||
background-color: var(--menuhover);
|
|
||||||
color: #515151;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftBar ul li:active {
|
|
||||||
border-bottom: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftBar ul li a.active {
|
|
||||||
color: #515151;
|
|
||||||
background-color: var(--menuactive);
|
|
||||||
border-left: 2px solid #515151;
|
|
||||||
margin-left: -2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainPage {
|
|
||||||
background-color: var(--white);
|
|
||||||
color: var(--black);
|
|
||||||
border: 1px solid var(--border);
|
|
||||||
padding: 20px 0 10px 0;
|
|
||||||
border-radius: 5px;
|
|
||||||
font-size: 16px;
|
|
||||||
text-align: center;
|
|
||||||
min-height: 460px;
|
|
||||||
height: auto;
|
|
||||||
overflow: auto;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(max-width:700px) {
|
|
||||||
.mainPage {
|
|
||||||
margin-top: 30px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@media(min-width:765px) {
|
|
||||||
* {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
box-sizing: border-box;
|
|
||||||
}
|
|
||||||
|
|
||||||
.actions {
|
|
||||||
display:flex;
|
|
||||||
justify-content: space-between;
|
|
||||||
padding: 0 4em;
|
|
||||||
margin: 15px 0 -25px 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.container {
|
|
||||||
padding: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wrapper {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr 3fr;
|
|
||||||
grid-gap: 30px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.wrapper > .mainPage {
|
|
||||||
padding: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.leftBar {
|
|
||||||
text-align: left;
|
|
||||||
max-height: 403px;
|
|
||||||
max-width: 400px;
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mainPage {
|
|
||||||
font-size: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
this.selectedView = { id: 'info', name: 'General Account Info' }
|
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return html`
|
|
||||||
<paper-dialog id="userSettingsDialog" class="userSettings" modal>
|
|
||||||
<div class="actions">
|
|
||||||
<h2></h2>
|
|
||||||
<mwc-icon class="close-icon" @click=${ () => this.closeSettings()} title="Close Settings" >highlight_off</mwc-icon>
|
|
||||||
</div>
|
|
||||||
<div class="container">
|
|
||||||
<div class="wrapper">
|
|
||||||
<div class="leftBar" style="display: table; width: 100%;">
|
|
||||||
<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)">${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('export')} ><a class=${this.selectedView.id === 'export' ? 'active' : ''} href="javascript:void(0)">${translate("settings.exp1") }</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>
|
|
||||||
<div class="mainPage">
|
|
||||||
<h1>${this.renderHeaderViews()}</h1>
|
|
||||||
<hr>
|
|
||||||
${html`${this.renderSettingViews(this.selectedView)}`}
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</paper-dialog>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
stateChanged(state) {
|
|
||||||
this.loggedIn = state.app.loggedIn
|
|
||||||
}
|
|
||||||
|
|
||||||
renderSettingViews(selectedView) {
|
|
||||||
if (selectedView.id === 'info') {
|
|
||||||
return html`<account-view></account-view>`
|
|
||||||
} else if (selectedView.id === 'security') {
|
|
||||||
return html`<security-view .closeSettings=${()=> this.closeSettings()}></security-view>`
|
|
||||||
} else if (selectedView.id === 'export') {
|
|
||||||
return html`<export-keys></export-keys>`
|
|
||||||
} 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>`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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 === 'export') {
|
|
||||||
return html`${translate("settings.exp1")}`
|
|
||||||
} 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")}`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
setSettingsView(pageId) {
|
|
||||||
if (pageId === 'info') {
|
|
||||||
return this.selectedView = { id: 'info', name: 'General Account Info' }
|
|
||||||
} else if (pageId === 'security') {
|
|
||||||
return this.selectedView = { id: 'security', name: 'Account Security' }
|
|
||||||
} else if (pageId === 'export') {
|
|
||||||
return this.selectedView = { id: 'export', name: 'Export Master Keys' }
|
|
||||||
} 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' }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
openSettings() {
|
|
||||||
if (this.loggedIn) {
|
|
||||||
this.shadowRoot.getElementById('userSettingsDialog').open()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
closeSettings() {
|
|
||||||
this.shadowRoot.getElementById('userSettingsDialog').close()
|
|
||||||
this.cleanUp()
|
|
||||||
}
|
|
||||||
|
|
||||||
cleanUp() {
|
|
||||||
this.selectedView = { id: 'info', name: 'General Account Info' }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('user-settings', UserSettings)
|
window.customElements.define('user-settings', UserSettings)
|
File diff suppressed because it is too large
Load Diff
@ -1,19 +1,20 @@
|
|||||||
import {css, html, LitElement} from 'lit';
|
import { html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers';
|
import { asyncReplace } from 'lit/directives/async-replace.js'
|
||||||
import {store} from '../store.js';
|
import { connect } from 'pwa-helpers'
|
||||||
import {get, translate} from '../../translate'
|
import { store } from '../store.js'
|
||||||
import {asyncReplace} from 'lit/directives/async-replace.js';
|
import { routes } from '../plugins/routes'
|
||||||
|
import { startMintingStyles } from '../styles/core-css'
|
||||||
import '../functional-components/my-button.js';
|
import '../functional-components/my-button'
|
||||||
import {routes} from '../plugins/routes.js';
|
|
||||||
import "@material/mwc-button"
|
import "@material/mwc-button"
|
||||||
import '@material/mwc-dialog'
|
import '@material/mwc-dialog'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { get, translate } from '../../translate'
|
||||||
|
|
||||||
async function* countDown(count, callback) {
|
async function* countDown(count, callback) {
|
||||||
while (count > 0) {
|
while (count > 0) {
|
||||||
yield count--;
|
yield count--
|
||||||
await new Promise((r) => setTimeout(r, 1000));
|
await new Promise((r) => setTimeout(r, 1000))
|
||||||
if (count === 0) {
|
if (count === 0) {
|
||||||
callback()
|
callback()
|
||||||
}
|
}
|
||||||
@ -30,187 +31,56 @@ class StartMinting extends connect(store)(LitElement) {
|
|||||||
status: { type: Number },
|
status: { type: Number },
|
||||||
timer: { type: Number },
|
timer: { type: Number },
|
||||||
privateRewardShareKey: { type: String }
|
privateRewardShareKey: { type: String }
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return [
|
return [startMintingStyles]
|
||||||
css`
|
|
||||||
p, h1 {
|
|
||||||
color: var(--black)
|
|
||||||
}
|
|
||||||
.dialogCustom {
|
|
||||||
position: fixed;
|
|
||||||
z-index: 10000;
|
|
||||||
display: flex;
|
|
||||||
justify-content: center;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
|
||||||
top: 0px;
|
|
||||||
bottom: 0px;
|
|
||||||
left: 0px;
|
|
||||||
width: 100vw;
|
|
||||||
}
|
|
||||||
.dialogCustomInner {
|
|
||||||
width: 300px;
|
|
||||||
min-height: 400px;
|
|
||||||
background-color: var(--white);
|
|
||||||
box-shadow: var(--mdc-dialog-box-shadow, 0px 11px 15px -7px rgba(0, 0, 0, 0.2), 0px 24px 38px 3px rgba(0, 0, 0, 0.14), 0px 9px 46px 8px rgba(0, 0, 0, 0.12));
|
|
||||||
padding: 20px 24px;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
.dialogCustomInner ul {
|
|
||||||
padding-left: 0px
|
|
||||||
}
|
|
||||||
.dialogCustomInner li {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.start-minting-wrapper {
|
|
||||||
position: absolute;
|
|
||||||
transform: translate(50%, 20px);
|
|
||||||
z-index: 10;
|
|
||||||
}
|
|
||||||
.dialog-header h1 {
|
|
||||||
font-size: 18px;
|
|
||||||
}
|
|
||||||
.row {
|
|
||||||
display: flex;
|
|
||||||
width: 100%;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
.modalFooter {
|
|
||||||
width: 100%;
|
|
||||||
display: flex;
|
|
||||||
justify-content: flex-end;
|
|
||||||
}
|
|
||||||
.hide {
|
|
||||||
visibility: hidden
|
|
||||||
}
|
|
||||||
.inactiveText {
|
|
||||||
opacity: .60
|
|
||||||
}
|
|
||||||
.column {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
width: 100%;
|
|
||||||
}
|
|
||||||
.smallLoading,
|
|
||||||
.smallLoading:after {
|
|
||||||
border-radius: 50%;
|
|
||||||
width: 2px;
|
|
||||||
height: 2px;
|
|
||||||
}
|
|
||||||
.smallLoading {
|
|
||||||
border-width: 0.6em;
|
|
||||||
border-style: solid;
|
|
||||||
border-color: rgba(3, 169, 244, 0.2) rgba(3, 169, 244, 0.2)
|
|
||||||
rgba(3, 169, 244, 0.2) rgb(3, 169, 244);
|
|
||||||
font-size: 10px;
|
|
||||||
position: relative;
|
|
||||||
text-indent: -9999em;
|
|
||||||
transform: translateZ(0px);
|
|
||||||
animation: 1.1s linear 0s infinite normal none running loadingAnimation;
|
|
||||||
}
|
|
||||||
@-webkit-keyframes loadingAnimation {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@keyframes loadingAnimation {
|
|
||||||
0% {
|
|
||||||
-webkit-transform: rotate(0deg);
|
|
||||||
transform: rotate(0deg);
|
|
||||||
}
|
|
||||||
100% {
|
|
||||||
-webkit-transform: rotate(360deg);
|
|
||||||
transform: rotate(360deg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
.word-break {
|
|
||||||
word-break:break-all;
|
|
||||||
}
|
|
||||||
.dialog-container {
|
|
||||||
width: 300px;
|
|
||||||
min-height: 300px;
|
|
||||||
max-height: 75vh;
|
|
||||||
padding: 5px;
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
flex-direction: column;
|
|
||||||
}
|
|
||||||
.between {
|
|
||||||
justify-content: space-between;
|
|
||||||
}
|
|
||||||
.no-width {
|
|
||||||
width: auto
|
|
||||||
}
|
|
||||||
.between p {
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
color: var(--black);
|
|
||||||
}
|
|
||||||
.marginLoader {
|
|
||||||
margin-left: 10px;
|
|
||||||
}
|
|
||||||
.marginRight {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
.warning{
|
|
||||||
display: flex;
|
|
||||||
flex-grow: 1
|
|
||||||
}
|
|
||||||
.message-error {
|
|
||||||
color: var(--error);
|
|
||||||
}
|
|
||||||
`,
|
|
||||||
];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super();
|
super()
|
||||||
this.addressInfo = {};
|
this.addressInfo = {}
|
||||||
this.mintingAccountData = [];
|
this.mintingAccountData = []
|
||||||
this.errorMsg = '';
|
this.errorMsg = ''
|
||||||
this.openDialogRewardShare = false;
|
this.openDialogRewardShare = false
|
||||||
this.status = 0;
|
this.status = 0
|
||||||
this.privateRewardShareKey = "";
|
this.privateRewardShareKey = ''
|
||||||
this.address = this.getAddress();
|
this.address = this.getAddress()
|
||||||
this.nonce = this.getNonce();
|
this.nonce = this.getNonce()
|
||||||
this.base58PublicKey = this.getBase58PublicKey()
|
this.base58PublicKey = this.getBase58PublicKey()
|
||||||
}
|
}
|
||||||
getBase58PublicKey(){
|
|
||||||
const appState = window.parent.reduxStore.getState().app;
|
|
||||||
const selectedAddress = appState && appState.selectedAddress;
|
|
||||||
const base58PublicKey = selectedAddress && selectedAddress.base58PublicKey;
|
|
||||||
return base58PublicKey || ""
|
|
||||||
}
|
|
||||||
|
|
||||||
getAddress(){
|
|
||||||
const appState = window.parent.reduxStore.getState().app;
|
|
||||||
const selectedAddress = appState && appState.selectedAddress;
|
|
||||||
const address = selectedAddress && selectedAddress.address;
|
|
||||||
return address || ""
|
|
||||||
|
|
||||||
}
|
|
||||||
getNonce(){
|
|
||||||
const appState = window.parent.reduxStore.getState().app;
|
|
||||||
const selectedAddress = appState && appState.selectedAddress;
|
|
||||||
const nonce = selectedAddress && selectedAddress.nonce;
|
|
||||||
return nonce || ""
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html` ${this.renderStartMintingButton()} `;
|
return html`${this.renderStartMintingButton()}`
|
||||||
}
|
}
|
||||||
|
|
||||||
firstUpdated() {
|
firstUpdated() {
|
||||||
this.getMintingAcccounts();
|
this.getMintingAcccounts()
|
||||||
|
}
|
||||||
|
|
||||||
|
getBase58PublicKey() {
|
||||||
|
const appState = window.parent.reduxStore.getState().app
|
||||||
|
const selectedAddress = appState && appState.selectedAddress
|
||||||
|
const base58PublicKey = selectedAddress && selectedAddress.base58PublicKey
|
||||||
|
|
||||||
|
return base58PublicKey || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
getAddress() {
|
||||||
|
const appState = window.parent.reduxStore.getState().app
|
||||||
|
const selectedAddress = appState && appState.selectedAddress
|
||||||
|
const address = selectedAddress && selectedAddress.address
|
||||||
|
|
||||||
|
return address || ''
|
||||||
|
}
|
||||||
|
|
||||||
|
getNonce() {
|
||||||
|
const appState = window.parent.reduxStore.getState().app
|
||||||
|
const selectedAddress = appState && appState.selectedAddress
|
||||||
|
const nonce = selectedAddress && selectedAddress.nonce
|
||||||
|
|
||||||
|
return nonce || ''
|
||||||
}
|
}
|
||||||
|
|
||||||
renderErrorMsg1() {
|
renderErrorMsg1() {
|
||||||
@ -230,124 +100,130 @@ const nonce = selectedAddress && selectedAddress.nonce;
|
|||||||
}
|
}
|
||||||
|
|
||||||
async getMintingAcccounts() {
|
async getMintingAcccounts() {
|
||||||
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node];
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
|
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
const url = `${nodeUrl}/admin/mintingaccounts`;
|
const url = `${nodeUrl}/admin/mintingaccounts`
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch(url);
|
const res = await fetch(url)
|
||||||
this.mintingAccountData = await res.json();
|
|
||||||
|
this.mintingAccountData = await res.json()
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.errorMsg = this.renderErrorMsg1();
|
this.errorMsg = this.renderErrorMsg1()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async changeStatus(value){
|
async changeStatus(value) {
|
||||||
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node];
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
|
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
this.status = value
|
|
||||||
const address = this.address
|
const address = this.address
|
||||||
|
|
||||||
|
this.status = value
|
||||||
|
|
||||||
// Check to see if a sponsorship key on a newly-level 1 minter exists. If it does, remove it.
|
// Check to see if a sponsorship key on a newly-level 1 minter exists. If it does, remove it.
|
||||||
const findMintingAccountFromOtherUser = this.mintingAccountData.find((ma) => ma.recipientAccount === address && ma.mintingAccount !== address);
|
const findMintingAccountFromOtherUser = this.mintingAccountData.find((ma) => ma.recipientAccount === address && ma.mintingAccount !== address)
|
||||||
|
|
||||||
const removeMintingAccount = async (publicKey) => {
|
const removeMintingAccount = async (publicKey) => {
|
||||||
const url = `${nodeUrl}/admin/mintingaccounts?apiKey=${myNode.apiKey}`;
|
const url = `${nodeUrl}/admin/mintingaccounts?apiKey=${myNode.apiKey}`
|
||||||
return await fetch(url, {
|
return await fetch(url, {
|
||||||
method: 'DELETE',
|
method: 'DELETE',
|
||||||
body: publicKey,
|
body: publicKey
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
const addMintingAccount = async (sponsorshipKeyValue) => {
|
const addMintingAccount = async (sponsorshipKeyValue) => {
|
||||||
const url = `${nodeUrl}/admin/mintingaccounts?apiKey=${myNode.apiKey}`;
|
const url = `${nodeUrl}/admin/mintingaccounts?apiKey=${myNode.apiKey}`
|
||||||
|
|
||||||
return await fetch(url, {
|
return await fetch(url, {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
body: sponsorshipKeyValue,
|
body: sponsorshipKeyValue
|
||||||
});
|
})
|
||||||
};
|
|
||||||
|
|
||||||
try {
|
|
||||||
if (
|
|
||||||
findMintingAccountFromOtherUser &&
|
|
||||||
findMintingAccountFromOtherUser.publicKey &&
|
|
||||||
findMintingAccountFromOtherUser.publicKey[0]
|
|
||||||
) {
|
|
||||||
await removeMintingAccount(
|
|
||||||
findMintingAccountFromOtherUser.publicKey[0]
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
|
||||||
this.errorMsg = this.renderErrorMsg2();
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await addMintingAccount(this.privateRewardShareKey);
|
if (findMintingAccountFromOtherUser && findMintingAccountFromOtherUser.publicKey && findMintingAccountFromOtherUser.publicKey[0]) {
|
||||||
await routes.showSnackBar({
|
await removeMintingAccount(
|
||||||
data: translate('becomeMinterPage.bchange19'),
|
findMintingAccountFromOtherUser.publicKey[0]
|
||||||
});
|
)
|
||||||
this.status = 5;
|
}
|
||||||
await this.getMintingAcccounts();
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
this.errorMsg = this.renderErrorMsg3();
|
this.errorMsg = this.renderErrorMsg2()
|
||||||
|
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
await addMintingAccount(this.privateRewardShareKey)
|
||||||
|
|
||||||
|
await routes.showSnackBar({
|
||||||
|
data: translate('becomeMinterPage.bchange19')
|
||||||
|
})
|
||||||
|
|
||||||
|
this.status = 5
|
||||||
|
|
||||||
|
await this.getMintingAcccounts()
|
||||||
|
} catch (error) {
|
||||||
|
this.errorMsg = this.renderErrorMsg3()
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async confirmRelationship() {
|
async confirmRelationship() {
|
||||||
const myNode =
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
store.getState().app.nodeConfig.knownNodes[
|
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
store.getState().app.nodeConfig.node
|
|
||||||
];
|
|
||||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
|
|
||||||
|
|
||||||
let interval = null
|
let interval = null
|
||||||
let stop = false
|
let stop = false
|
||||||
|
|
||||||
this.status = 2
|
this.status = 2
|
||||||
|
|
||||||
const getAnswer = async () => {
|
const getAnswer = async () => {
|
||||||
const rewardShares = async (minterAddr) => {
|
const rewardShares = async (minterAddr) => {
|
||||||
const url = `${nodeUrl}/addresses/rewardshares?minters=${minterAddr}&recipients=${minterAddr}`;
|
const url = `${nodeUrl}/addresses/rewardshares?minters=${minterAddr}&recipients=${minterAddr}`
|
||||||
const res = await fetch(url);
|
const res = await fetch(url)
|
||||||
return await res.json();
|
|
||||||
};
|
return await res.json()
|
||||||
|
}
|
||||||
|
|
||||||
if (!stop) {
|
if (!stop) {
|
||||||
stop = true;
|
stop = true
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const address = this.address
|
const address = this.address
|
||||||
const myRewardShareArray = await rewardShares(address);
|
const myRewardShareArray = await rewardShares(address)
|
||||||
|
|
||||||
if (myRewardShareArray.length > 0) {
|
if (myRewardShareArray.length > 0) {
|
||||||
clearInterval(interval)
|
clearInterval(interval)
|
||||||
this.status = 3
|
|
||||||
this.timer = countDown(180, () => this.changeStatus(4));
|
|
||||||
}
|
|
||||||
|
|
||||||
} catch (error) {
|
this.status = 3
|
||||||
}
|
this.timer = countDown(180, () => this.changeStatus(4))
|
||||||
|
}
|
||||||
|
} catch (error) { }
|
||||||
|
|
||||||
stop = false
|
stop = false
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
interval = setInterval(getAnswer, 5000);
|
|
||||||
|
interval = setInterval(getAnswer, 5000)
|
||||||
}
|
}
|
||||||
|
|
||||||
renderStartMintingButton() {
|
renderStartMintingButton() {
|
||||||
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node];
|
const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port;
|
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
|
||||||
const mintingAccountData = this.mintingAccountData;
|
const mintingAccountData = this.mintingAccountData
|
||||||
const addressInfo = window.parent.reduxStore.getState().app.accountInfo.addressInfo
|
const addressInfo = window.parent.reduxStore.getState().app.accountInfo.addressInfo
|
||||||
const address = this.address
|
const address = this.address
|
||||||
const nonce = this.nonce
|
const nonce = this.nonce
|
||||||
const publicAddress = this.base58PublicKey
|
const publicAddress = this.base58PublicKey
|
||||||
const findMintingAccount = mintingAccountData.find((ma) => ma.mintingAccount === address);
|
const findMintingAccount = mintingAccountData.find((ma) => ma.mintingAccount === address)
|
||||||
const isMinterButKeyMintingKeyNotAssigned = addressInfo && addressInfo.error !== 124 && addressInfo.level >= 1 && !findMintingAccount;
|
const isMinterButKeyMintingKeyNotAssigned = addressInfo && addressInfo.error !== 124 && addressInfo.level >= 1 && !findMintingAccount
|
||||||
|
|
||||||
const makeTransactionRequest = async (lastRef) => {
|
const makeTransactionRequest = async (lastRef) => {
|
||||||
let mylastRef = lastRef;
|
let mylastRef = lastRef
|
||||||
let rewarddialog1 = get('transactions.rewarddialog1');
|
let rewarddialog1 = get('transactions.rewarddialog1')
|
||||||
let rewarddialog2 = get('transactions.rewarddialog2');
|
let rewarddialog2 = get('transactions.rewarddialog2')
|
||||||
let rewarddialog3 = get('transactions.rewarddialog3');
|
let rewarddialog3 = get('transactions.rewarddialog3')
|
||||||
let rewarddialog4 = get('transactions.rewarddialog4');
|
let rewarddialog4 = get('transactions.rewarddialog4')
|
||||||
|
|
||||||
return await routes.transaction({
|
return await routes.transaction({
|
||||||
data: {
|
data: {
|
||||||
@ -360,170 +236,150 @@ const nonce = selectedAddress && selectedAddress.nonce;
|
|||||||
rewarddialog1: rewarddialog1,
|
rewarddialog1: rewarddialog1,
|
||||||
rewarddialog2: rewarddialog2,
|
rewarddialog2: rewarddialog2,
|
||||||
rewarddialog3: rewarddialog3,
|
rewarddialog3: rewarddialog3,
|
||||||
rewarddialog4: rewarddialog4,
|
rewarddialog4: rewarddialog4
|
||||||
},
|
}
|
||||||
},
|
},
|
||||||
disableModal: true,
|
disableModal: true
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
const getTxnRequestResponse = (txnResponse) => {
|
const getTxnRequestResponse = (txnResponse) => {
|
||||||
let err6string = get('rewardsharepage.rchange21');
|
let err6string = get('rewardsharepage.rchange21')
|
||||||
|
|
||||||
if (txnResponse && txnResponse.extraData && txnResponse.extraData.rewardSharePrivateKey &&
|
if (txnResponse && txnResponse.extraData && txnResponse.extraData.rewardSharePrivateKey &&
|
||||||
txnResponse.data && (txnResponse.data.message && (txnResponse.data.message.includes('multiple') || txnResponse.data.message.includes('SELF_SHARE_EXISTS')))) {
|
txnResponse.data && (txnResponse.data.message && (txnResponse.data.message.includes('multiple') || txnResponse.data.message.includes('SELF_SHARE_EXISTS')))) {
|
||||||
return err6string;
|
return err6string
|
||||||
}
|
}
|
||||||
|
|
||||||
if (txnResponse.success === false && txnResponse.message) {
|
if (txnResponse.success === false && txnResponse.message) {
|
||||||
throw txnResponse;
|
throw txnResponse
|
||||||
} else if (txnResponse.success === true && txnResponse.data && !txnResponse.data.error) {
|
} else if (txnResponse.success === true && txnResponse.data && !txnResponse.data.error) {
|
||||||
return err6string;
|
return err6string
|
||||||
} else {
|
} else {
|
||||||
throw txnResponse;
|
throw txnResponse
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
const createSponsorshipKey = async () => {
|
const createSponsorshipKey = async () => {
|
||||||
this.status = 1;
|
this.status = 1
|
||||||
let lastRef = await getLastRef();
|
|
||||||
let myTransaction = await makeTransactionRequest(lastRef);
|
let lastRef = await getLastRef()
|
||||||
getTxnRequestResponse(myTransaction);
|
let myTransaction = await makeTransactionRequest(lastRef)
|
||||||
|
|
||||||
|
getTxnRequestResponse(myTransaction)
|
||||||
|
|
||||||
if (myTransaction && myTransaction.extraData) {
|
if (myTransaction && myTransaction.extraData) {
|
||||||
return myTransaction.extraData.rewardSharePrivateKey;
|
return myTransaction.extraData.rewardSharePrivateKey
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
const getLastRef = async () => {
|
const getLastRef = async () => {
|
||||||
const url = `${nodeUrl}/addresses/lastreference/${address}`;
|
const url = `${nodeUrl}/addresses/lastreference/${address}`
|
||||||
const res = await fetch(url);
|
const res = await fetch(url)
|
||||||
return await res.text();
|
|
||||||
};
|
return await res.text()
|
||||||
|
}
|
||||||
|
|
||||||
const startMinting = async () => {
|
const startMinting = async () => {
|
||||||
this.openDialogRewardShare = true
|
this.openDialogRewardShare = true
|
||||||
this.errorMsg = '';
|
this.errorMsg = ''
|
||||||
|
|
||||||
const address = this.address
|
const address = this.address
|
||||||
|
|
||||||
const findMintingAccountsFromUser = this.mintingAccountData.filter((ma) => ma.recipientAccount === address && ma.mintingAccount === address);
|
const findMintingAccountsFromUser = this.mintingAccountData.filter((ma) => ma.recipientAccount === address && ma.mintingAccount === address)
|
||||||
|
|
||||||
if(findMintingAccountsFromUser.length > 2){
|
if (findMintingAccountsFromUser.length > 2) {
|
||||||
this.errorMsg = translate("startminting.smchange10")
|
this.errorMsg = translate("startminting.smchange10")
|
||||||
return;
|
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.privateRewardShareKey = await createSponsorshipKey();
|
this.privateRewardShareKey = await createSponsorshipKey()
|
||||||
|
|
||||||
await this.confirmRelationship(publicAddress)
|
await this.confirmRelationship(publicAddress)
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.log({ error })
|
console.log({ error })
|
||||||
this.errorMsg = (error && error.data && error.data.message) ? error.data.message : this.renderErrorMsg4();
|
|
||||||
|
|
||||||
|
this.errorMsg = (error && error.data && error.data.message) ? error.data.message : this.renderErrorMsg4()
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
${isMinterButKeyMintingKeyNotAssigned ? html`
|
${isMinterButKeyMintingKeyNotAssigned ? html`
|
||||||
<div class="start-minting-wrapper">
|
<div class="start-minting-wrapper">
|
||||||
<my-button label="${translate('becomeMinterPage.bchange18')}"
|
<my-button
|
||||||
|
label="${translate('becomeMinterPage.bchange18')}"
|
||||||
?isLoading=${false}
|
?isLoading=${false}
|
||||||
.onClick=${async () => {
|
.onClick=${async () => {
|
||||||
await startMinting();
|
await startMinting();
|
||||||
if (this.errorMsg) {
|
if (this.errorMsg) {
|
||||||
await routes.showSnackBar({
|
await routes.showSnackBar({
|
||||||
data: this.errorMsg,
|
data: this.errorMsg
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
>
|
></my-button>
|
||||||
</my-button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Dialog for tracking the progress of starting minting -->
|
<!-- Dialog for tracking the progress of starting minting -->
|
||||||
|
|
||||||
${this.openDialogRewardShare ? html`
|
${this.openDialogRewardShare ? html`
|
||||||
<div class="dialogCustom">
|
<div class="dialogCustom">
|
||||||
<div class="dialogCustomInner">
|
<div class="dialogCustomInner">
|
||||||
<div class="dialog-header" >
|
<div class="dialog-header" >
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<h1>In progress</h1>
|
<h1>In progress</h1>
|
||||||
<div class=${`smallLoading marginLoader ${this.status > 3 && 'hide'}`}></div>
|
<div class=${`smallLoading marginLoader ${this.status > 3 && 'hide'}`}></div>
|
||||||
|
</div>
|
||||||
|
<hr />
|
||||||
</div>
|
</div>
|
||||||
<hr />
|
<div class="dialog-container">
|
||||||
</div>
|
<ul>
|
||||||
<div class="dialog-container">
|
<li class="row between">
|
||||||
<ul>
|
<p>1. ${translate("startminting.smchange5")}</p>
|
||||||
<li class="row between">
|
<div class=${`smallLoading marginLoader ${this.status !== 1 && 'hide'}`}></div>
|
||||||
<p>
|
</li>
|
||||||
1. ${translate("startminting.smchange5")}
|
<li class=${`row between ${this.status < 2 && 'inactiveText'}`}>
|
||||||
</p>
|
<p>2. ${translate("startminting.smchange6")}</p>
|
||||||
<div class=${`smallLoading marginLoader ${this.status !== 1 && 'hide'}`}></div>
|
<div class=${`smallLoading marginLoader ${this.status !== 2 && 'hide'}`}></div>
|
||||||
</li>
|
</li>
|
||||||
|
<li class=${`row between ${this.status < 3 && 'inactiveText'}`}>
|
||||||
<li class=${`row between ${this.status < 2 && 'inactiveText'}`}>
|
<p>3. ${translate("startminting.smchange7")}</p>
|
||||||
<p>
|
<div class="row no-width">
|
||||||
2. ${translate("startminting.smchange6")}
|
<div class=${`smallLoading marginLoader marginRight ${this.status !== 3 && 'hide'}`} ></div>
|
||||||
</p>
|
<p>${asyncReplace(this.timer)}</p>
|
||||||
<div class=${`smallLoading marginLoader ${this.status !== 2 && 'hide'}`}></div>
|
</div>
|
||||||
</li>
|
</li>
|
||||||
|
<li class=${`row between ${this.status < 4 && 'inactiveText'}`}>
|
||||||
<li class=${`row between ${this.status < 3 && 'inactiveText'}`}>
|
<p>4. ${translate("startminting.smchange8")}</p>
|
||||||
<p>
|
<div class=${`smallLoading marginLoader ${this.status !== 4 && 'hide'}`}></div>
|
||||||
3. ${translate("startminting.smchange7")}
|
</li>
|
||||||
</p>
|
<li class=${`row between ${this.status < 5 && 'inactiveText'}`}>
|
||||||
<div class="row no-width">
|
<p>5. ${translate("startminting.smchange9")}</p>
|
||||||
<div class=${`smallLoading marginLoader marginRight ${this.status !== 3 && 'hide'}`} ></div> <p>${asyncReplace(this.timer)}</p>
|
</li>
|
||||||
</div>
|
</ul>
|
||||||
</li>
|
<div class="warning column">
|
||||||
|
<p>Warning: do not close the Qortal UI until completion!</p>
|
||||||
<li class=${`row between ${this.status < 4 && 'inactiveText'}`}>
|
<p class="message-error">${this.errorMsg}</p>
|
||||||
<p>
|
</div>
|
||||||
4. ${translate("startminting.smchange8")}
|
</div>
|
||||||
</p>
|
<div class="modalFooter">
|
||||||
<div class=${`smallLoading marginLoader ${this.status !== 4 && 'hide'}`}></div>
|
${this.errorMsg || this.status === 5 ? html`
|
||||||
</li>
|
<mwc-button slot="primaryAction" @click=${() => { this.openDialogRewardShare = false; this.errorMsg = '';}} class="red">
|
||||||
|
${translate("general.close")}
|
||||||
<li class=${`row between ${this.status < 5 && 'inactiveText'}`}>
|
</mwc-button>
|
||||||
<p>
|
` : ''}
|
||||||
5. ${translate("startminting.smchange9")}
|
|
||||||
</p>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
<div class="warning column">
|
|
||||||
<p>
|
|
||||||
Warning: do not close the Qortal UI until completion!
|
|
||||||
</p>
|
|
||||||
<p class="message-error">${this.errorMsg}</p>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="modalFooter">
|
|
||||||
${this.errorMsg || this.status === 5 ? html`
|
|
||||||
<mwc-button
|
|
||||||
slot="primaryAction"
|
|
||||||
@click=${() => {
|
|
||||||
this.openDialogRewardShare = false
|
|
||||||
this.errorMsg = ''
|
|
||||||
}}
|
|
||||||
class="red"
|
|
||||||
>
|
|
||||||
${translate("general.close")}
|
|
||||||
</mwc-button>
|
|
||||||
` : '' }
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
` : ''}
|
||||||
</div>
|
|
||||||
|
|
||||||
` : ""}
|
|
||||||
` : ''}
|
` : ''}
|
||||||
`;
|
`
|
||||||
}
|
}
|
||||||
|
|
||||||
stateChanged(state) {
|
stateChanged(state) {
|
||||||
this.addressInfo = state.app.accountInfo.addressInfo;
|
this.addressInfo = state.app.accountInfo.addressInfo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('start-minting', StartMinting);
|
window.customElements.define('start-minting', StartMinting)
|
@ -1,9 +1,12 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {translate} from '../../translate'
|
import { themeToggleStyles } from '../styles/core-css'
|
||||||
import '@polymer/paper-icon-button/paper-icon-button.js'
|
import '@polymer/paper-icon-button/paper-icon-button.js'
|
||||||
import '@polymer/iron-icons/image-icons.js'
|
import '@polymer/iron-icons/image-icons.js'
|
||||||
import '@polymer/iron-icons/iron-icons.js'
|
import '@polymer/iron-icons/iron-icons.js'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { translate } from '../../translate'
|
||||||
|
|
||||||
class ThemeToggle extends LitElement {
|
class ThemeToggle extends LitElement {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
@ -11,58 +14,15 @@ class ThemeToggle extends LitElement {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static get styles() {
|
||||||
|
return [themeToggleStyles]
|
||||||
|
}
|
||||||
|
|
||||||
constructor() {
|
constructor() {
|
||||||
super()
|
super()
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
}
|
}
|
||||||
|
|
||||||
static styles = [
|
|
||||||
css`
|
|
||||||
* {
|
|
||||||
--mdc-theme-primary: rgb(3, 169, 244);
|
|
||||||
--mdc-theme-secondary: var(--mdc-theme-primary);
|
|
||||||
--mdc-theme-error: rgb(255, 89, 89);
|
|
||||||
--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);
|
|
||||||
--item-selected-color: var(--nav-selected-color);
|
|
||||||
--item-selected-color-text: var(--nav-selected-color-text);
|
|
||||||
--item-color-active: var(--nav-color-active);
|
|
||||||
--item-color-hover: var(--nav-color-hover);
|
|
||||||
--item-text-color: var(--nav-text-color);
|
|
||||||
--item-icon-color: var(--nav-icon-color);
|
|
||||||
--item-border-color: var(--nav-border-color);
|
|
||||||
--item-border-selected-color: var(--nav-border-selected-color);
|
|
||||||
}
|
|
||||||
|
|
||||||
paper-icon-button {
|
|
||||||
-ms-transform: rotate(120deg);
|
|
||||||
transform: rotate(120deg);
|
|
||||||
}
|
|
||||||
|
|
||||||
:host([theme="light"]) .light-mode {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host([theme="light"]) .dark-mode {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host([theme="dark"]) .light-mode {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
:host([theme="dark"]) .dark-mode {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
]
|
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return html`
|
return html`
|
||||||
<div style="display: inline;">
|
<div style="display: inline;">
|
||||||
@ -87,16 +47,17 @@ class ThemeToggle extends LitElement {
|
|||||||
this.dispatchEvent(new CustomEvent('qort-theme-change', {
|
this.dispatchEvent(new CustomEvent('qort-theme-change', {
|
||||||
bubbles: true,
|
bubbles: true,
|
||||||
composed: true,
|
composed: true,
|
||||||
detail: this.theme,
|
detail: this.theme
|
||||||
}))
|
}))
|
||||||
|
|
||||||
window.localStorage.setItem('qortalTheme', this.theme)
|
window.localStorage.setItem('qortalTheme', this.theme)
|
||||||
|
|
||||||
this.initTheme()
|
this.initTheme()
|
||||||
}
|
}
|
||||||
|
|
||||||
initTheme() {
|
initTheme() {
|
||||||
document.querySelector('html').setAttribute('theme', this.theme);
|
document.querySelector('html').setAttribute('theme', this.theme)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('theme-toggle', ThemeToggle);
|
window.customElements.define('theme-toggle', ThemeToggle)
|
File diff suppressed because it is too large
Load Diff
@ -1,124 +1,84 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers'
|
import { connect } from 'pwa-helpers'
|
||||||
import {store} from '../store.js'
|
import { store } from '../store'
|
||||||
import {translate} from '../../translate'
|
import { walletProfileStyles } from '../styles/core-css'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { translate } from '../../translate'
|
||||||
|
|
||||||
class WalletProfile extends connect(store)(LitElement) {
|
class WalletProfile extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
wallet: { type: Object },
|
wallet: { type: Object },
|
||||||
nodeConfig: { type: Object },
|
nodeConfig: { type: Object },
|
||||||
accountInfo: { type: Object },
|
accountInfo: { type: Object },
|
||||||
theme: { type: String, reflect: true }
|
theme: { type: String, reflect: true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return css`
|
return [walletProfileStyles]
|
||||||
#profileInMenu {
|
}
|
||||||
padding: 12px;
|
|
||||||
border-top: var(--border);
|
|
||||||
background: var(--sidetopbar);
|
|
||||||
color: var(--black);
|
|
||||||
}
|
|
||||||
|
|
||||||
#accountName {
|
constructor() {
|
||||||
margin: 0;
|
super()
|
||||||
font-size: 18px;
|
this.wallet = {}
|
||||||
font-weight: 500;
|
this.nodeConfig = {}
|
||||||
width: 100%;
|
this.accountInfo = {
|
||||||
padding-bottom: 8px;
|
names: [],
|
||||||
display: flex;
|
addressInfo: {}
|
||||||
}
|
}
|
||||||
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
|
}
|
||||||
|
|
||||||
#blocksMinted {
|
render() {
|
||||||
margin:0;
|
return html`
|
||||||
margin-top: 0;
|
<div id="profileInMenu">
|
||||||
font-size: 12px;
|
<div style="padding: 8px 0;">
|
||||||
color: #03a9f4;
|
<div id="accountName">
|
||||||
}
|
<div id="child inline-block-child" class="full-info-logo">${this.getAvatar()}</div>
|
||||||
|
|
||||||
|
<div id="inline-block-child">
|
||||||
|
<div>
|
||||||
|
${this.accountInfo.names.length !== 0 ? this.accountInfo.names[0].name : ''}
|
||||||
|
</div>
|
||||||
|
<div>
|
||||||
|
${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>
|
||||||
|
` : ''}
|
||||||
|
</div>
|
||||||
|
<p id="blocksMinted">${translate("walletprofile.blocksminted")} - ${this.accountInfo.addressInfo.blocksMinted + this.accountInfo.addressInfo.blocksMintedAdjustment}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p id="address">${this.wallet.addresses[0].address}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
#address {
|
firstUpdated() {
|
||||||
white-space: nowrap;
|
// ...
|
||||||
overflow: hidden;
|
}
|
||||||
text-overflow: ellipsis;
|
|
||||||
margin:0;
|
|
||||||
margin-top: 8px;
|
|
||||||
font-size: 11px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.round-fullinfo {
|
getAvatar() {
|
||||||
position: relative;
|
if (this.accountInfo.names.length === 0) {
|
||||||
width: 68px;
|
return html`<img class="round-fullinfo" src="/img/incognito.png">`
|
||||||
height: 68px;
|
} else {
|
||||||
border-radius: 50%;
|
const avatarNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
||||||
}
|
const avatarUrl = avatarNode.protocol + '://' + avatarNode.domain + ':' + avatarNode.port
|
||||||
|
const url = `${avatarUrl}/arbitrary/THUMBNAIL/${this.accountInfo.names[0].name}/qortal_avatar?async=true`
|
||||||
|
|
||||||
.full-info-logo {
|
return html`<img class="round-fullinfo" src="${url}" onerror="this.src='/img/incognito.png';" />`
|
||||||
width: 68px;
|
}
|
||||||
height: 68px;
|
}
|
||||||
border-radius: 50%;
|
|
||||||
}
|
|
||||||
|
|
||||||
.inline-block-child {
|
stateChanged(state) {
|
||||||
flex: 1;
|
this.wallet = state.app.wallet
|
||||||
}
|
this.nodeConfig = state.app.nodeConfig
|
||||||
`
|
this.accountInfo = state.app.accountInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
constructor() {
|
|
||||||
super()
|
|
||||||
this.wallet = {}
|
|
||||||
this.nodeConfig = {}
|
|
||||||
this.accountInfo = {
|
|
||||||
names: [],
|
|
||||||
addressInfo: {}
|
|
||||||
}
|
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
|
||||||
return html`
|
|
||||||
<div id="profileInMenu">
|
|
||||||
<div style="padding: 8px 0;">
|
|
||||||
<div id="accountName">
|
|
||||||
<div id="child inline-block-child" class="full-info-logo">${this.getAvatar()}</div>
|
|
||||||
|
|
||||||
<div id="inline-block-child">
|
|
||||||
<div>${this.accountInfo.names.length !== 0 ? this.accountInfo.names[0].name : ''}</div>
|
|
||||||
<div>${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>` : ''}</div>
|
|
||||||
<p id="blocksMinted">${translate("walletprofile.blocksminted")} - ${this.accountInfo.addressInfo.blocksMinted + this.accountInfo.addressInfo.blocksMintedAdjustment}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<p id="address">${this.wallet.addresses[0].address}</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
firstUpdated() {}
|
|
||||||
|
|
||||||
getAvatar() {
|
|
||||||
if (this.accountInfo.names.length === 0) {
|
|
||||||
return html`<img class="round-fullinfo" src="/img/incognito.png">`
|
|
||||||
} else {
|
|
||||||
const avatarNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
|
||||||
const avatarUrl = avatarNode.protocol + '://' + avatarNode.domain + ':' + avatarNode.port
|
|
||||||
const url = `${avatarUrl}/arbitrary/THUMBNAIL/${this.accountInfo.names[0].name}/qortal_avatar?async=true&apiKey=${this.getApiKey()}`
|
|
||||||
return html`<img class="round-fullinfo" src="${url}" onerror="this.src='/img/incognito.png';" />`
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
getApiKey() {
|
|
||||||
const apiNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
|
|
||||||
return apiNode.apiKey
|
|
||||||
}
|
|
||||||
|
|
||||||
stateChanged(state) {
|
|
||||||
this.wallet = state.app.wallet
|
|
||||||
this.nodeConfig = state.app.nodeConfig
|
|
||||||
this.accountInfo = state.app.accountInfo
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('wallet-profile', WalletProfile)
|
window.customElements.define('wallet-profile', WalletProfile)
|
@ -1,55 +1,62 @@
|
|||||||
'use strict'
|
|
||||||
const utils = {
|
const utils = {
|
||||||
int32ToBytes (word) {
|
int32ToBytes(word) {
|
||||||
var byteArray = []
|
var byteArray = []
|
||||||
for (var b = 0; b < 32; b += 8) {
|
for (var b = 0; b < 32; b += 8) {
|
||||||
byteArray.push((word >>> (24 - b % 32)) & 0xFF)
|
byteArray.push((word >>> (24 - b % 32)) & 0xFF)
|
||||||
}
|
}
|
||||||
return byteArray
|
return byteArray
|
||||||
},
|
},
|
||||||
|
|
||||||
stringtoUTF8Array (message) {
|
stringtoUTF8Array(message) {
|
||||||
if (typeof message === 'string') {
|
if (typeof message === 'string') {
|
||||||
var s = unescape(encodeURIComponent(message)) // UTF-8
|
var s = unescape(encodeURIComponent(message)) // UTF-8
|
||||||
message = new Uint8Array(s.length)
|
message = new Uint8Array(s.length)
|
||||||
for (var i = 0; i < s.length; i++) {
|
for (var i = 0; i < s.length; i++) {
|
||||||
message[i] = s.charCodeAt(i) & 0xff
|
message[i] = s.charCodeAt(i) & 0xff
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return message
|
|
||||||
},
|
|
||||||
// ...buffers then buffers.foreach and append to buffer1
|
|
||||||
appendBuffer (buffer1, buffer2) {
|
|
||||||
buffer1 = new Uint8Array(buffer1)
|
|
||||||
buffer2 = new Uint8Array(buffer2)
|
|
||||||
const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength)
|
|
||||||
tmp.set(buffer1, 0)
|
|
||||||
tmp.set(buffer2, buffer1.byteLength)
|
|
||||||
return tmp
|
|
||||||
},
|
|
||||||
|
|
||||||
int64ToBytes (int64) {
|
return message
|
||||||
// we want to represent the input as a 8-bytes array
|
},
|
||||||
var byteArray = [0, 0, 0, 0, 0, 0, 0, 0]
|
|
||||||
|
|
||||||
for (var index = 0; index < byteArray.length; index++) {
|
// ...buffers then buffers.foreach and append to buffer1
|
||||||
var byte = int64 & 0xff
|
appendBuffer(buffer1, buffer2) {
|
||||||
byteArray[byteArray.length - index - 1] = byte
|
buffer1 = new Uint8Array(buffer1)
|
||||||
int64 = (int64 - byte) / 256
|
buffer2 = new Uint8Array(buffer2)
|
||||||
}
|
|
||||||
|
|
||||||
return byteArray
|
const tmp = new Uint8Array(buffer1.byteLength + buffer2.byteLength)
|
||||||
},
|
|
||||||
|
|
||||||
equal (buf1, buf2) {
|
tmp.set(buffer1, 0)
|
||||||
if (buf1.byteLength != buf2.byteLength) return false
|
tmp.set(buffer2, buffer1.byteLength)
|
||||||
var dv1 = new Uint8Array(buf1)
|
|
||||||
var dv2 = new Uint8Array(buf2)
|
return tmp
|
||||||
for (var i = 0; i != buf1.byteLength; i++) {
|
},
|
||||||
if (dv1[i] != dv2[i]) return false
|
|
||||||
}
|
int64ToBytes(int64) {
|
||||||
return true
|
// we want to represent the input as a 8-bytes array
|
||||||
}
|
var byteArray = [0, 0, 0, 0, 0, 0, 0, 0]
|
||||||
|
|
||||||
|
for (var index = 0; index < byteArray.length; index++) {
|
||||||
|
var byte = int64 & 0xff
|
||||||
|
byteArray[byteArray.length - index - 1] = byte
|
||||||
|
int64 = (int64 - byte) / 256
|
||||||
|
}
|
||||||
|
|
||||||
|
return byteArray
|
||||||
|
},
|
||||||
|
|
||||||
|
equal(buf1, buf2) {
|
||||||
|
if (buf1.byteLength != buf2.byteLength) return false
|
||||||
|
|
||||||
|
var dv1 = new Uint8Array(buf1)
|
||||||
|
var dv2 = new Uint8Array(buf2)
|
||||||
|
|
||||||
|
for (var i = 0; i != buf1.byteLength; i++) {
|
||||||
|
if (dv1[i] != dv2[i]) return false
|
||||||
|
}
|
||||||
|
|
||||||
|
return true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default utils
|
export default utils
|
@ -1,115 +0,0 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
|
||||||
|
|
||||||
import '@material/mwc-button'
|
|
||||||
import '@material/mwc-icon'
|
|
||||||
|
|
||||||
import {translate} from '../../translate'
|
|
||||||
|
|
||||||
class FragFileInput extends LitElement {
|
|
||||||
static get properties () {
|
|
||||||
return {
|
|
||||||
accept: { type: String },
|
|
||||||
readAs: { type: String }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static get styles () {
|
|
||||||
return css`
|
|
||||||
#drop-area {
|
|
||||||
border: 2px dashed #ccc;
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor () {
|
|
||||||
super()
|
|
||||||
this.readAs = this.readAs || 'Text'
|
|
||||||
}
|
|
||||||
|
|
||||||
render () {
|
|
||||||
return html`
|
|
||||||
<div id="drop-area">
|
|
||||||
<slot name="info-text"></slot>
|
|
||||||
<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><span style="color: var(--black);"> ${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 },
|
|
||||||
bubbles: true,
|
|
||||||
composed: true
|
|
||||||
}))
|
|
||||||
}
|
|
||||||
fr['readAs' + this.readAs](file)
|
|
||||||
}
|
|
||||||
|
|
||||||
firstUpdated () {
|
|
||||||
this._dropArea = this.shadowRoot.getElementById('drop-area')
|
|
||||||
|
|
||||||
const preventDefaults = e => {
|
|
||||||
e.preventDefault()
|
|
||||||
e.stopPropagation()
|
|
||||||
}
|
|
||||||
|
|
||||||
;['dragenter', 'dragover', 'dragleave', 'drop'].forEach(eventName => {
|
|
||||||
this._dropArea.addEventListener(eventName, preventDefaults, false)
|
|
||||||
})
|
|
||||||
|
|
||||||
const highlight = e => {
|
|
||||||
this._dropArea.classList.add('highlight')
|
|
||||||
}
|
|
||||||
|
|
||||||
const unhighlight = e => {
|
|
||||||
this._dropArea.classList.remove('highlight')
|
|
||||||
}
|
|
||||||
|
|
||||||
;['dragenter', 'dragover'].forEach(eventName => {
|
|
||||||
this._dropArea.addEventListener(eventName, highlight, false)
|
|
||||||
})
|
|
||||||
|
|
||||||
;['dragleave', 'drop'].forEach(eventName => {
|
|
||||||
this._dropArea.addEventListener(eventName, unhighlight, false)
|
|
||||||
})
|
|
||||||
|
|
||||||
this._dropArea.addEventListener('drop', e => {
|
|
||||||
const dt = e.dataTransfer
|
|
||||||
const file = dt.files[0]
|
|
||||||
|
|
||||||
this.readFile(file)
|
|
||||||
}, false)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
window.customElements.define('frag-file-input', FragFileInput)
|
|
@ -1,4 +1,15 @@
|
|||||||
export const defaultQappsTabs = [
|
export const defaultQappsTabs = [
|
||||||
|
{
|
||||||
|
"url": "myapp",
|
||||||
|
"domain": "core",
|
||||||
|
"page": "qdn/browser/index.html?name=Q-Support&service=APP",
|
||||||
|
"title": "Q-Support",
|
||||||
|
"icon": "vaadin:external-browser",
|
||||||
|
"mwcicon": "apps",
|
||||||
|
"pluginNumber": "plugin-04tlGdLkkd",
|
||||||
|
"menus": [],
|
||||||
|
"parent": false
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"url": "myapp",
|
"url": "myapp",
|
||||||
"domain": "core",
|
"domain": "core",
|
||||||
|
@ -15,4 +15,4 @@ Epml.registerPlugin(EpmlStreamPlugin)
|
|||||||
Epml.registerPlugin(EpmlProxyPlugin)
|
Epml.registerPlugin(EpmlProxyPlugin)
|
||||||
Epml.allowProxying = true
|
Epml.allowProxying = true
|
||||||
|
|
||||||
export { Epml, EpmlStream }
|
export { Epml, EpmlStream }
|
@ -1,106 +1,83 @@
|
|||||||
import {css, html, LitElement} from 'lit'
|
import { css, html, LitElement } from 'lit'
|
||||||
import {connect} from 'pwa-helpers'
|
import { connect } from 'pwa-helpers'
|
||||||
import {store} from '../store.js'
|
import { store } from '../store'
|
||||||
import {get, translate} from '../../translate'
|
import { listenForRequest } from '../transactionRequest'
|
||||||
|
import { confirmTransactionDialogStyles } from '../styles/core-css'
|
||||||
import {listenForRequest} from '../transactionRequest.js'
|
|
||||||
|
|
||||||
import '@polymer/paper-dialog/paper-dialog.js'
|
|
||||||
import '@material/mwc-button'
|
import '@material/mwc-button'
|
||||||
|
import '@polymer/paper-dialog/paper-dialog.js'
|
||||||
|
|
||||||
|
// Multi language support
|
||||||
|
import { get, translate } from '../../translate'
|
||||||
|
|
||||||
class ConfirmTransactionDialog extends connect(store)(LitElement) {
|
class ConfirmTransactionDialog extends connect(store)(LitElement) {
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
txInfo: { type: Object },
|
txInfo: { type: Object },
|
||||||
theme: { type: String, reflect: true }
|
theme: { type: String, reflect: true }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static get styles() {
|
static get styles() {
|
||||||
return css`
|
return [confirmTransactionDialogStyles]
|
||||||
* {
|
}
|
||||||
--mdc-theme-primary: rgb(3, 169, 244);
|
|
||||||
--mdc-theme-secondary: var(--mdc-theme-primary);
|
|
||||||
--mdc-theme-surface: var(--white);
|
|
||||||
--mdc-dialog-content-ink-color: var(--black);
|
|
||||||
}
|
|
||||||
|
|
||||||
.decline {
|
constructor() {
|
||||||
--mdc-theme-primary: var(--mdc-theme-error)
|
super()
|
||||||
}
|
this.transaction = {
|
||||||
|
template: html`Awaiting transaction info`
|
||||||
|
}
|
||||||
|
this.txInfo = html``
|
||||||
|
listenForRequest(args => this.requestTransaction(args))
|
||||||
|
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
|
||||||
|
}
|
||||||
|
|
||||||
#txInfo {
|
render() {
|
||||||
text-align: left;
|
return html`
|
||||||
max-width: 520px;
|
<paper-dialog style="background: var(--white);" id="confirmDialog" modal>
|
||||||
color: var(--black);
|
<h2 style="color: var(--black);">${translate("transpage.tchange1")}</h2>
|
||||||
}
|
<div id="txInfo">
|
||||||
|
${this.txInfo}
|
||||||
|
</div>
|
||||||
|
<div class="buttons">
|
||||||
|
<mwc-button class='decline' @click=${e => this.decline(e)} dialog-dismiss>${translate("transpage.tchange2")}</mwc-button>
|
||||||
|
<mwc-button class='confirm' @click=${e => this.confirm(e)} dialog-confirm autofocus>${translate("transpage.tchange3")}</mwc-button>
|
||||||
|
</div>
|
||||||
|
</paper-dialog>
|
||||||
|
`
|
||||||
|
}
|
||||||
|
|
||||||
.buttons {
|
firstUpdated() {
|
||||||
text-align:right;
|
// ...
|
||||||
}
|
}
|
||||||
|
|
||||||
table td, th{
|
requestTransaction(transaction) {
|
||||||
padding:4px;
|
this.shadowRoot.getElementById('confirmDialog').open()
|
||||||
text-align:left;
|
this.transaction = transaction
|
||||||
font-size:14px;
|
this.txInfo = transaction.render(html)
|
||||||
color: var(--black);
|
|
||||||
}
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
constructor() {
|
return new Promise((resolve, reject) => {
|
||||||
super()
|
this._resolve = resolve
|
||||||
this.transaction = {
|
this._reject = reject
|
||||||
template: html`Awaiting transaction info`
|
})
|
||||||
}
|
}
|
||||||
this.txInfo = html``
|
|
||||||
listenForRequest(args => this.requestTransaction(args))
|
|
||||||
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light';
|
|
||||||
}
|
|
||||||
|
|
||||||
render() {
|
confirm(e) {
|
||||||
return html`
|
this._resolve({
|
||||||
<paper-dialog style="background: var(--white);" id="confirmDialog" modal>
|
success: true
|
||||||
<h2 style="color: var(--black);">${translate("transpage.tchange1")}</h2>
|
})
|
||||||
<div id="txInfo">
|
}
|
||||||
${this.txInfo}
|
|
||||||
</div>
|
|
||||||
<div class="buttons">
|
|
||||||
<mwc-button class='decline' @click=${e => this.decline(e)} dialog-dismiss>${translate("transpage.tchange2")}</mwc-button>
|
|
||||||
<mwc-button class='confirm' @click=${e => this.confirm(e)} dialog-confirm autofocus>${translate("transpage.tchange3")}</mwc-button>
|
|
||||||
</div>
|
|
||||||
</paper-dialog>
|
|
||||||
`
|
|
||||||
}
|
|
||||||
|
|
||||||
stateChanged(state) {
|
decline(e) {
|
||||||
this.loggedIn = state.app.loggedIn
|
const rejecterror = get("transactions.declined")
|
||||||
}
|
this._reject(new Error(rejecterror))
|
||||||
|
}
|
||||||
|
|
||||||
requestTransaction(transaction) {
|
stateChanged(state) {
|
||||||
this.shadowRoot.getElementById('confirmDialog').open()
|
this.loggedIn = state.app.loggedIn
|
||||||
this.transaction = transaction
|
}
|
||||||
this.txInfo = transaction.render(html)
|
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
this._resolve = resolve
|
|
||||||
this._reject = reject
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
confirm(e) {
|
|
||||||
this._resolve({
|
|
||||||
success: true
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
decline(e) {
|
|
||||||
const rejecterror = get("transactions.declined")
|
|
||||||
this._reject(new Error(rejecterror))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
window.customElements.define('confirm-transaction-dialog', ConfirmTransactionDialog)
|
window.customElements.define('confirm-transaction-dialog', ConfirmTransactionDialog)
|
||||||
|
|
||||||
const txDialog = document.createElement('confirm-transaction-dialog')
|
const txDialog = document.createElement('confirm-transaction-dialog')
|
||||||
export const requestTransactionDialog = document.body.appendChild(txDialog)
|
export const requestTransactionDialog = document.body.appendChild(txDialog)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user