4
1
mirror of https://github.com/Qortal/qortal-ui.git synced 2025-02-11 17:55:51 +00:00

Dark / Light mode

This commit is contained in:
AlphaX-Projects 2022-03-07 07:35:57 -08:00 committed by GitHub
parent 3faf1e6f79
commit 4c1e4dcba9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
33 changed files with 1174 additions and 765 deletions

View File

@ -39,9 +39,9 @@
"@rollup/plugin-commonjs": "^21.0.2",
"@rollup/plugin-node-resolve": "^13.1.3",
"@rollup/plugin-replace": "^4.0.0",
"@vaadin/button": "^23.0.0",
"@vaadin/grid": "^23.0.0",
"@vaadin/icons": "^23.0.0",
"@vaadin/button": "^23.0.1",
"@vaadin/grid": "^23.0.1",
"@vaadin/icons": "^23.0.1",
"epml": "^0.3.3",
"html-escaper": "^3.0.3",
"lit": "^2.2.0",

View File

@ -23,26 +23,34 @@ class ChatHead extends LitElement {
cursor: pointer;
width: 100%;
}
li:hover {
background-color: #eee;
background-color: var(--chatmenuhover);
}
.active {
background: #ebebeb;
background: var(--chatmenuactive);
border-left: 4px solid #3498db;
}
.img-icon {
float: left;
font-size:40px;
color: var(--black);
}
.about {
margin-top: 8px;
}
.about {
padding-left: 8px;
}
.status {
color: #92959e;
}
.clearfix:after {
visibility: hidden;
display: block;
@ -74,7 +82,7 @@ class ChatHead extends LitElement {
<li @click=${() => this.getUrl(this.chatInfo.url)} class="clearfix ${this.activeChatHeadUrl === this.chatInfo.url ? 'active' : ''}">
<mwc-icon class="img-icon">account_circle</mwc-icon>
<div class="about">
<div class="name"><span style="float:left; padding-left: 8px;">${this.chatInfo.groupName ? this.chatInfo.groupName : this.chatInfo.name !== undefined ? this.chatInfo.name : this.chatInfo.address.substr(0, 15)} </span> <mwc-icon style="float:right; padding: 0 1rem;">${this.chatInfo.groupId !== undefined ? 'lock_open' : 'lock'}</mwc-icon> </div>
<div class="name"><span style="float:left; padding-left: 8px; color: var(--black);">${this.chatInfo.groupName ? this.chatInfo.groupName : this.chatInfo.name !== undefined ? this.chatInfo.name : this.chatInfo.address.substr(0, 15)} </span> <mwc-icon style="float:right; padding: 0 1rem; color: var(--black);">${this.chatInfo.groupId !== undefined ? 'lock_open' : 'lock'}</mwc-icon> </div>
</div>
</li>
`

View File

@ -39,11 +39,13 @@ class ChatPage extends LitElement {
html {
scroll-behavior: smooth;
}
.chat-text-area {
display: flex;
justify-content: center;
overflow: hidden;
}
.chat-text-area .typing-area {
display: flex;
flex-direction: row;
@ -53,12 +55,16 @@ class ChatPage extends LitElement {
box-sizing: border-box;
padding: 5px;
margin-bottom: 8px;
border: 1px solid rgba(0, 0, 0, 0.3);
border: 1px solid var(--black);
border-radius: 10px;
background: #f1f1f1;
color: var(--black);
}
.chat-text-area .typing-area textarea {
display: none;
}
.chat-text-area .typing-area .chat-editor {
border-color: transparent;
flex: 1;
@ -68,6 +74,7 @@ class ChatPage extends LitElement {
padding: 0;
border: none;
}
.chat-text-area .typing-area .emoji-button {
width: 45px;
height: 40px;
@ -77,7 +84,9 @@ class ChatPage extends LitElement {
background: transparent;
cursor: pointer;
max-height: 40px;
color: var(--black);
}
.float-left {
float: left;
}
@ -88,15 +97,11 @@ class ChatPage extends LitElement {
`
}
updated(changedProps) {
}
constructor() {
super()
this.getOldMessage = this.getOldMessage.bind(this)
this._sendMessage = this._sendMessage.bind(this)
this._downObserverhandler = this._downObserverhandler.bind(this)
this.selectedAddress = {}
this.chatId = ''
this.myAddress = ''
@ -122,7 +127,7 @@ class ChatPage extends LitElement {
<div class="chat-text-area">
<div class="typing-area">
<textarea tabindex='1' ?autofocus=${true} ?disabled=${this.isLoading || this.isLoadingMessages} id="messageBox" rows="1"></textarea>
<textarea style="color: var(--black);" tabindex='1' ?autofocus=${true} ?disabled=${this.isLoading || this.isLoadingMessages} id="messageBox" rows="1"></textarea>
<iframe class="chat-editor" id="_chatEditorDOM" tabindex="-1"></iframe>
<button class="emoji-button" ?disabled=${this.isLoading || this.isLoadingMessages}>
@ -133,6 +138,113 @@ class ChatPage extends LitElement {
`
}
firstUpdated() {
// TODO: Load and fetch messages from localstorage (maybe save messages to localstorage...)
this.emojiPickerHandler = this.shadowRoot.querySelector('.emoji-button');
this.mirrorChatInput = this.shadowRoot.getElementById('messageBox');
this.chatMessageInput = this.shadowRoot.getElementById('_chatEditorDOM');
document.addEventListener('keydown', (e) => {
if (!this.chatEditor.content.body.matches(':focus')) {
// WARNING: Deprecated methods from KeyBoard Event
if (e.code === "Space" || e.keyCode === 32 || e.which === 32) {
this.chatEditor.insertText('&nbsp;');
} else if (inputKeyCodes.includes(e.keyCode)) {
this.chatEditor.insertText(e.key);
return this.chatEditor.focus();
} else {
return this.chatEditor.focus();
}
};
});
// Init EmojiPicker
this.emojiPicker = new EmojiPicker({
style: "twemoji",
twemojiBaseUrl: '/emoji/',
showPreview: false,
showVariants: false,
showAnimation: false,
position: 'top-start',
boxShadow: 'rgba(4, 4, 5, 0.15) 0px 0px 0px 1px, rgba(0, 0, 0, 0.24) 0px 8px 16px 0px'
});
this.emojiPicker.on('emoji', selection => {
const emojiHtmlString = `<img class="emoji" draggable="false" alt="${selection.emoji}" src="${selection.url}">`;
this.chatEditor.insertEmoji(emojiHtmlString);
});
// Attach Event Handler
this.emojiPickerHandler.addEventListener('click', () => this.emojiPicker.togglePicker(this.emojiPickerHandler));
const getAddressPublicKey = () => {
parentEpml.request('apiCall', {
type: 'api',
url: `/addresses/publickey/${this._chatId}`
}).then(res => {
if (res.error === 102) {
this._publicKey.key = ''
this._publicKey.hasPubKey = false
this.fetchChatMessages(this._chatId)
} else if (res !== false) {
this._publicKey.key = res
this._publicKey.hasPubKey = true
this.fetchChatMessages(this._chatId)
} else {
this._publicKey.key = ''
this._publicKey.hasPubKey = false
this.fetchChatMessages(this._chatId)
}
})
};
setTimeout(() => {
this.chatId.includes('direct') === true ? this.isReceipient = true : this.isReceipient = false;
this._chatId = this.chatId.split('/')[1];
const placeholder = this.isReceipient === true ? `Message ${this._chatId}` : 'Message...';
this.chatEditorPlaceholder = placeholder;
this.isReceipient ? getAddressPublicKey() : this.fetchChatMessages(this._chatId);
// Init ChatEditor
this.initChatEditor();
}, 100)
parentEpml.ready().then(() => {
parentEpml.subscribe('selected_address', async selectedAddress => {
this.selectedAddress = {}
selectedAddress = JSON.parse(selectedAddress)
if (!selectedAddress || Object.entries(selectedAddress).length === 0) return
this.selectedAddress = selectedAddress
})
parentEpml.request('apiCall', {
url: `/addresses/balance/${window.parent.reduxStore.getState().app.selectedAddress.address}`
}).then(res => {
this.balance = res
})
parentEpml.subscribe('frame_paste_menu_switch', async res => {
res = JSON.parse(res)
if (res.isOpen === false && this.isPasteMenuOpen === true) {
this.pasteToTextBox(textarea)
this.isPasteMenuOpen = false
}
})
})
parentEpml.imReady();
}
updated(changedProps) {
}
renderChatScroller(initialMessages) {
return html`<chat-scroller .initialMessages=${initialMessages} .emojiPicker=${this.emojiPicker} .escapeHTML=${escape} .getOldMessage=${this.getOldMessage} > </chat-scroller>`
@ -204,8 +316,6 @@ class ChatPage extends LitElement {
this.newMessages = this.newMessages.concat(_newMessages)
}
}
/**
@ -574,112 +684,6 @@ class ChatPage extends LitElement {
observer.observe(downObserver)
}
firstUpdated() {
// TODO: Load and fetch messages from localstorage (maybe save messages to localstorage...)
this.emojiPickerHandler = this.shadowRoot.querySelector('.emoji-button');
this.mirrorChatInput = this.shadowRoot.getElementById('messageBox');
this.chatMessageInput = this.shadowRoot.getElementById('_chatEditorDOM');
document.addEventListener('keydown', (e) => {
if (!this.chatEditor.content.body.matches(':focus')) {
// WARNING: Deprecated methods from KeyBoard Event
if (e.code === "Space" || e.keyCode === 32 || e.which === 32) {
this.chatEditor.insertText('&nbsp;');
} else if (inputKeyCodes.includes(e.keyCode)) {
this.chatEditor.insertText(e.key);
return this.chatEditor.focus();
} else {
return this.chatEditor.focus();
}
};
});
// Init EmojiPicker
this.emojiPicker = new EmojiPicker({
style: "twemoji",
twemojiBaseUrl: '/emoji/',
showPreview: false,
showVariants: false,
showAnimation: false,
position: 'top-start',
boxShadow: 'rgba(4, 4, 5, 0.15) 0px 0px 0px 1px, rgba(0, 0, 0, 0.24) 0px 8px 16px 0px'
});
this.emojiPicker.on('emoji', selection => {
const emojiHtmlString = `<img class="emoji" draggable="false" alt="${selection.emoji}" src="${selection.url}">`;
this.chatEditor.insertEmoji(emojiHtmlString);
});
// Attach Event Handler
this.emojiPickerHandler.addEventListener('click', () => this.emojiPicker.togglePicker(this.emojiPickerHandler));
const getAddressPublicKey = () => {
parentEpml.request('apiCall', {
type: 'api',
url: `/addresses/publickey/${this._chatId}`
}).then(res => {
if (res.error === 102) {
this._publicKey.key = ''
this._publicKey.hasPubKey = false
this.fetchChatMessages(this._chatId)
} else if (res !== false) {
this._publicKey.key = res
this._publicKey.hasPubKey = true
this.fetchChatMessages(this._chatId)
} else {
this._publicKey.key = ''
this._publicKey.hasPubKey = false
this.fetchChatMessages(this._chatId)
}
})
};
setTimeout(() => {
this.chatId.includes('direct') === true ? this.isReceipient = true : this.isReceipient = false;
this._chatId = this.chatId.split('/')[1];
const placeholder = this.isReceipient === true ? `Message ${this._chatId}` : 'Message...';
this.chatEditorPlaceholder = placeholder;
this.isReceipient ? getAddressPublicKey() : this.fetchChatMessages(this._chatId);
// Init ChatEditor
this.initChatEditor();
}, 100)
parentEpml.ready().then(() => {
parentEpml.subscribe('selected_address', async selectedAddress => {
this.selectedAddress = {}
selectedAddress = JSON.parse(selectedAddress)
if (!selectedAddress || Object.entries(selectedAddress).length === 0) return
this.selectedAddress = selectedAddress
})
parentEpml.request('apiCall', {
url: `/addresses/balance/${window.parent.reduxStore.getState().app.selectedAddress.address}`
}).then(res => {
this.balance = res
})
parentEpml.subscribe('frame_paste_menu_switch', async res => {
res = JSON.parse(res)
if (res.isOpen === false && this.isPasteMenuOpen === true) {
this.pasteToTextBox(textarea)
this.isPasteMenuOpen = false
}
})
})
parentEpml.imReady();
}
pasteToTextBox(textarea) {
// Return focus to the window

View File

@ -43,6 +43,7 @@ class ChatScroller extends LitElement {
margin: 0;
padding: 20px;
}
.chat-list {
overflow-y: auto;
height: 91vh;
@ -53,6 +54,10 @@ class ChatScroller extends LitElement {
margin-bottom: 15px;
}
.message-data-name {
color: var(--black);
}
.message-data-time {
color: #a8aab1;
font-size: 13px;

View File

@ -18,12 +18,24 @@ class ChatWelcomePage extends LitElement {
messages: { type: Array },
btnDisable: { type: Boolean },
isLoading: { type: Boolean },
balance: { type: Number }
balance: { type: Number },
theme: { type: String, reflect: true }
}
}
static get styles() {
return css`
* {
--mdc-theme-primary: rgb(3, 169, 244);
--paper-input-container-focus-color: var(--mdc-theme-primary);
--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);
}
@keyframes moveInBottom {
0% {
opacity: 0;
@ -47,7 +59,7 @@ class ChatWelcomePage extends LitElement {
display: block;
overflow: hidden;
font-size: 40px;
color: black;
color: var(--black);
font-weight: 400;
text-align: center;
white-space: pre-wrap;
@ -72,6 +84,7 @@ class ChatWelcomePage extends LitElement {
.img-icon {
font-size: 150px;
color: var(--black);
}
.start-chat {
@ -83,8 +96,8 @@ class ChatWelcomePage extends LitElement {
border-radius: 20px;
padding-left: 25px;
padding-right: 25px;
color: white;
background: #6a6c75;
color: var(--white);
background: var(--tradehead);
width: 50%;
font-size: 17px;
cursor: pointer;
@ -125,7 +138,7 @@ class ChatWelcomePage extends LitElement {
}
h2, h3, h4, h5 {
color:#333;
color:# var(--black);
font-weight: 400;
}
@ -179,6 +192,7 @@ class ChatWelcomePage extends LitElement {
this.messages = []
this.btnDisable = false
this.isLoading = false
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
@ -191,7 +205,7 @@ class ChatWelcomePage extends LitElement {
<div class="sub-main">
<div class="center-box">
<mwc-icon class="img-icon">chat</mwc-icon><br>
<span style="font-size: 20px;">${this.myAddress.address}</span>
<span style="font-size: 20px; color: var(--black);">${this.myAddress.address}</span>
<div class="start-chat" @click=${() => this.shadowRoot.querySelector('#startSecondChatDialog').show()}>New Private Message</div>
</div>
</div>
@ -224,6 +238,11 @@ class ChatWelcomePage extends LitElement {
}
firstUpdated() {
setInterval(() => {
this.changeTheme();
}, 250)
const stopKeyEventPropagation = (e) => {
e.stopPropagation();
return false;
@ -260,6 +279,16 @@ class ChatWelcomePage extends LitElement {
parentEpml.imReady()
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') {
this.theme = 'dark';
} else {
this.theme = 'light';
}
document.querySelector('html').setAttribute('theme', this.theme);
}
_sendMessage() {
this.isLoading = true

View File

@ -29,7 +29,8 @@ class GroupManagement extends LitElement {
error: { type: Boolean },
message: { type: String },
removeError: { type: Boolean },
removeMessage: { type: String }
removeMessage: { type: String },
theme: { type: String, reflect: true }
}
}
@ -42,10 +43,16 @@ class GroupManagement extends LitElement {
--lumo-primary-color-50pct: rgba(0, 167, 245, 0.5);
--lumo-primary-color-10pct: rgba(0, 167, 245, 0.1);
--lumo-primary-color: hsl(199, 100%, 48%);
--lumo-base-color: var(--white);
--lumo-body-text-color: var(--black);
--lumo-secondary-text-color: var(--sectxt);
--lumo-contrast-60pct: var(--vdicon);
--_lumo-grid-border-color: var(--border);
--_lumo-grid-secondary-border-color: var(--border2);
}
#group-management-page {
background: #fff;
background: var(--white);
padding: 12px 24px;
}
@ -79,7 +86,7 @@ class GroupManagement extends LitElement {
}
h2, h3, h4, h5 {
color:#333;
color: var(--black);
font-weight: 400;
}
@ -133,12 +140,13 @@ class GroupManagement extends LitElement {
this.createFee = 0.001
this.joinFee = 0.001
this.leaveFee = 0.001
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
return html`
<div id="group-management-page">
<div style="min-height:48px; display: flex; padding-bottom: 6px; margin: 2px;">
<div style="min-height: 48px; display: flex; padding-bottom: 6px; margin: 2px;">
<h2 style="margin: 0; flex: 1; padding-top: .1em; display: inline;">Qortal Groups</h2>
<mwc-button style="float:right;" @click=${() => this.shadowRoot.querySelector('#createGroupDialog').show()}><mwc-icon>add</mwc-icon>Create Group</mwc-button>
</div>
@ -156,7 +164,7 @@ class GroupManagement extends LitElement {
}}></vaadin-grid-column>
</vaadin-grid>
${this.isEmptyArray(this.joinedGroups) ? html`
Not a member of any groups!
<span style="color: var(--black);">Not a member of any groups!</span>
`: ''}
</div>
@ -171,7 +179,7 @@ class GroupManagement extends LitElement {
}}></vaadin-grid-column>
</vaadin-grid>
${this.isEmptyArray(this.publicGroups) ? html`
No Open Public Groups available!
<span style="color: var(--black);">No Open Public Groups available!</span>
`: ''}
</div>
@ -182,7 +190,7 @@ class GroupManagement extends LitElement {
<hr>
</div>
<mwc-textfield style="width:100%;" ?disabled="${this.isLoading}" label="Group Name" id="groupNameInput"></mwc-textfield>
<mwc-textfield style="width: 100%;" ?disabled="${this.isLoading}" label="Group Name" id="groupNameInput"></mwc-textfield>
<p style="margin-bottom:0;">
<mwc-textfield style="width:100%;" ?disabled="${this.isLoading}" label="Description" id="groupDescInput"></mwc-textfield>
</p>
@ -420,6 +428,11 @@ class GroupManagement extends LitElement {
}
firstUpdated() {
setInterval(() => {
this.changeTheme();
}, 100)
this.unitCreateFee()
this.unitJoinFee()
this.unitLeaveFee()
@ -491,6 +504,16 @@ class GroupManagement extends LitElement {
parentEpml.imReady()
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') {
this.theme = 'dark';
} else {
this.theme = 'light';
}
document.querySelector('html').setAttribute('theme', this.theme);
}
async unitCreateFee() {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node];
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port;

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="/font/material-icons.css">
<link rel="stylesheet" href="/font/switch-theme.css">
<style>
html {
--scrollbarBG: #a1a1a1;
@ -32,7 +33,7 @@
body {
margin: 0;
font-family: "Roboto", sans-serif;
background-color: #fff;
background: var(--plugback);
}
</style>
</head>

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="/font/material-icons.css">
<link rel="stylesheet" href="/font/switch-theme.css">
<style>
html {
--scrollbarBG: #a1a1a1;
@ -32,7 +33,7 @@
body {
margin: 0;
font-family: "Roboto", sans-serif;
background-color: #fff;
background: var(--plugback);
}
</style>
</head>

View File

@ -5,16 +5,26 @@ const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
class Messaging extends LitElement {
static get properties() {
return {}
return {
theme: { type: String, reflect: true }
}
}
static get styles() {
return css`
* {
--mdc-theme-primary: rgb(3, 169, 244);
--paper-input-container-focus-color: var(--mdc-theme-primary);
--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);
}
#page {
background: #fff;
background: var(--white);
padding: 12px 24px;
}
@ -24,7 +34,7 @@ class Messaging extends LitElement {
}
h3, h4, h5 {
color:#333;
color: var(--black);
font-weight: 400;
}
@ -64,17 +74,18 @@ class Messaging extends LitElement {
}
p {
color:#333;
color: var(--black);
}
ul, ul li {
color:#333;
color: var(--black);
}
`
}
constructor() {
super()
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
@ -95,8 +106,6 @@ class Messaging extends LitElement {
These messages <strong>are able</strong> to be <strong>sent to groups or individual accounts</strong>, and are essentially <strong>the 'e-mail' of Qortal</strong>.
Use these messages if you intend on the message being a <strong>PERMANENT message</strong> that stays when and where you send it.</p>
<!-- <span style="display: block; text-align: center"><strong>- more info -</strong></span> -->
<ul>
<li style="font-size: 17px; padding: 10px;">There are no @ in Qortal Chain Messaging, only 'registered names'. As the registered names on the chain can only be registered ONCE. Therefore, there are NO DUPLICATES.</li>
<li style="font-size: 17px; padding: 10px;">Chain Messages LAST FOREVER</li>
@ -125,18 +134,12 @@ class Messaging extends LitElement {
`
}
getUrl(pageId) {
this.onPageNavigation(`/app/${pageId}`)
}
onPageNavigation(pageUrl) {
parentEpml.request('setPageUrl', pageUrl)
}
firstUpdated() {
setInterval(() => {
this.changeTheme();
}, 100)
window.addEventListener("contextmenu", (event) => {
event.preventDefault();
@ -178,11 +181,27 @@ class Messaging extends LitElement {
}
})
})
parentEpml.imReady()
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') {
this.theme = 'dark';
} else {
this.theme = 'light';
}
document.querySelector('html').setAttribute('theme', this.theme);
}
getUrl(pageId) {
this.onPageNavigation(`/app/${pageId}`)
}
onPageNavigation(pageUrl) {
parentEpml.request('setPageUrl', pageUrl)
}
_textMenu(event) {
const getSelectedText = () => {

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="/font/material-icons.css">
<link rel="stylesheet" href="/font/switch-theme.css">
<style>
html {
--scrollbarBG: #a1a1a1;
@ -32,7 +33,7 @@
body {
margin: 0;
font-family: "Roboto", sans-serif;
background-color: #fff;
background: var(--plugback);
overflow: hidden;
}
</style>

View File

@ -23,16 +23,22 @@ class Chat extends LitElement {
messages: { type: Array },
btnDisable: { type: Boolean },
isLoading: { type: Boolean },
balance: { type: Number }
balance: { type: Number },
theme: { type: String, reflect: true }
}
}
static get styles() {
return css`
* {
--mdc-theme-primary: rgb(3, 169, 244);
--paper-input-container-focus-color: var(--mdc-theme-primary);
--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);
}
paper-spinner-lite{
@ -56,7 +62,7 @@ class Chat extends LitElement {
.container {
margin: 0 auto;
width: 100%;
background: #fff;
background: var(--white);
}
.people-list {
@ -76,8 +82,8 @@ class Chat extends LitElement {
border: none;
display: inline-block;
padding: 14px;
color: white;
background: #6a6c75;
color: var(--white);
background: var(--tradehead);
width: 90%;
font-size: 15px;
text-align: center;
@ -100,7 +106,7 @@ class Chat extends LitElement {
width: 80vw;
height: 100vh;
float: left;
background: #fff;
background: var(--white);
border-top-right-radius: 5px;
border-bottom-right-radius: 5px;
color: #434651;
@ -120,8 +126,8 @@ class Chat extends LitElement {
left: 20vw;
right: 0;
z-index: 5;
background: #6a6c75;
color: white;
background: var(--tradehead);
color: var(--white);
border-radius: 0 0 8px 8px;
min-height: 25px;
transition: opacity .15s;
@ -146,7 +152,7 @@ class Chat extends LitElement {
right: 0;
bottom: 100%;
left: 20vw;
border-bottom: 2px solid white;
border-bottom: 2px solid var(--white);
overflow-y: hidden;
height: 100vh;
box-sizing: border-box;
@ -202,6 +208,7 @@ class Chat extends LitElement {
clear: both;
height: 0;
}
.red {
--mdc-theme-primary: red;
}
@ -211,7 +218,7 @@ class Chat extends LitElement {
}
h2, h3, h4, h5 {
color:#333;
color: var(--black);
font-weight: 400;
}
@ -219,16 +226,19 @@ class Chat extends LitElement {
display: hidden !important;
visibility: none !important;
}
.details {
display: flex;
font-size: 18px;
}
.title {
font-weight:600;
font-size:12px;
line-height: 32px;
opacity: 0.66;
}
.input {
width: 100%;
border: none;
@ -239,6 +249,7 @@ class Chat extends LitElement {
resize: none;
background: #eee;
}
.textarea {
width: 100%;
border: none;
@ -271,17 +282,13 @@ class Chat extends LitElement {
this.messages = []
this.btnDisable = false
this.isLoading = false
this.showNewMesssageBar = this.showNewMesssageBar.bind(this)
this.hideNewMesssageBar = this.hideNewMesssageBar.bind(this)
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
return html`
<style>
</style>
<div class="container clearfix">
<div class="people-list" id="people-list">
<div class="search">
@ -336,63 +343,12 @@ class Chat extends LitElement {
`
}
renderChatWelcomePage() {
return html`<chat-welcome-page myAddress=${JSON.stringify(this.selectedAddress)}></chat-welcome-page>`
}
renderChatHead(chatHeadArr) {
let tempUrl = document.location.href
let splitedUrl = decodeURI(tempUrl).split('?')
let activeChatHeadUrl = splitedUrl[1] === undefined ? '' : splitedUrl[1]
return chatHeadArr.map(eachChatHead => {
return html`<chat-head activeChatHeadUrl=${activeChatHeadUrl} chatInfo=${JSON.stringify(eachChatHead)}></chat-head>`
})
}
renderChatPage(chatId) {
// Check for the chat ID from and render chat messages
// Else render Welcome to Q-CHat
// TODO: DONE: Do the above in the ChatPage
return html`<chat-page .hideNewMesssageBar=${this.hideNewMesssageBar} .showNewMesssageBar=${this.showNewMesssageBar} myAddress=${window.parent.reduxStore.getState().app.selectedAddress.address} chatId=${chatId}></chat-page>`
}
setChatHeads(chatObj) {
let groupList = chatObj.groups.map(group => group.groupId === 0 ? { groupId: group.groupId, url: `group/${group.groupId}`, groupName: "Qortal General Chat", timestamp: group.timestamp === undefined ? 2 : group.timestamp } : { ...group, timestamp: group.timestamp === undefined ? 1 : group.timestamp, url: `group/${group.groupId}` })
let directList = chatObj.direct.map(dc => {
return { ...dc, url: `direct/${dc.address}` }
})
const compareNames = (a, b) => {
return a.groupName.localeCompare(b.groupName)
}
groupList.sort(compareNames)
let chatHeadMasterList = [...groupList, ...directList]
const compareArgs = (a, b) => {
return b.timestamp - a.timestamp
}
this.chatHeads = chatHeadMasterList.sort(compareArgs)
}
getChatHeadFromState(chatObj) {
if (chatObj === undefined) {
return
} else {
this.chatHeadsObj = chatObj
this.setChatHeads(chatObj)
}
}
firstUpdated() {
setInterval(() => {
this.changeTheme();
}, 250)
const stopKeyEventPropagation = (e) => {
e.stopPropagation();
return false;
@ -455,6 +411,7 @@ class Chat extends LitElement {
}
let configLoaded = false
parentEpml.ready().then(() => {
parentEpml.subscribe('selected_address', async selectedAddress => {
this.selectedAddress = {}
@ -485,10 +442,73 @@ class Chat extends LitElement {
}
})
})
parentEpml.imReady()
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') {
this.theme = 'dark';
} else {
this.theme = 'light';
}
document.querySelector('html').setAttribute('theme', this.theme);
}
renderChatWelcomePage() {
return html`<chat-welcome-page myAddress=${JSON.stringify(this.selectedAddress)}></chat-welcome-page>`
}
renderChatHead(chatHeadArr) {
let tempUrl = document.location.href
let splitedUrl = decodeURI(tempUrl).split('?')
let activeChatHeadUrl = splitedUrl[1] === undefined ? '' : splitedUrl[1]
return chatHeadArr.map(eachChatHead => {
return html`<chat-head activeChatHeadUrl=${activeChatHeadUrl} chatInfo=${JSON.stringify(eachChatHead)}></chat-head>`
})
}
renderChatPage(chatId) {
// Check for the chat ID from and render chat messages
// Else render Welcome to Q-CHat
// TODO: DONE: Do the above in the ChatPage
return html`<chat-page .hideNewMesssageBar=${this.hideNewMesssageBar} .showNewMesssageBar=${this.showNewMesssageBar} myAddress=${window.parent.reduxStore.getState().app.selectedAddress.address} chatId=${chatId}></chat-page>`
}
setChatHeads(chatObj) {
let groupList = chatObj.groups.map(group => group.groupId === 0 ? { groupId: group.groupId, url: `group/${group.groupId}`, groupName: "Qortal General Chat", timestamp: group.timestamp === undefined ? 2 : group.timestamp } : { ...group, timestamp: group.timestamp === undefined ? 1 : group.timestamp, url: `group/${group.groupId}` })
let directList = chatObj.direct.map(dc => {
return { ...dc, url: `direct/${dc.address}` }
})
const compareNames = (a, b) => {
return a.groupName.localeCompare(b.groupName)
}
groupList.sort(compareNames)
let chatHeadMasterList = [...groupList, ...directList]
const compareArgs = (a, b) => {
return b.timestamp - a.timestamp
}
this.chatHeads = chatHeadMasterList.sort(compareArgs)
}
getChatHeadFromState(chatObj) {
if (chatObj === undefined) {
return
} else {
this.chatHeadsObj = chatObj
this.setChatHeads(chatObj)
}
}
_sendMessage() {
this.isLoading = true

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="/font/material-icons.css">
<link rel="stylesheet" href="/font/switch-theme.css">
<style>
html {
--scrollbarBG: #a1a1a1;
@ -32,7 +33,7 @@
body {
margin: 0;
font-family: "Roboto", sans-serif;
background-color: #fff;
background: var(--plugback);
}
</style>
</head>

View File

@ -18,7 +18,8 @@ class MintingInfo extends LitElement {
nodeInfo: { type: Array },
sampleBlock: { type: Array },
addressInfo: { type: Array },
addressLevel: { type: Array }
addressLevel: { type: Array },
theme: { type: String, reflect: true }
}
}
@ -45,14 +46,14 @@ class MintingInfo extends LitElement {
font-weight:600;
font-size:20px;
line-height: 28px;
color:#000000;
color: var(--black);
}
.header-title {
display: block;
overflow: hidden;
font-size: 40px;
color: black;
color: var(--black);
font-weight: 400;
text-align: center;
white-space: pre-wrap;
@ -64,7 +65,7 @@ class MintingInfo extends LitElement {
.level-black {
font-size: 32px;
color: black;
color: var(--black);
font-weight: 400;
text-align: center;
margin-top: 2rem;
@ -165,7 +166,7 @@ class MintingInfo extends LitElement {
}
.black {
color: #000000;
color: var(--black);
}
.red {
@ -192,6 +193,7 @@ class MintingInfo extends LitElement {
this.sampleBlock = [];
this.addressInfo = [];
this.addressLevel = [];
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light';
}
render() {
@ -238,10 +240,10 @@ class MintingInfo extends LitElement {
</div>
<div>
<h3>Introduction</h3><br />
To "activate" your account, an OUTGOING transaction needs to take place.
Name Registration is the most common method. You can ask someone in Q-Chat to send you a small amount of QORT so that you may activate your account,
or buy QORT within the Trade Portal then make an OUTGOING transaction of any kind and secure your public key on the blockchain.
Until you do this, your public key is only known by you, in your UI, and no one else can pull your public key from the chain.
To "activate" your account, an OUTGOING transaction needs to take place.
Name Registration is the most common method. You can ask someone in Q-Chat to send you a small amount of QORT so that you may activate your account,
or buy QORT within the Trade Portal then make an OUTGOING transaction of any kind and secure your public key on the blockchain.
Until you do this, your public key is only known by you, in your UI, and no one else can pull your public key from the chain.
</div>
<mwc-button slot="primaryAction" dialogAction="cancel" class="red-button">Close</mwc-button>
</mwc-dialog>
@ -355,6 +357,11 @@ class MintingInfo extends LitElement {
}
firstUpdated() {
setInterval(() => {
this.changeTheme();
}, 100)
const getAdminInfo = () => {
parentEpml.request("apiCall", { url: `/admin/info` }).then((res) => {
setTimeout(() => { this.adminInfo = res; }, 1);
@ -422,6 +429,16 @@ class MintingInfo extends LitElement {
parentEpml.imReady();
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') {
this.theme = 'dark';
} else {
this.theme = 'light';
}
document.querySelector('html').setAttribute('theme', this.theme);
}
renderMintingPage() {
if (this.addressInfo.error === 124) {
return "false"

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="/font/material-icons.css">
<link rel="stylesheet" href="/font/switch-theme.css">
<style>
html {
--scrollbarBG: #a1a1a1;
@ -32,7 +33,7 @@
body {
margin: 0;
font-family: "Roboto", sans-serif;
background-color: #fff;
background: var(--plugback);
}
</style>
</head>

View File

@ -23,7 +23,8 @@ class NameRegistration extends LitElement {
error: { type: Boolean },
message: { type: String },
removeError: { type: Boolean },
removeMessage: { type: String }
removeMessage: { type: String },
theme: { type: String, reflect: true }
}
}
@ -37,9 +38,14 @@ class NameRegistration extends LitElement {
--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-grid-border-color: var(--border);
--_lumo-grid-secondary-border-color: var(--border2);
}
#name-registration-page {
background: #fff;
background: var(--white);
padding: 12px 24px;
}
@ -54,7 +60,7 @@ class NameRegistration extends LitElement {
}
h2, h3, h4, h5 {
color:#333;
color: var(--black);
font-weight: 400;
}
@ -79,6 +85,7 @@ class NameRegistration extends LitElement {
this.btnDisable = false
this.registerNameLoading = false
this.fee = 0.001
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
@ -102,7 +109,7 @@ class NameRegistration extends LitElement {
}}></vaadin-grid-column>
</vaadin-grid>
${this.isEmptyArray(this.names) ? html`
No names registered by this account!
<span style="color: var(--black);">No names registered by this account!</span>
`: ''}
</div>
@ -151,6 +158,11 @@ class NameRegistration extends LitElement {
}
firstUpdated() {
setInterval(() => {
this.changeTheme();
}, 100)
this.unitFee();
window.addEventListener("contextmenu", (event) => {
@ -202,6 +214,16 @@ class NameRegistration extends LitElement {
parentEpml.imReady()
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') {
this.theme = 'dark';
} else {
this.theme = 'light';
}
document.querySelector('html').setAttribute('theme', this.theme);
}
renderAvatar(nameObj) {
let name = nameObj.name
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="/font/material-icons.css">
<link rel="stylesheet" href="/font/switch-theme.css">
<style>
html {
--scrollbarBG: #a1a1a1;
@ -32,7 +33,7 @@
body {
margin: 0;
font-family: "Roboto", sans-serif;
background-color: #fff;
background: var(--plugback);
}
</style>
</head>

View File

@ -7,8 +7,7 @@ import '@material/mwc-icon'
import '@material/mwc-textfield'
import '@material/mwc-button'
import '@material/mwc-dialog'
import '@vaadin/grid/vaadin-grid.js'
import '@vaadin/grid/theme/material/all-imports.js'
import '@vaadin/grid'
const parentEpml = new Epml({ type: "WINDOW", source: window.parent })
@ -31,7 +30,8 @@ class NodeManagement extends LitElement {
removeMintingAccountMessage: { type: String },
tempMintingAccount: { type: Object },
nodeConfig: { type: Object },
nodeDomain: { type: String }
nodeDomain: { type: String },
theme: { type: String, reflect: true }
};
}
@ -44,6 +44,12 @@ class NodeManagement extends LitElement {
--lumo-primary-color-50pct: rgba(0, 167, 245, 0.5);
--lumo-primary-color-10pct: rgba(0, 167, 245, 0.1);
--lumo-primary-color: hsl(199, 100%, 48%);
--lumo-base-color: var(--white);
--lumo-body-text-color: var(--black);
--lumo-secondary-text-color: var(--sectxt);
--lumo-contrast-60pct: var(--vdicon);
--_lumo-grid-border-color: var(--border);
--_lumo-grid-secondary-border-color: var(--border2);
}
paper-spinner-lite {
@ -54,7 +60,7 @@ class NodeManagement extends LitElement {
}
#node-management-page {
background: #fff;
background: var(--white);
}
mwc-textfield {
@ -77,7 +83,7 @@ class NodeManagement extends LitElement {
.node-card {
padding: 12px 24px;
background: #fff;
background: var(--white);
border-radius: 2px;
box-shadow: 11;
}
@ -90,10 +96,14 @@ class NodeManagement extends LitElement {
h3,
h4,
h5 {
color: #333;
color: var(--black);
font-weight: 400;
}
.sblack {
color: var(--black);
}
[hidden] {
display: hidden !important;
visibility: none !important;
@ -127,6 +137,7 @@ class NodeManagement extends LitElement {
};
this.nodeConfig = {};
this.nodeDomain = "";
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light';
}
render() {
@ -134,7 +145,7 @@ class NodeManagement extends LitElement {
<div id="node-management-page">
<div class="node-card">
<h2>Node management for: ${this.nodeDomain}</h2>
<span><br />Node has been online for: ${this.upTime}</span>
<span class="sblack"><br />Node has been online for: ${this.upTime}</span>
<br /><br />
<div id="minting">
@ -212,8 +223,7 @@ class NodeManagement extends LitElement {
render(html`<mwc-button class="red" ?disabled=${this.removeMintingAccountLoading} @click=${() => this.removeMintingAccount(data.item.publicKey)}><mwc-icon>create</mwc-icon>Remove</mwc-button>`, root)
}}></vaadin-grid-column>
</vaadin-grid>
${this.isEmptyArray(this.mintingAccounts) ? html` No minting accounts found for this node ` : ""}
${this.isEmptyArray(this.mintingAccounts) ? html`<span style="color: var(--black);">No minting accounts found for this node</span>` : ""}
</div>
<br />
@ -267,7 +277,7 @@ class NodeManagement extends LitElement {
}}></vaadin-grid-column>
</vaadin-grid>
${this.isEmptyArray(this.peers) ? html` Node has no connected peers ` : ""}
${this.isEmptyArray(this.peers) ? html`<span style="color: var(--black);">Node has no connected peers</span>` : ""}
</div>
<br />
</div>
@ -275,6 +285,113 @@ class NodeManagement extends LitElement {
`;
}
firstUpdated() {
setInterval(() => {
this.changeTheme();
}, 100)
// Call updateMintingAccounts
this.updateMintingAccounts();
window.addEventListener("contextmenu", (event) => {
event.preventDefault();
this._textMenu(event)
});
window.addEventListener("click", () => {
parentEpml.request('closeCopyTextMenu', null)
});
window.onkeyup = (e) => {
if (e.keyCode === 27) parentEpml.request('closeCopyTextMenu', null)
}
// Calculate HH MM SS from Milliseconds...
const convertMsToTime = (milliseconds) => {
let day, hour, minute, seconds;
seconds = Math.floor(milliseconds / 1000);
minute = Math.floor(seconds / 60);
seconds = seconds % 60;
hour = Math.floor(minute / 60);
minute = minute % 60;
day = Math.floor(hour / 24);
hour = hour % 24;
if (isNaN(day)) {
return "offline";
}
return day + "d " + hour + "h " + minute + "m";
};
const getNodeUpTime = () => {
parentEpml
.request("apiCall", {
url: `/admin/uptime`,
})
.then((res) => {
this.upTime = "";
setTimeout(() => {
this.upTime = convertMsToTime(res);
}, 1);
});
setTimeout(getNodeUpTime, this.config.user.nodeSettings.pingInterval);
};
const updatePeers = () => {
parentEpml
.request("apiCall", {
url: `/peers`,
})
.then((res) => {
setTimeout(() => {
this.peers = res;
}, 1);
});
setTimeout(updatePeers, this.config.user.nodeSettings.pingInterval);
};
const getNodeConfig = () => {
parentEpml.request("getNodeConfig").then((res) => {
setTimeout(() => {
this.nodeConfig = res;
}, 1);
let myNode = window.parent.reduxStore.getState().app.nodeConfig
.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node];
this.nodeDomain = myNode.domain + ":" + myNode.port;
});
setTimeout(getNodeConfig, 1000);
};
let configLoaded = false;
parentEpml.ready().then(() => {
parentEpml.subscribe("config", async c => {
if (!configLoaded) {
setTimeout(getNodeUpTime, 1);
setTimeout(updatePeers, 1);
setTimeout(this.updateMintingAccounts, 1);
setTimeout(getNodeConfig, 1);
configLoaded = true;
}
this.config = JSON.parse(c);
})
parentEpml.subscribe('copy_menu_switch', async value => {
if (value === 'false' && window.getSelection().toString().length !== 0) this.clearSelection();
})
});
parentEpml.imReady();
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') {
this.theme = 'dark';
} else {
this.theme = 'light';
}
document.querySelector('html').setAttribute('theme', this.theme);
}
forceSyncPeer(peerAddress, rowIndex) {
parentEpml
.request("apiCall", {
@ -403,99 +520,6 @@ class NodeManagement extends LitElement {
});
}
firstUpdated() {
// Call updateMintingAccounts
this.updateMintingAccounts();
window.addEventListener("contextmenu", (event) => {
event.preventDefault();
this._textMenu(event)
});
window.addEventListener("click", () => {
parentEpml.request('closeCopyTextMenu', null)
});
window.onkeyup = (e) => {
if (e.keyCode === 27) parentEpml.request('closeCopyTextMenu', null)
}
// Calculate HH MM SS from Milliseconds...
const convertMsToTime = (milliseconds) => {
let day, hour, minute, seconds;
seconds = Math.floor(milliseconds / 1000);
minute = Math.floor(seconds / 60);
seconds = seconds % 60;
hour = Math.floor(minute / 60);
minute = minute % 60;
day = Math.floor(hour / 24);
hour = hour % 24;
if (isNaN(day)) {
return "offline";
}
return day + "d " + hour + "h " + minute + "m";
};
const getNodeUpTime = () => {
parentEpml
.request("apiCall", {
url: `/admin/uptime`,
})
.then((res) => {
this.upTime = "";
setTimeout(() => {
this.upTime = convertMsToTime(res);
}, 1);
});
setTimeout(getNodeUpTime, this.config.user.nodeSettings.pingInterval);
};
const updatePeers = () => {
parentEpml
.request("apiCall", {
url: `/peers`,
})
.then((res) => {
setTimeout(() => {
this.peers = res;
}, 1);
});
setTimeout(updatePeers, this.config.user.nodeSettings.pingInterval);
};
const getNodeConfig = () => {
parentEpml.request("getNodeConfig").then((res) => {
setTimeout(() => {
this.nodeConfig = res;
}, 1);
let myNode = window.parent.reduxStore.getState().app.nodeConfig
.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node];
this.nodeDomain = myNode.domain + ":" + myNode.port;
});
setTimeout(getNodeConfig, 1000);
};
let configLoaded = false;
parentEpml.ready().then(() => {
parentEpml.subscribe("config", async c => {
if (!configLoaded) {
setTimeout(getNodeUpTime, 1);
setTimeout(updatePeers, 1);
setTimeout(this.updateMintingAccounts, 1);
setTimeout(getNodeConfig, 1);
configLoaded = true;
}
this.config = JSON.parse(c);
})
parentEpml.subscribe('copy_menu_switch', async value => {
if (value === 'false' && window.getSelection().toString().length !== 0) this.clearSelection();
})
});
parentEpml.imReady();
}
getApiKey() {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node];
let apiKey = myNode.apiKey;

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="/font/material-icons.css">
<link rel="stylesheet" href="/font/switch-theme.css">
<style>
html {
--scrollbarBG: #a1a1a1;
@ -32,7 +33,7 @@
body {
margin: 0;
font-family: "Roboto", sans-serif;
background-color: #fff;
background: var(--plugback);
}
</style>
</head>

View File

@ -29,7 +29,8 @@ class Puzzles extends LitElement {
selectedAddress: { type: Object },
selectedPuzzle: { type: Object },
error: { type: Boolean },
message: { type: String }
message: { type: String },
theme: { type: String, reflect: true }
}
}
@ -43,9 +44,16 @@ class Puzzles extends LitElement {
--lumo-primary-color-50pct: rgba(0, 167, 245, 0.5);
--lumo-primary-color-10pct: rgba(0, 167, 245, 0.1);
--lumo-primary-color: hsl(199, 100%, 48%);
--lumo-base-color: var(--white);
--lumo-body-text-color: var(--black);
--lumo-secondary-text-color: var(--sectxt);
--lumo-contrast-60pct: var(--vdicon);
--_lumo-grid-border-color: var(--border);
--_lumo-grid-secondary-border-color: var(--border2);
}
#puzzle-page {
background: #fff;
background: var(--white);
padding: 12px 24px;
}
@ -54,7 +62,7 @@ class Puzzles extends LitElement {
}
h2, h3, h4, h5 {
color:#333;
color: var(--black);
font-weight: 400;
}
@ -66,6 +74,13 @@ class Puzzles extends LitElement {
font-family: "Lucida Console", "Courier New", monospace;
font-size: smaller;
}
.divCard {
border: 1px solid #eee;
padding: 1em;
box-shadow: 0 .3px 1px 0 rgba(0,0,0,0.14), 0 1px 1px -1px rgba(0,0,0,0.12), 0 1px 2px 0 rgba(0,0,0,0.20);
margin-bottom: 2em;
}
`
}
@ -79,6 +94,7 @@ class Puzzles extends LitElement {
this.selectedPuzzle = {}
this.error = false
this.message = ''
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
@ -154,6 +170,11 @@ class Puzzles extends LitElement {
}
firstUpdated() {
setInterval(() => {
this.changeTheme();
}, 100)
window.addEventListener("contextmenu", (event) => {
event.preventDefault();
this._textMenu(event)
@ -342,6 +363,16 @@ class Puzzles extends LitElement {
})
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') {
this.theme = 'dark';
} else {
this.theme = 'light';
}
document.querySelector('html').setAttribute('theme', this.theme);
}
async guessPuzzle(puzzle) {
this.selectedPuzzle = puzzle
this.shadowRoot.getElementById("puzzleGuess").value = ''

View File

@ -19,7 +19,8 @@ class WebBrowser extends LitElement {
service: { type: String },
identifier: { type: String },
followedNames: { type: Array },
blockedNames: { type: Array }
blockedNames: { type: Array },
theme: { type: String, reflect: true }
}
}
@ -49,7 +50,7 @@ class WebBrowser extends LitElement {
left: 0;
right: 0;
height: 100px;
background-color: white;
background-color: var(--white);
height: 36px;
}
@ -63,7 +64,7 @@ class WebBrowser extends LitElement {
left: 0;
right: 0;
bottom: 0;
border-top: 1px solid #000000;
border-top: 1px solid var(--black);
}
.iframe-container iframe {
@ -71,7 +72,7 @@ class WebBrowser extends LitElement {
width: 100%;
height: 100%;
border: none;
background-color: #ffffff;
background-color: var(--white);
}
input[type=text] {
@ -80,7 +81,7 @@ class WebBrowser extends LitElement {
border: 0;
height: 34px;
font-size: 16px;
background-color: #ffffff;
background-color: var(--white);
}
paper-progress {
@ -94,23 +95,105 @@ class WebBrowser extends LitElement {
`
}
constructor() {
super()
this.url = 'about:blank'
const urlParams = new URLSearchParams(window.location.search);
this.name = urlParams.get('name');
this.service = urlParams.get('service');
// FUTURE: add support for identifiers
this.identifier = null;
this.followedNames = []
this.blockedNames = []
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
const getFollowedNames = async () => {
let followedNames = await parentEpml.request('apiCall', {
url: `/lists/followedNames?apiKey=${this.getApiKey()}`
})
this.followedNames = followedNames
setTimeout(getFollowedNames, this.config.user.nodeSettings.pingInterval)
}
const getBlockedNames = async () => {
let blockedNames = await parentEpml.request('apiCall', {
url: `/lists/blockedNames?apiKey=${this.getApiKey()}`
})
this.blockedNames = blockedNames
setTimeout(getBlockedNames, this.config.user.nodeSettings.pingInterval)
}
const render = () => {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
this.url = `${nodeUrl}/render/${this.service}/${this.name}`;
}
const authorizeAndRender = () => {
parentEpml.request('apiCall', {
url: `/render/authorize/${this.name}?apiKey=${this.getApiKey()}`,
method: "POST"
}).then(res => {
console.log(res)
if (res.error) {
// Authorization problem - API key incorrect?
}
else {
render()
}
})
}
let configLoaded = false
parentEpml.ready().then(() => {
parentEpml.subscribe('selected_address', async selectedAddress => {
this.selectedAddress = {}
selectedAddress = JSON.parse(selectedAddress)
if (!selectedAddress || Object.entries(selectedAddress).length === 0) return
this.selectedAddress = selectedAddress
})
parentEpml.subscribe('config', c => {
this.config = JSON.parse(c)
if (!configLoaded) {
authorizeAndRender()
setTimeout(getFollowedNames, 1)
setTimeout(getBlockedNames, 1)
configLoaded = true
}
})
parentEpml.subscribe('copy_menu_switch', async value => {
if (value === 'false' && window.getSelection().toString().length !== 0) {
this.clearSelection()
}
})
})
}
render() {
return html`
<div id="websitesWrapper" style="width:auto; padding:10px; background: #fff;">
<div id="websitesWrapper" style="width:auto; padding:10px; background: var(--white);">
<div class="layout horizontal center">
<div class="address-bar">
<mwc-button @click=${() => this.goBack()} title="Back" class="address-bar-button"><mwc-icon>arrow_back_ios</mwc-icon></mwc-button>
<mwc-button @click=${() => this.goForward()} title="Forward" class="address-bar-button"><mwc-icon>arrow_forward_ios</mwc-icon></mwc-button>
<mwc-button @click=${() => this.refresh()} title="Reload" class="address-bar-button"><mwc-icon>refresh</mwc-icon></mwc-button>
<mwc-button @click=${() => this.goBackToList()} title="Back to list" class="address-bar-button"><mwc-icon>home</mwc-icon></mwc-button>
<input disabled style="width:550px;" id="address" type="text" value="qortal://${this.service.toLowerCase()}/${this.name}"></input>
<input disabled style="width: 550px; color: var(--black);" id="address" type="text" value="qortal://${this.service.toLowerCase()}/${this.name}"></input>
<mwc-button @click=${() => this.delete()} title="Delete ${this.service} ${this.name} from node" class="address-bar-button float-right"><mwc-icon>delete</mwc-icon></mwc-button>
${this.renderBlockUnblockButton()}
${this.renderFollowUnfollowButton()}
</div>
<div class="iframe-container">
<iframe id="browser-iframe" src="${this.url}" sandbox="allow-scripts allow-forms allow-downloads">
Your browser doesn't support iframes
<span style="color: var(--black);">Your browser doesn't support iframes</span>
</iframe>
</div>
</div>
@ -118,6 +201,38 @@ class WebBrowser extends LitElement {
`
}
firstUpdated() {
setInterval(() => {
this.changeTheme();
}, 100)
window.addEventListener('contextmenu', (event) => {
event.preventDefault()
this._textMenu(event)
})
window.addEventListener('click', () => {
parentEpml.request('closeCopyTextMenu', null)
})
window.onkeyup = (e) => {
if (e.keyCode === 27) {
parentEpml.request('closeCopyTextMenu', null)
}
}
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') {
this.theme = 'dark';
} else {
this.theme = 'light';
}
document.querySelector('html').setAttribute('theme', this.theme);
}
renderFollowUnfollowButton() {
// Only show the follow/unfollow button if we have permission to modify the list on this node
if (this.followedNames == null || !Array.isArray(this.followedNames)) {
@ -357,105 +472,6 @@ class WebBrowser extends LitElement {
checkSelectedTextAndShowMenu()
}
constructor() {
super()
this.url = 'about:blank'
const urlParams = new URLSearchParams(window.location.search);
this.name = urlParams.get('name');
this.service = urlParams.get('service');
// FUTURE: add support for identifiers
this.identifier = null;
this.followedNames = []
this.blockedNames = []
const getFollowedNames = async () => {
let followedNames = await parentEpml.request('apiCall', {
url: `/lists/followedNames?apiKey=${this.getApiKey()}`
})
this.followedNames = followedNames
setTimeout(getFollowedNames, this.config.user.nodeSettings.pingInterval)
}
const getBlockedNames = async () => {
let blockedNames = await parentEpml.request('apiCall', {
url: `/lists/blockedNames?apiKey=${this.getApiKey()}`
})
this.blockedNames = blockedNames
setTimeout(getBlockedNames, this.config.user.nodeSettings.pingInterval)
}
const render = () => {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
this.url = `${nodeUrl}/render/${this.service}/${this.name}`;
}
const authorizeAndRender = () => {
parentEpml.request('apiCall', {
url: `/render/authorize/${this.name}?apiKey=${this.getApiKey()}`,
method: "POST"
}).then(res => {
console.log(res)
if (res.error) {
// Authorization problem - API key incorrect?
}
else {
render()
}
})
}
let configLoaded = false
parentEpml.ready().then(() => {
parentEpml.subscribe('selected_address', async selectedAddress => {
this.selectedAddress = {}
selectedAddress = JSON.parse(selectedAddress)
if (!selectedAddress || Object.entries(selectedAddress).length === 0) return
this.selectedAddress = selectedAddress
})
parentEpml.subscribe('config', c => {
this.config = JSON.parse(c)
if (!configLoaded) {
authorizeAndRender()
setTimeout(getFollowedNames, 1)
setTimeout(getBlockedNames, 1)
configLoaded = true
}
})
parentEpml.subscribe('copy_menu_switch', async value => {
if (value === 'false' && window.getSelection().toString().length !== 0) {
this.clearSelection()
}
})
})
}
firstUpdated() {
window.addEventListener('contextmenu', (event) => {
event.preventDefault()
this._textMenu(event)
})
window.addEventListener('click', () => {
parentEpml.request('closeCopyTextMenu', null)
})
window.onkeyup = (e) => {
if (e.keyCode === 27) {
parentEpml.request('closeCopyTextMenu', null)
}
}
}
getApiKey() {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node];
let apiKey = myNode.apiKey;

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="/font/material-icons.css">
<link rel="stylesheet" href="/font/switch-theme.css">
<style>
html {
--scrollbarBG: #a1a1a1;
@ -32,7 +33,7 @@
body {
margin: 0;
font-family: "Roboto", sans-serif;
background-color: #fff;
background: var(--plugback);
}
</style>
</head>

View File

@ -21,7 +21,8 @@ class DataManagement extends LitElement {
searchDatres: { type: Array },
blockedNames: { type: Array },
followedNames: { type: Array },
datres: { type: Array }
datres: { type: Array },
theme: { type: String, reflect: true }
}
}
@ -34,12 +35,18 @@ class DataManagement extends LitElement {
--lumo-primary-color-50pct: rgba(0, 167, 245, 0.5);
--lumo-primary-color-10pct: rgba(0, 167, 245, 0.1);
--lumo-primary-color: hsl(199, 100%, 48%);
--lumo-base-color: var(--white);
--lumo-body-text-color: var(--black);
--lumo-secondary-text-color: var(--sectxt);
--lumo-contrast-60pct: var(--vdicon);
--_lumo-grid-border-color: var(--border);
--_lumo-grid-secondary-border-color: var(--border2);
}
#pages {
#pages {
display: flex;
flex-wrap: wrap;
padding: 10px 5px 5px 5px;
padding: 10px 5px 5px 5px;
margin: 0px 20px 20px 20px;
}
@ -53,6 +60,7 @@ class DataManagement extends LitElement {
font: inherit;
outline: none;
cursor: pointer;
color: var(--black);
}
#pages > button:not([disabled]):hover,
@ -63,7 +71,7 @@ class DataManagement extends LitElement {
#pages > button[selected] {
font-weight: bold;
color: white;
color: var(--white);
background-color: #ccc;
}
@ -73,7 +81,7 @@ class DataManagement extends LitElement {
}
#websites-list-page {
background: #fff;
background: var(--white);
padding: 12px 24px;
}
@ -95,12 +103,12 @@ class DataManagement extends LitElement {
}
h2, h3, h4, h5 {
color:#333;
color: var(--black);
font-weight: 400;
}
a.visitSite {
color: #000;
color: var(--black);
text-decoration: none;
}
@ -155,6 +163,7 @@ class DataManagement extends LitElement {
this.followedNames = []
this.datres = []
this.isLoading = false
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
@ -218,6 +227,10 @@ class DataManagement extends LitElement {
firstUpdated() {
setInterval(() => {
this.changeTheme();
}, 100)
this.showManagement()
window.addEventListener('contextmenu', (event) => {
@ -270,6 +283,16 @@ class DataManagement extends LitElement {
parentEpml.imReady()
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') {
this.theme = 'dark';
} else {
this.theme = 'light';
}
document.querySelector('html').setAttribute('theme', this.theme);
}
searchListener(e) {
if (e.key === 'Enter') {
this.doSearch(e);

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="/font/material-icons.css">
<link rel="stylesheet" href="/font/switch-theme.css">
<style>
html {
--scrollbarBG: #a1a1a1;
@ -32,7 +33,7 @@
body {
margin: 0;
font-family: "Roboto", sans-serif;
background-color: #fff;
background: var(--plugback);
}
</style>
</head>

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="/font/material-icons.css">
<link rel="stylesheet" href="/font/switch-theme.css">
<style>
html {
--scrollbarBG: #a1a1a1;
@ -32,7 +33,7 @@
body {
margin: 0;
font-family: "Roboto", sans-serif;
background-color: #fff;
background: var(--plugback);
}
</style>
</head>

View File

@ -35,7 +35,8 @@ class Websites extends LitElement {
webBlockedNames: { type: Array },
blockResources: { type: Array },
blockFollowedNames: { type: Array },
blockBlockedNames: { type: Array }
blockBlockedNames: { type: Array },
theme: { type: String, reflect: true }
}
}
@ -48,6 +49,12 @@ class Websites extends LitElement {
--lumo-primary-color-50pct: rgba(0, 167, 245, 0.5);
--lumo-primary-color-10pct: rgba(0, 167, 245, 0.1);
--lumo-primary-color: hsl(199, 100%, 48%);
--lumo-base-color: var(--white);
--lumo-body-text-color: var(--black);
--lumo-secondary-text-color: var(--sectxt);
--lumo-contrast-60pct: var(--vdicon);
--_lumo-grid-border-color: var(--border);
--_lumo-grid-secondary-border-color: var(--border2);
}
#tabs-1 {
@ -59,10 +66,16 @@ class Websites extends LitElement {
padding-bottom: 10px;
}
#pages {
mwc-tab-bar {
--mdc-text-transform: none;
--mdc-tab-color-default: var(--black);
--mdc-tab-text-label-color-default: var(--black);
}
#pages {
display: flex;
flex-wrap: wrap;
padding: 10px 5px 5px 5px;
padding: 10px 5px 5px 5px;
margin: 0px 20px 20px 20px;
}
@ -76,6 +89,7 @@ class Websites extends LitElement {
font: inherit;
outline: none;
cursor: pointer;
color: var(--black);
}
#pages > button:not([disabled]):hover,
@ -86,7 +100,7 @@ class Websites extends LitElement {
#pages > button[selected] {
font-weight: bold;
color: white;
color: var(--white);
background-color: #ccc;
}
@ -96,7 +110,7 @@ class Websites extends LitElement {
}
#websites-list-page {
background: #fff;
background: var(--white);
padding: 12px 24px;
}
@ -118,12 +132,12 @@ class Websites extends LitElement {
}
h2, h3, h4, h5 {
color:#333;
color: var(--black);
font-weight: 400;
}
a.visitSite {
color: #000;
color: var(--black);
text-decoration: none;
}
@ -167,7 +181,7 @@ class Websites extends LitElement {
word-break:normal;
font-size:14px;
line-height:20px;
color:rgb(100,100,100);
color: var(--relaynodetxt);
}
img {
@ -199,6 +213,7 @@ class Websites extends LitElement {
this.blockResources = []
this.blockFollowedNames = []
this.blockBlockedNames = []
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
@ -283,7 +298,7 @@ class Websites extends LitElement {
</vaadin-grid>
<div id="pages"></div>
${this.isEmptyArray(this.resources) ? html`
No websites available
<span style="color: var(--black);">No websites available</span>
`: ''}
</div>
${this.renderRelayModeText()}
@ -322,7 +337,7 @@ class Websites extends LitElement {
</vaadin-grid-column>
</vaadin-grid>
${this.isEmptyArray(this.webResources) ? html`
You not follow any website
<span style="color: var(--black);">You not follow any website</span>
`: ''}
</div>
${this.renderRelayModeText()}
@ -361,7 +376,7 @@ class Websites extends LitElement {
</vaadin-grid-column>
</vaadin-grid>
${this.isEmptyArray(this.blockResources) ? html`
You have not blocked any website
<span style="color: var(--black);">You have not blocked any website</span>
`: ''}
</div>
${this.renderRelayModeText()}
@ -373,6 +388,10 @@ class Websites extends LitElement {
firstUpdated() {
setInterval(() => {
this.changeTheme();
}, 100)
this.showWebsites()
setTimeout(() => {
@ -514,6 +533,16 @@ class Websites extends LitElement {
parentEpml.imReady()
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') {
this.theme = 'dark';
} else {
this.theme = 'light';
}
document.querySelector('html').setAttribute('theme', this.theme);
}
displayTabContent(tab) {
const tabBrowseContent = this.shadowRoot.getElementById('tab-browse-content')
const tabFollowedContent = this.shadowRoot.getElementById('tab-followed-content')

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="/font/material-icons.css">
<link rel="stylesheet" href="/font/switch-theme.css">
<style>
html {
--scrollbarBG: #a1a1a1;
@ -32,7 +33,7 @@
body {
margin: 0;
font-family: "Roboto", sans-serif;
background-color: #fff;
background: var(--plugback);
}
</style>
</head>

View File

@ -24,7 +24,8 @@ class RewardShare extends LitElement {
removeRewardShareLoading: { type: Boolean },
rewardSharePercentage: { type: Number },
error: { type: Boolean },
message: { type: String }
message: { type: String },
theme: { type: String, reflect: true }
}
}
@ -38,10 +39,19 @@ class RewardShare extends LitElement {
--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-grid-border-color: var(--border);
--_lumo-grid-secondary-border-color: var(--border2);
}
.myGridColor {
background-color: var(--white) !important;
color: var(--black);
}
#reward-share-page {
background: #fff;
background: var(--white);
padding: 12px 24px;
}
@ -56,7 +66,7 @@ class RewardShare extends LitElement {
}
h2, h3, h4, h5 {
color:#333;
color: var(--black);
font-weight: 400;
}
@ -75,6 +85,7 @@ class RewardShare extends LitElement {
this.btnDisable = false
this.createRewardShareLoading = false
this.removeRewardShareLoading = false
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
render() {
@ -87,7 +98,7 @@ class RewardShare extends LitElement {
<div class="divCard">
<h3 style="margin: 0; margin-bottom: 1em; text-align: center;">Rewardshares Involving In This Account</h3>
<vaadin-grid theme="large" id="accountRewardSharesGrid" ?hidden="${this.isEmptyArray(this.rewardShares)}" .items="${this.rewardShares}" all-rows-visible>
<vaadin-grid id="accountRewardSharesGrid" ?hidden="${this.isEmptyArray(this.rewardShares)}" .items="${this.rewardShares}" all-rows-visible>
<vaadin-grid-column auto-width path="mintingAccount"></vaadin-grid-column>
<vaadin-grid-column auto-width path="sharePercent"></vaadin-grid-column>
<vaadin-grid-column auto-width path="recipient"></vaadin-grid-column>
@ -146,13 +157,18 @@ class RewardShare extends LitElement {
</mwc-button>
</mwc-dialog>
${this.isEmptyArray(this.rewardShares) ? html`
Account is not involved in any reward shares
<span style="color: var(--black);">Account is not involved in any reward shares</span>
`: ''}
</div>
`
}
firstUpdated() {
setInterval(() => {
this.changeTheme();
}, 100)
window.addEventListener("contextmenu", (event) => {
event.preventDefault();
this._textMenu(event)
@ -246,6 +262,16 @@ class RewardShare extends LitElement {
})
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') {
this.theme = 'dark';
} else {
this.theme = 'light';
}
document.querySelector('html').setAttribute('theme', this.theme);
}
renderRemoveRewardShareButton(rewardShareObject) {
if (rewardShareObject.mintingAccount === this.selectedAddress.address) {
return html`<mwc-button class="red" ?disabled=${this.removeRewardShareLoading} @click=${() => this.removeRewardShare(rewardShareObject)}><mwc-icon>create</mwc-icon>Remove</mwc-button>`

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="/font/material-icons.css">
<link rel="stylesheet" href="/font/switch-theme.css">
<style>
html {
--scrollbarBG: #a1a1a1;
@ -32,7 +33,7 @@
body {
margin: 0;
font-family: "Roboto", sans-serif;
background-color: #fff;
background: var(--plugback);
}
</style>
</head>

View File

@ -29,7 +29,8 @@ class SendMoneyPage extends LitElement {
ltcBalance: { type: Number },
dogeBalance: { type: Number },
selectedCoin: { type: String },
satFeePerByte: { type: Number }
satFeePerByte: { type: Number },
theme: { type: String, reflect: true }
}
}
@ -39,99 +40,111 @@ class SendMoneyPage extends LitElement {
static get styles() {
return css`
* {
--mdc-theme-primary: rgb(3, 169, 244);
--mdc-theme-secondary: var(--mdc-theme-primary);
--paper-input-container-focus-color: var(--mdc-theme-primary);
}
* {
--mdc-theme-primary: rgb(3, 169, 244);
--mdc-theme-secondary: var(--mdc-theme-primary);
--paper-input-container-focus-color: var(--mdc-theme-primary);
}
#sendMoneyWrapper {
}
h2,
h3,
h4,
h5 {
color: var(--black);
font-weight: 400;
}
#sendMoneyWrapper paper-button {
float: right;
}
#sendMoneyWrapper {
}
#sendMoneyWrapper .buttons {
width: auto !important;
}
#sendMoneyWrapper paper-button {
float: right;
}
.address-item {
--paper-item-focused: {
background: transparent;
}
--paper-item-focused-before: {
opacity: 0;
}
}
#sendMoneyWrapper .buttons {
width: auto !important;
}
.address-balance {
font-size: 42px;
font-weight: 100;
.address-item {
--paper-item-focused: {
background: transparent;
}
--paper-item-focused-before: {
opacity: 0;
}
}
.show-transactions {
cursor: pointer;
}
.address-balance {
font-size: 42px;
font-weight: 100;
}
.address-icon {
border-radius: 50%;
border: 5px solid;
padding: 8px;
}
.show-transactions {
cursor: pointer;
}
mwc-textfield {
margin: 0;
}
.address-icon {
border-radius: 50%;
border: 5px solid;
padding: 8px;
}
.selectedBalance {
display: none;
font-size: 14px;
}
.baltxt {
color: var(--black);
}
.selectedBalance .balance {
font-size: 22px;
font-weight: 100;
}
.coinName::before {
content: "";
display: inline-block;
height: 25px;
width: 25px;
position: absolute;
background-repeat: no-repeat;
background-size: cover;
left: 10px;
top: 10px;
}
mwc-textfield {
margin: 0;
}
.qort.coinName:before {
background-image: url('/img/qort.png');
}
.selectedBalance {
display: none;
font-size: 14px;
}
.btc.coinName:before {
background-image: url('/img/btc.png');
}
.selectedBalance .balance {
font-size: 22px;
font-weight: 100;
}
.ltc.coinName:before {
background-image: url('/img/ltc.png');
}
.coinName::before {
content: "";
display: inline-block;
height: 25px;
width: 25px;
position: absolute;
background-repeat: no-repeat;
background-size: cover;
left: 10px;
top: 10px;
}
.doge.coinName:before {
background-image: url('/img/doge.png');
}
.qort.coinName:before {
background-image: url('/img/qort.png');
}
.coinName {
display: inline-block;
height: 25px;
padding-left: 25px;
}
paper-progress {
--paper-progress-active-color: var(--mdc-theme-primary);
}
`
.btc.coinName:before {
background-image: url('/img/btc.png');
}
.ltc.coinName:before {
background-image: url('/img/ltc.png');
}
.doge.coinName:before {
background-image: url('/img/doge.png');
}
.coinName {
display: inline-block;
height: 25px;
padding-left: 25px;
}
paper-progress {
--paper-progress-active-color: var(--mdc-theme-primary);
}
`
}
constructor() {
@ -158,6 +171,7 @@ class SendMoneyPage extends LitElement {
this.ltcBalance = 0
this.dogeBalance = 0
this.selectedCoin = 'invalid'
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light';
let configLoaded = false
parentEpml.ready().then(() => {
@ -193,15 +207,14 @@ class SendMoneyPage extends LitElement {
render() {
return html`
<div id="sendMoneyWrapper" style="width:auto; padding:10px; background: #fff; height:100vh;">
<div class="layout horizontal center" style=" padding:12px 15px;">
<div id="sendMoneyWrapper" style="width:auto; padding:10px; background: var(--white); height:100vh;">
<div class="layout horizontal center" style="padding:12px 15px;">
<paper-card style="width:100%; max-width:740px;">
<div style="background-color: ${this.selectedAddress.color}; margin:0; color: ${this.textColor(this.selectedAddress.textColor)};">
<h3 style="margin:0; padding:8px 0;">Send Coin</h3>
<h3 style="margin: 0; padding: 8px 0;">Send Coin</h3>
<div class="selectedBalance">
<span id="balance"></span> available for transfer from
<span id="address"></span>
<span id="balance" class="baltxt"></span> <span class="baltxt">available for transfer from</span> <span id="address" class="baltxt"></span>
</div>
</div>
</paper-card>
@ -231,7 +244,7 @@ class SendMoneyPage extends LitElement {
</p>
<div style="${this.selectedCoin === 'invalid' || this.selectedCoin === 'qort' ? 'visibility: hidden; margin-bottom: -5em;' : 'visibility: visible; margin-bottom: 0;'}">
<p style="margin-bottom:0;">Fee per byte: ${(this.satFeePerByte / 1e8).toFixed(8)} ${this.selectedCoin === 'invalid' ? 'QORT' : this.selectedCoin.toLocaleUpperCase()}</p>
<p style="margin-bottom: 0; color: var(--black);">Fee per byte: ${(this.satFeePerByte / 1e8).toFixed(8)} ${this.selectedCoin === 'invalid' ? 'QORT' : this.selectedCoin.toLocaleUpperCase()}</p>
<mwc-slider
@change="${(e) => (this.satFeePerByte = e.target.value)}"
id="feeSlider"
@ -245,8 +258,8 @@ class SendMoneyPage extends LitElement {
</mwc-slider>
</div>
<p style="color:red">${this.errorMessage}</p>
<p style="color:green;word-break: break-word;">${this.successMessage}</p>
<p style="color: red;">${this.errorMessage}</p>
<p style="color: green; word-break: break-word;">${this.successMessage}</p>
${this.sendMoneyLoading ? html` <paper-progress indeterminate style="width:100%; margin:4px;"></paper-progress> ` : ''}
@ -261,6 +274,11 @@ class SendMoneyPage extends LitElement {
}
firstUpdated() {
setInterval(() => {
this.changeTheme();
}, 100)
// Get BTC Balance
this.updateBTCAccountBalance()
@ -347,6 +365,16 @@ class SendMoneyPage extends LitElement {
})
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') {
this.theme = 'dark';
} else {
this.theme = 'light';
}
document.querySelector('html').setAttribute('theme', this.theme);
}
_floor(num) {
return Math.floor(num)
}

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="/font/material-icons.css">
<link rel="stylesheet" href="/font/switch-theme.css">
<style>
html {
--scrollbarBG: #a1a1a1;
@ -32,7 +33,7 @@
body {
margin: 0;
font-family: "Roboto", sans-serif;
background-color: #fff;
background: var(--plugback);
}
</style>
</head>

View File

@ -34,7 +34,8 @@ class TradePortal extends LitElement {
selectedCoin: { type: String },
isLoadingHistoricTrades: { type: Boolean },
isLoadingOpenTrades: { type: Boolean },
isLoadingMyOpenOrders: { type: Boolean }
isLoadingMyOpenOrders: { type: Boolean },
theme: { type: String, reflect: true }
}
}
@ -43,18 +44,40 @@ class TradePortal extends LitElement {
* {
--mdc-theme-primary: rgb(3, 169, 244);
--mdc-theme-secondary: var(--mdc-theme-primary);
--mdc-theme-error: rgb(255, 89, 89);
--mdc-text-field-outlined-idle-border-color: var(--txtfieldborder);
--mdc-text-field-outlined-hover-border-color: var(--txtfieldhoverborder);
--mdc-text-field-label-ink-color: var(--black);
--mdc-text-field-ink-color: var(--black);
--mdc-select-outlined-idle-border-color: var(--txtfieldborder);
--mdc-select-outlined-hover-border-color: var(--txtfieldhoverborder);
--mdc-select-label-ink-color: var(--black);
--mdc-select-ink-color: var(--black);
--paper-input-container-focus-color: var(--mdc-theme-primary);
--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-primary-text-color: rgb(0, 167, 245);
--lumo-primary-color-50pct: rgba(0, 167, 245, 0.5);
--lumo-primary-color-10pct: rgba(0, 167, 245, 0.1);
--lumo-primary-color: hsl(199, 100%, 48%);
--lumo-base-color: var(--white);
--lumo-body-text-color: var(--black);
--lumo-secondary-text-color: var(--sectxt);
--lumo-contrast-60pct: var(--vdicon);
--_lumo-grid-border-color: var(--border);
--_lumo-grid-secondary-border-color: var(--border2);
}
mwc-tab-bar {
--mdc-text-transform: none;
--mdc-tab-color-default: var(--black);
--mdc-tab-text-label-color-default: var(--black);
}
#tabs-1 {
--mdc-tab-height: 50px;
border-left: 1px solid rgb(102, 102, 102);
border-top: 1px solid rgb(102, 102, 102);
border-right: 1px solid rgb(102, 102, 102);
border-left: 1px solid var(--tradeborder);
border-top: 1px solid var(--tradeborder);
border-right: 1px solid var(--tradeborder);
color: var(--black);
}
#tab-buy[active] {
@ -68,7 +91,7 @@ class TradePortal extends LitElement {
#tabs-1-content > div {
height: 100%;
border: 1px solid rgb(102, 102, 102);
border: 1px solid var(--tradeborder);
}
#tabs-1-content .card {
@ -77,6 +100,7 @@ class TradePortal extends LitElement {
#tabs-1-content .btn-clear {
--mdc-icon-button-size: 40px;
color: var(--black);
}
#tab-sell[active] {
@ -84,12 +108,12 @@ class TradePortal extends LitElement {
}
#trade-portal-page {
background: #fff;
background: var(--white);
padding: 12px 24px;
}
.divCard {
border: 1px solid #eee;
border: 1px solid var(--black);
padding: 1em;
box-shadow: 0 0.3px 1px 0 rgba(0, 0, 0, 0.14), 0 1px 1px -1px rgba(0, 0, 0, 0.12), 0 1px 2px 0 rgba(0, 0, 0, 0.2);
}
@ -102,7 +126,7 @@ class TradePortal extends LitElement {
h3,
h4,
h5 {
color: #333;
color: var(--black);
font-weight: 400;
}
@ -113,8 +137,11 @@ class TradePortal extends LitElement {
justify-content: center;
padding: 0px 15px;
font-size: 16px;
color: #fff;
background-color: rgb(106, 108, 117);
color: var(--white);
background-color: var(--tradehead);
border-left: 1px solid var(--tradeborder);
border-top: 1px solid var(--tradeborder);
border-right: 1px solid var(--tradeborder);
min-height: 40px;
}
@ -158,7 +185,7 @@ class TradePortal extends LitElement {
}
.trade-chart {
background-color: #eee;
background-color: var(--white);
border: 2px #ddd solid;
text-align: center;
}
@ -184,7 +211,7 @@ class TradePortal extends LitElement {
.card {
padding: 1em;
border: 1px #666 solid;
border: 1px var(--tradeborder) solid;
flex: 1 1 auto;
display: flex;
flex-flow: column;
@ -197,12 +224,12 @@ class TradePortal extends LitElement {
}
.border-wrapper {
border: 1px #666 solid;
border: 1px var(--tradeborder) solid;
overflow: hidden;
}
.you-have {
color: #555;
color: var(--tradehave);
font-size: 15px;
text-align: right;
margin-top: 2px;
@ -234,7 +261,7 @@ class TradePortal extends LitElement {
}
.full-width {
background-color: #fff;
background-color: var(--white);
border: 2px #ddd solid;
height: 100px;
text-align: center;
@ -435,6 +462,7 @@ class TradePortal extends LitElement {
this.isLoadingHistoricTrades = true
this.isLoadingOpenTrades = true
this.isLoadingMyOpenOrders = false
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
}
// TODO: Move each template to a separate components! Maybe
@ -544,7 +572,7 @@ class TradePortal extends LitElement {
</div>
<p>
<mwc-textfield
style="width:100%;"
style="width: 100%; color: var(--black);"
id="buyAmountInput"
required readOnly label="Amount (QORT)"
placeholder="0.0000"
@ -556,7 +584,7 @@ class TradePortal extends LitElement {
</p>
<p>
<mwc-textfield
style="width:100%;"
style="width: 100%; color: var(--black);"
id="buyPriceInput"
required readOnly
label="Price Ea. (${this.listedCoins.get(this.selectedCoin).coinCode})"
@ -569,7 +597,7 @@ class TradePortal extends LitElement {
</p>
<p style="margin-bottom: 10px;">
<mwc-textfield
style="width:100%;"
style="width: 100%; color: var(--black);"
id="buyTotalInput"
required readOnly
label="Total (${this.listedCoins.get(this.selectedCoin).coinCode})"
@ -607,7 +635,7 @@ class TradePortal extends LitElement {
</div>
<p>
<mwc-textfield
style="width:100%;"
style="width: 100%; color: var(--black);"
id="sellAmountInput"
required label="Amount (QORT)"
placeholder="0.0000"
@ -620,7 +648,7 @@ class TradePortal extends LitElement {
</p>
<p>
<mwc-textfield
style="width:100%;"
style="width: 100%; color: var(--black);"
id="sellPriceInput"
required label="Price Ea. (${this.listedCoins.get(this.selectedCoin).coinCode})"
placeholder="0.0000"
@ -633,7 +661,7 @@ class TradePortal extends LitElement {
</p>
<p style="margin-bottom: 10px;">
<mwc-textfield
style="width:100%;"
style="width: 100%; color: var(--black);"
id="sellTotalInput"
required readOnly
label="Total (${this.listedCoins.get(this.selectedCoin).coinCode})"
@ -829,6 +857,10 @@ class TradePortal extends LitElement {
firstUpdated() {
let _this = this
setInterval(() => {
this.changeTheme();
}, 100)
this.updateWalletBalance()
setTimeout(() => {
@ -907,6 +939,16 @@ class TradePortal extends LitElement {
setTimeout(() => this.shadowRoot.querySelector('[slot="vaadin-grid-cell-content-3"]').setAttribute('title', 'Last Seen'), 3000)
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') {
this.theme = 'dark';
} else {
this.theme = 'light';
}
document.querySelector('html').setAttribute('theme', this.theme);
}
updateWalletBalance() {
let _url = ``
let _body = null

View File

@ -3,6 +3,7 @@
<head>
<link rel="stylesheet" href="/font/material-icons.css">
<link rel="stylesheet" href="/font/switch-theme.css">
<style>
html {
--scrollbarBG: #a1a1a1;
@ -32,7 +33,7 @@
body {
margin: 0;
font-family: "Roboto", sans-serif;
background-color: #fff;
background: var(--plugback);
}
</style>
</head>

View File

@ -24,6 +24,7 @@ class MultiWallet extends LitElement {
isTextMenuOpen: { type: Boolean },
wallets: { type: Map },
_selectedWallet: 'qort',
theme: { type: String, reflect: true },
balanceString: 'Fetching balance ...'
}
}
@ -37,6 +38,10 @@ class MultiWallet extends LitElement {
--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-grid-border-color: var(--border);
--_lumo-grid-secondary-border-color: var(--border2);
}
#pages {
@ -56,6 +61,7 @@ class MultiWallet extends LitElement {
font: inherit;
outline: none;
cursor: pointer;
color: var(--black);
}
#pages > button:not([disabled]):hover,
@ -66,7 +72,7 @@ class MultiWallet extends LitElement {
#pages > button[selected] {
font-weight: bold;
color: white;
color: var(--white);
background-color: #ccc;
}
@ -108,7 +114,7 @@ class MultiWallet extends LitElement {
.text-white-primary {
color: var(--white-primary);
color: var(--white);
}
.text-white-secondary {
@ -124,6 +130,7 @@ class MultiWallet extends LitElement {
table {
border: none;
}
table td,
th {
white-space: nowrap;
@ -131,39 +138,51 @@ class MultiWallet extends LitElement {
font-size: 14px;
padding: 0 12px;
font-family: 'Roboto', sans-serif;
color: var(--black);
background: var(--white);
}
table tr {
height: 48px;
}
table tr:hover td {
background: #eee;
}
table tr th {
color: #666;
font-size: 12px;
}
table tr td {
margin: 0;
}
.white-bg {
height: 100vh;
background: #fff;
background: var(--white);
}
span {
font-size: 18px;
word-break: break-all;
}
.title {
font-weight: 600;
font-size: 12px;
line-height: 32px;
opacity: 0.66;
}
#transactionList {
padding: 0;
}
#transactionList > * {
}
.color-in {
color: #02977e;
background-color: rgba(0, 201, 167, 0.2);
@ -173,6 +192,7 @@ class MultiWallet extends LitElement {
padding: 0.2rem 0.5rem;
margin-left: 4px;
}
.color-out {
color: #b47d00;
background-color: rgba(219, 154, 4, 0.2);
@ -186,7 +206,7 @@ class MultiWallet extends LitElement {
body {
margin: 0;
padding: 0;
background: white;
background: var(--white);
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
@ -194,7 +214,7 @@ class MultiWallet extends LitElement {
h2 {
margin: 0;
font-weight: 400;
color: #707584;
color: var(--black);
font: 24px/24px 'Open Sans', sans-serif;
}
@ -218,7 +238,7 @@ class MultiWallet extends LitElement {
height: 100%;
overflow: hidden;
border-radius: 8px;
background-color: #fff;
background-color: var(--white);
}
.wallet {
@ -243,7 +263,7 @@ class MultiWallet extends LitElement {
display: flex;
align-items: center;
font-size: 18px;
color: var(--mdc-theme-primary, #444750);
color: var(--black);
margin: 4px 0 20px;
}
@ -251,7 +271,7 @@ class MultiWallet extends LitElement {
display: inline-block;
font-weight: 600;
font-size: 32px;
color: var(--mdc-theme-primary, #444750);
color: var(--black);
}
#transactions {
@ -275,6 +295,7 @@ class MultiWallet extends LitElement {
margin-bottom: 45px;
margin-right: 50px;
}
.transaction-item::before {
position: absolute;
content: '';
@ -324,18 +345,19 @@ class MultiWallet extends LitElement {
.currency-box {
display: flex;
background-color: #fff;
background-color: var(--white);
text-align: center;
padding: 12px;
cursor: pointer;
transition: 0.1s ease-in-out;
}
.currency-box:not(:last-child) {
border-bottom: 1px solid #eee;
}
.active {
background: #ddd;
background: #bbb;
}
.currency-image {
@ -347,13 +369,16 @@ class MultiWallet extends LitElement {
border-radius: 3px;
filter: grayscale(100%);
}
.currency-box.active .currency-image,
.currency-box:hover .currency-image {
filter: none;
}
.currency-box:hover {
background: #bbb;
}
.currency-box.active,
.currency-box:hover .currency-text {
font-weight: 500;
@ -363,7 +388,7 @@ class MultiWallet extends LitElement {
margin: auto 0;
margin-left: 8px;
font-size: 20px;
color: #777;
color: var(--black);
}
.qort .currency-image {
@ -496,6 +521,8 @@ class MultiWallet extends LitElement {
this.selectWallet = this.selectWallet.bind(this)
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light';
this.wallets = new Map()
let coinProp = {
balance: 0,
@ -539,7 +566,7 @@ class MultiWallet extends LitElement {
return html`
<div class="wrapper">
<div class="wallet">
<div style="font-size: 20px; color: #777; padding: 16px; border-bottom: 1px solid #eee;">Wallets</div>
<div style="font-size: 20px; color: var(--black); padding: 16px; border-bottom: 1px solid #eee;">Wallets</div>
<div class="cards">
<div coin="qort" class="currency-box qort active">
<div class="currency-image"></div>
@ -572,7 +599,7 @@ class MultiWallet extends LitElement {
textToCopy=${this.getSelectedWalletAddress()}
buttonSize="28px"
iconSize="16px"
color="#707584"
color="var(--copybutton)"
offsetLeft="4px"
>
</button-icon-copy>
@ -631,13 +658,167 @@ class MultiWallet extends LitElement {
`
}
firstUpdated() {
setInterval(() => {
this.changeTheme();
}, 100)
// DOM refs
this.currencyBoxes = this.shadowRoot.querySelectorAll('.currency-box')
this.transactionsDOM = this.shadowRoot.getElementById('transactionsDOM')
// Attach eventlisteners to the cuurency boxes
this.currencyBoxes.forEach((currencyBox) => {
currencyBox.addEventListener('click', this.selectWallet)
})
this.showWallet()
window.addEventListener('contextmenu', (event) => {
event.preventDefault()
this.isTextMenuOpen = true
this._textMenu(event)
})
window.addEventListener('click', () => {
if (this.isTextMenuOpen) {
parentEpml.request('closeCopyTextMenu', null)
}
})
window.onkeyup = (e) => {
if (e.keyCode === 27) {
parentEpml.request('closeCopyTextMenu', null)
}
}
}
selectWallet(event) {
event.preventDefault()
const target = event.currentTarget
// if (target.classList.contains('active')) return
// removed to allow one click wallet refresh
this.currencyBoxes.forEach((currencyBox) => {
if (currencyBox.classList.contains('active')) {
currencyBox.classList.remove('active')
}
})
target.classList.add('active')
this._selectedWallet = target.attributes.coin.value
this.showWallet()
}
async showWallet() {
this.transactionsDOM.hidden = true
this.loading = true
if (this._selectedWallet == 'qort') {
if (!window.parent.reduxStore.getState().app.blockInfo.height) {
// we make sure that `blockHeight` is set before rendering QORT transactions
await parentEpml.request('apiCall', { url: `/blocks/height`, type: 'api' })
.then(height => parentEpml.request('updateBlockInfo', { height }))
}
}
const coin = this._selectedWallet
await this.fetchWalletDetails(this._selectedWallet)
if (this._selectedWallet == coin) {
//if the wallet didn't switch
await this.renderTransactions()
await this.getTransactionGrid(this._selectedWallet)
await this.updateItemsFromPage(1, true)
this.loading = false
this.transactionsDOM.hidden = false
}
}
async fetchWalletDetails(coin) {
//this function will fetch the balance and transactions of the given wallet
this.balanceString = "Fetching balance ..."
switch (coin) {
case 'qort':
//fetching the qort balance
parentEpml
.request('apiCall', {
url: `/addresses/balance/${this.wallets.get('qort').wallet.address}?apiKey=${this.getApiKey()}`,
})
.then((res) => {
if (isNaN(Number(res))) {
parentEpml.request('showSnackBar', `Failed to Fetch QORT Balance. Try again!`)
} else {
if (this._selectedWallet == coin) {
//check if we are still fetching wallet balance ...
this.wallets.get(coin).balance = res
this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase()
}
}
})
//fetching the qort transactions
const txsQort = await parentEpml.request('apiCall', {
url: `/transactions/search?address=${this.wallets.get('qort').wallet.address}&confirmationStatus=CONFIRMED&reverse=true`,
})
if (this._selectedWallet == coin)
this.wallets.get(coin).transactions = txsQort
break
case 'btc':
case 'ltc':
case 'doge':
//fetching the balance
const walletName = `${coin}Wallet`
parentEpml
.request('apiCall', {
url: `/crosschain/${coin}/walletbalance?apiKey=${this.getApiKey()}`,
method: 'POST',
body: `${window.parent.reduxStore.getState().app.selectedAddress[walletName].derivedMasterPublicKey}`,
})
.then((res) => {
if (isNaN(Number(res))) {
parentEpml.request('showSnackBar', `Failed to Fetch ${coin.toLocaleUpperCase()} Balance. Try again!`)
} else {
if (this._selectedWallet == coin) {
//check if we are still fetching wallet balance ...
this.wallets.get(this._selectedWallet).balance = (Number(res) / 1e8).toFixed(8)
this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase()
}
}
})
//fetching transactions
const txs = await parentEpml.request('apiCall', {
url: `/crosschain/${coin}/wallettransactions?apiKey=${this.getApiKey()}`,
method: 'POST',
body: `${window.parent.reduxStore.getState().app.selectedAddress[walletName].derivedMasterPublicKey}`,
})
const compareFn = (a, b) => {
return b.timestamp - a.timestamp
}
const sortedTransactions = txs.sort(compareFn)
if (this._selectedWallet == coin) {
this.wallets.get(this._selectedWallet).transactions = sortedTransactions
}
break
default:
break
}
}
changeTheme() {
const checkTheme = localStorage.getItem('qortalTheme')
if (checkTheme === 'dark') {
this.theme = 'dark';
} else {
this.theme = 'light';
}
document.querySelector('html').setAttribute('theme', this.theme);
}
getSelectedWalletAddress() {
return this._selectedWallet === 'qort'
? this.wallets.get(this._selectedWallet).wallet.address
: this.wallets.get(this._selectedWallet).wallet.address
}
async getTransactionGrid(coin) {
this.transactionsGrid = this.shadowRoot.querySelector(`#${coin}TransactionsGrid`)
if (coin === 'qort') {
@ -675,19 +856,7 @@ class MultiWallet extends LitElement {
}
return html`
<dom-module id="vaadin-grid-qort-theme" theme-for="vaadin-grid">
<template>
<style>
:host([theme~="qort"]) table thead tr > th:first-of-type,
:host([theme~="qort"]) table tbody tr > td:first-of-type {
min-width: 56px;
max-width: 56px;
padding: 4px 0;
}
</style>
</template>
</dom-module>
<div style="padding-left:12px;" ?hidden="${!this.isEmptyArray(transactions)}">Address has no transactions yet.</div>
<div style="padding-left:12px;" ?hidden="${!this.isEmptyArray(transactions)}"><span style="color: var(--black);">Address has no transactions yet.</span></div>
<vaadin-grid theme="large" id="${coin}TransactionsGrid" ?hidden="${this.isEmptyArray(this.wallets.get(this._selectedWallet).transactions)}" page-size="25" all-rows-visible>
<vaadin-grid-column
auto-width
@ -734,7 +903,7 @@ class MultiWallet extends LitElement {
renderBTCLikeTransactions(transactions, coin) {
return html`
<div style="padding-left:12px;" ?hidden="${!this.isEmptyArray(transactions)}">Address has no transactions yet.</div>
<div style="padding-left:12px;" ?hidden="${!this.isEmptyArray(transactions)}"><span style="color: var(--black);">Address has no transactions yet.</span></div>
<vaadin-grid theme="large" id="${coin}TransactionsGrid" ?hidden="${this.isEmptyArray(this.wallets.get(this._selectedWallet).transactions)}" page-size="25" all-rows-visible>
<vaadin-grid-column auto-width resizable header="Transaction Hash" path="txHash"></vaadin-grid-column>
<vaadin-grid-column
@ -880,146 +1049,6 @@ class MultiWallet extends LitElement {
`
}
firstUpdated() {
// DOM refs
this.currencyBoxes = this.shadowRoot.querySelectorAll('.currency-box')
this.transactionsDOM = this.shadowRoot.getElementById('transactionsDOM')
// Attach eventlisteners to the cuurency boxes
this.currencyBoxes.forEach((currencyBox) => {
currencyBox.addEventListener('click', this.selectWallet)
})
this.showWallet()
window.addEventListener('contextmenu', (event) => {
event.preventDefault()
this.isTextMenuOpen = true
this._textMenu(event)
})
window.addEventListener('click', () => {
if (this.isTextMenuOpen) {
parentEpml.request('closeCopyTextMenu', null)
}
})
window.onkeyup = (e) => {
if (e.keyCode === 27) {
parentEpml.request('closeCopyTextMenu', null)
}
}
}
selectWallet(event) {
event.preventDefault()
const target = event.currentTarget
// if (target.classList.contains('active')) return
// removed to allow one click wallet refresh
this.currencyBoxes.forEach((currencyBox) => {
if (currencyBox.classList.contains('active')) {
currencyBox.classList.remove('active')
}
})
target.classList.add('active')
this._selectedWallet = target.attributes.coin.value
this.showWallet()
}
async showWallet() {
this.transactionsDOM.hidden = true
this.loading = true
if (this._selectedWallet == 'qort') {
if (!window.parent.reduxStore.getState().app.blockInfo.height) {
// we make sure that `blockHeight` is set before rendering QORT transactions
await parentEpml.request('apiCall', { url: `/blocks/height`, type: 'api' })
.then(height => parentEpml.request('updateBlockInfo', { height }))
}
}
const coin = this._selectedWallet
await this.fetchWalletDetails(this._selectedWallet)
if (this._selectedWallet == coin) {
//if the wallet didn't switch
await this.renderTransactions()
await this.getTransactionGrid(this._selectedWallet)
await this.updateItemsFromPage(1, true)
this.loading = false
this.transactionsDOM.hidden = false
}
}
async fetchWalletDetails(coin) {
//this function will fetch the balance and transactions of the given wallet
this.balanceString = "Fetching balance ..."
switch (coin) {
case 'qort':
//fetching the qort balance
parentEpml
.request('apiCall', {
url: `/addresses/balance/${this.wallets.get('qort').wallet.address}?apiKey=${this.getApiKey()}`,
})
.then((res) => {
if (isNaN(Number(res))) {
parentEpml.request('showSnackBar', `Failed to Fetch QORT Balance. Try again!`)
} else {
if (this._selectedWallet == coin) {
//check if we are still fetching wallet balance ...
this.wallets.get(coin).balance = res
this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase()
}
}
})
//fetching the qort transactions
const txsQort = await parentEpml.request('apiCall', {
url: `/transactions/search?address=${this.wallets.get('qort').wallet.address}&confirmationStatus=CONFIRMED&reverse=true`,
})
if (this._selectedWallet == coin)
this.wallets.get(coin).transactions = txsQort
break
case 'btc':
case 'ltc':
case 'doge':
//fetching the balance
const walletName = `${coin}Wallet`
parentEpml
.request('apiCall', {
url: `/crosschain/${coin}/walletbalance?apiKey=${this.getApiKey()}`,
method: 'POST',
body: `${window.parent.reduxStore.getState().app.selectedAddress[walletName].derivedMasterPublicKey}`,
})
.then((res) => {
if (isNaN(Number(res))) {
parentEpml.request('showSnackBar', `Failed to Fetch ${coin.toLocaleUpperCase()} Balance. Try again!`)
} else {
if (this._selectedWallet == coin) {
//check if we are still fetching wallet balance ...
this.wallets.get(this._selectedWallet).balance = (Number(res) / 1e8).toFixed(8)
this.balanceString = this.wallets.get(this._selectedWallet).balance + " " + this._selectedWallet.toLocaleUpperCase()
}
}
})
//fetching transactions
const txs = await parentEpml.request('apiCall', {
url: `/crosschain/${coin}/wallettransactions?apiKey=${this.getApiKey()}`,
method: 'POST',
body: `${window.parent.reduxStore.getState().app.selectedAddress[walletName].derivedMasterPublicKey}`,
})
const compareFn = (a, b) => {
return b.timestamp - a.timestamp
}
const sortedTransactions = txs.sort(compareFn)
if (this._selectedWallet == coin) {
this.wallets.get(this._selectedWallet).transactions = sortedTransactions
}
break
default:
break
}
}
showTransactionDetails(myTransaction, allTransactions) {
allTransactions.forEach((transaction) => {
if (myTransaction.signature === transaction.signature) {