From 689cd82f8102ad05c3a6f850d263e534a12d47cc Mon Sep 17 00:00:00 2001
From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com>
Date: Fri, 14 Jul 2023 15:08:32 +0200
Subject: [PATCH 1/5] Add dev part 1
---
core/src/components/show-plugin.js | 4356 ++++++++++++++--------------
1 file changed, 2178 insertions(+), 2178 deletions(-)
diff --git a/core/src/components/show-plugin.js b/core/src/components/show-plugin.js
index 2861d3c1..e32d08e6 100644
--- a/core/src/components/show-plugin.js
+++ b/core/src/components/show-plugin.js
@@ -1,2178 +1,2178 @@
-import { LitElement, html, css } from 'lit'
-import { render } from 'lit/html.js'
-import { connect } from 'pwa-helpers'
-import { store } from '../store.js'
-import { Epml } from '../epml.js'
-import { addPluginRoutes } from '../plugins/addPluginRoutes.js'
-import { repeat } from 'lit/directives/repeat.js';
-import ShortUniqueId from 'short-unique-id';
-import { setNewTab } from '../redux/app/app-actions.js'
-import localForage from 'localforage'
-import FileSaver from 'file-saver'
-import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
-
-registerTranslateConfig({
- loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
-})
-
-import '@material/mwc-button'
-import '@material/mwc-dialog'
-import '@material/mwc-icon'
-import '@material/mwc-textfield'
-import '@polymer/paper-icon-button/paper-icon-button.js'
-import '@polymer/iron-icons/iron-icons.js'
-import '@polymer/paper-dialog/paper-dialog.js'
-import '@vaadin/grid'
-import '@vaadin/text-field'
-import '../custom-elements/frag-file-input.js'
-
-const chatLastSeen = localForage.createInstance({
- name: "chat-last-seen",
-})
-
-const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
-
-class ShowPlugin extends connect(store)(LitElement) {
- static get properties() {
- return {
- app: { type: Object },
- pluginConfig: { type: Object },
- url: { type: String },
- linkParam: { type: String },
- registeredUrls: { type: Array },
- currentTab: { type: Number },
- tabs: { type: Array },
- theme: { type: String, reflect: true },
- tabInfo: { type: Object },
- chatLastSeen: { type: Array },
- chatHeads: { type: Array }
- }
- }
-
- static get styles() {
- return css`
- html {
- --scrollbarBG: #a1a1a1;
- --thumbBG: #6a6c75;
- }
-
- *::-webkit-scrollbar {
- width: 11px;
- }
-
- * {
- scrollbar-width: thin;
- scrollbar-color: var(--thumbBG) var(--scrollbarBG);
- }
-
- *::-webkit-scrollbar-track {
- background: var(--scrollbarBG);
- }
-
- *::-webkit-scrollbar-thumb {
- background-color: var(--thumbBG);
- border-radius: 6px;
- border: 3px solid var(--scrollbarBG);
- }
-
- .hideIframe {
- display: none;
- position: absolute;
- zIndex: -10;
- }
-
- .showIframe {
- display: block;
- position: relative;
- zIndex: 1;
- }
-
- .tabs {
- display: flex;
- width: 100%;
- max-width: 100%;
- justify-content: flex-start;
- padding-top: 0.5em;
- padding-left: 0.5em;
- background: var(--sidetopbar);
- border-bottom: 1px solid var(--black);
- height: 48px;
- box-sizing: border-box;
- }
-
- .tab {
- padding: 0.5em;
- background: var(--white);
- border-top-right-radius: 10px;
- border-top-left-radius: 10px;
- border-top: 1px solid grey;
- border-left: 1px solid grey;
- border-right: 1px solid grey;
- color: grey;
- cursor: pointer;
- transition: background 0.3s;
- position: relative;
- width: auto;
- min-width: 110px;
- max-width: 220px;
- overflow: hidden;
- zIndex: 2;
- }
-
- .tabCard {
- display: inline-block;
- }
-
- .tabTitle {
- display: inline-block;
- position: relative;
- width: auto;
- min-width: 1px;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- }
-
- .tab:hover {
- background: var(--nav-color-hover);
- color: var(--black);
- min-width: fit-content;
- }
-
- .tab.active {
- display: inline-block;
- min-width: fit-content;
- max-width: 200px;
- margin-bottom: -1px;
- background: var(--white);
- color: var(--black);
- border-top-right-radius: 10px;
- border-top-left-radius: 10px;
- border-top: 1px solid var(--black);
- border-left: 1px solid var(--black);
- border-right: 1px solid var(--black);
- border-bottom: 1px solid var(--white);
- zIndex: 1;
- }
-
- .close {
- position: absolute;
- top: 8px;
- right: 5px;
- color: var(--black);
- --mdc-icon-size: 20px;
- }
-
- .close:hover {
- color: #C6011F;
- font-weight: bold;
- }
-
- .tab .close,
- .tab .show {
- display: none;
- }
-
- .tab.active .close,
- .tab.active .show {
- display: inline-block;
- color: var(--black);
- }
-
- .tab:hover .close,
- .tab:hover .show {
- display: inline-block;
- color: var(--black);
- }
-
- .tab .close:hover,
- .tab.active .close:hover {
- color: #C6011F;
- font-weight: bold;
- }
-
- .add-tab-button {
- margin-left: 10px;
- font-weight: bold;
- background: none;
- border: none;
- color: #03a9f4;
- font-size: 2em;
- cursor: pointer;
- transition: color 0.3s;
- }
-
- .add-tab-button:hover {
- color: var(--black);
- }
-
- .iconActive {
- position: absolute;
- top: 5px;
- color: #03a9f4;
- --mdc-icon-size: 24px;
- }
-
- .iconInactive {
- position: absolute;
- top: 5px;
- color: #999;
- --mdc-icon-size: 24px;
- }
-
- .tab:hover .iconInactive {
- color: #03a9f4;
- }
-
- .count {
- position: relative;
- top: -5px;
- font-weight: bold;
- background-color: #C6011F;
- color: white;
- font-size: 12px;
- padding: 2px 6px;
- text-align: center;
- border-radius: 5px;
- animation: pulse 1500ms infinite;
- animation-duration: 6s;
- }
-
- .ml-5 {
- margin-left: 5px;
- }
-
- .ml-10 {
- margin-left: 10px;
- }
-
- .ml-15 {
- margin-left: 15px;
- }
-
- .ml-20 {
- margin-left: 20px;
- }
-
- .ml-25 {
- margin-left: 25px;
- }
-
- .ml-30 {
- margin-left: 30px;
- }
-
- .ml-35 {
- margin-left: 35px;
- }
-
- .ml-40 {
- margin-left: 40px;
- }
-
- @keyframes pulse {
- 0% {
- box-shadow:#C6011F 0 0 0 0;
- }
- 75% {
- box-shadow:#ff69b400 0 0 0 16px;
- }
- }
- `
- }
-
- constructor() {
- super()
- this.registeredUrls = []
- this.currentTab = 0
- this.tabs = []
- this.uid = new ShortUniqueId()
- this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
- this.tabInfo = {}
- this.chatLastSeen = []
- this.chatHeads = []
- }
-
- render() {
- const plugSrc = (myPlug) => {
- return myPlug === undefined ? 'about:blank' : `${window.location.origin}/plugin/${myPlug.domain}/${myPlug.page}${this.linkParam}`
- }
-
- return html`
-
- ${this.tabs.map((tab, index) => {
- let title = ''
- let icon = ''
- let count = 0
-
- if (tab.myPlugObj && tab.myPlugObj.title === "Overview Page") {
- title = html`${translate('tabmenu.tm28')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Minting Details") {
- title = html`${translate('tabmenu.tm1')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Become a Minter") {
- title = html`${translate('tabmenu.tm2')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Sponsorship List") {
- title = html`${translate('tabmenu.tm3')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Wallets") {
- title = html`${translate('tabmenu.tm4')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Trade Portal") {
- title = html`${translate('tabmenu.tm5')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Auto Buy") {
- title = html`${translate('tabmenu.tm6')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Reward Share") {
- title = html`${translate('tabmenu.tm7')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Q-Chat") {
- title = html`${translate('tabmenu.tm8')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Name Registration") {
- title = html`${translate('tabmenu.tm9')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Names Market") {
- title = html`${translate('tabmenu.tm10')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Websites") {
- title = html`${translate('tabmenu.tm11')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Q-Apps") {
- title = html`${translate('tabmenu.tm12')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Group Management") {
- title = html`${translate('tabmenu.tm13')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Data Management") {
- title = html`${translate('tabmenu.tm14')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Puzzles") {
- title = html`${translate('tabmenu.tm15')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Node Management") {
- title = html`${translate('tabmenu.tm16')}`
- } else if (tab.myPlugObj && tab.myPlugObj.url === "myapp") {
- title = tab.myPlugObj && tab.myPlugObj.title
- } else {
- title = html`${translate('tabmenu.tm17')}`
- }
-
- if (tab.myPlugObj && tab.myPlugObj.mwcicon) {
- icon = tab.myPlugObj.mwcicon
- } else {
- icon = 'tab'
- }
-
- if (tab.myPlugObj && (tab.myPlugObj.url === 'websites' || tab.myPlugObj.url === 'qapps') && this.tabInfo[tab.id]) {
- title = this.tabInfo[tab.id].name
- }
-
- if (tab.myPlugObj && (tab.myPlugObj.url === 'websites' || tab.myPlugObj.url === 'qapps') && this.tabInfo[tab.id]) {
- count = this.tabInfo[tab.id].count
- }
-
- if (tab.myPlugObj && tab.myPlugObj.url === 'q-chat') {
- for (const chat of this.chatHeads) {
-
- const lastReadMessage = this.chatLastSeen.find((ch) => {
- let id
- if (chat.groupId === 0) {
- id = chat.groupId
- } else if (chat.groupId) {
- id = chat.groupId
- } else {
- id = chat.address
- }
- return ch.key.includes(id)
- })
- if (lastReadMessage && lastReadMessage.timestamp < chat.timestamp) {
- count = count + 1
- }
- }
- }
-
- return html`
-
this.currentTab = index}"
- >
-
- ${icon}
-
-
- ${count ? html`
- ${title}
- ${count}
- {this.removeTab(index, tab.id)}}>close
- ` : html`
- ${title}
- {this.removeTab(index, tab.id)}}>close
- `}
-
-
- `
- })}
-
-
-
- ${repeat(this.tabs, (tab) => tab.id, (tab, index) => html`
-
-
- this.changePage(val)}
- >
-
-
- `)}
- `
- }
-
- firstUpdated() {
- this.changeLanguage()
-
- this.tabs.forEach((tab, index) => {
- const frame = this.shadowRoot.getElementById(`showPluginFrame${index}`)
- this.createEpmlInstance(frame, index)
- })
-
- window.addEventListener('storage', () => {
- const checkLanguage = localStorage.getItem('qortalLanguage')
- const checkTheme = localStorage.getItem('qortalTheme')
-
- use(checkLanguage)
-
- if (checkTheme === 'dark') {
- this.theme = 'dark'
- } else {
- this.theme = 'light'
- }
- document.querySelector('html').setAttribute('theme', this.theme)
- })
- }
-
- changeLanguage() {
- const checkLanguage = localStorage.getItem('qortalLanguage')
-
- if (checkLanguage === null || checkLanguage.length === 0) {
- localStorage.setItem('qortalLanguage', 'us')
- use('us')
- } else {
- use(checkLanguage)
- }
- }
-
- async getUpdateComplete() {
- await super.getUpdateComplete()
- return true
- }
-
- async addTab(tab) {
- if (this.tabs == []) {
- // ...Nothing to do
- } else {
- this.tabs.forEach((rac, index) => {
- let racId = ''
- let tabRacId = ''
- let frameRacId = ''
- let plugRacId = ''
- let iconRacId = ''
-
- racId = rac.id
- tabRacId = 'tab-' + racId
- frameRacId = 'frame-' + racId
- plugRacId = 'plug-' + racId
- iconRacId = 'icon-' + racId
-
- const plugObjRac = rac.url
-
- var tabActiveRac = this.shadowRoot.getElementById(tabRacId)
- var frameActiveRac = this.shadowRoot.getElementById(frameRacId)
- var plugActiveRac = this.shadowRoot.getElementById(plugRacId)
- var iconActiveRac = this.shadowRoot.getElementById(iconRacId)
-
- if (plugObjRac === undefined || "") {
- tabActiveRac.classList.remove("active")
- iconActiveRac.classList.remove("iconActive")
- iconActiveRac.classList.add("iconInactive")
- plugActiveRac.classList.remove("showIframe")
- plugActiveRac.classList.add("hideIframe")
- } else {
- tabActiveRac.classList.remove("active")
- iconActiveRac.classList.remove("iconActive")
- iconActiveRac.classList.add("iconInactive")
- frameActiveRac.classList.remove("showIframe")
- frameActiveRac.classList.add("hideIframe")
- }
- })
- }
-
- this.tabs = [...this.tabs, tab]
- await this.getUpdateComplete()
-
- // add the new tab to the tabs array
- const newIndex = this.tabs.length - 1
-
- // render the tab and wait for it to be added to the DOM
- const frame = this.shadowRoot.getElementById(`showPluginFrame${newIndex}`)
- this.createEpmlInstance(frame, newIndex)
- }
-
- removeTab(index, tabA) {
- const tabB = this.tabs.length - 1
- const tabC = this.tabs[tabB].id
-
- if (tabC === tabA) {
- let theId = ''
- let tabId = ''
- let frameId = ''
- let plugId = ''
- let iconId = ''
-
- this.tabs = this.tabs.filter((tab, tIndex) => tIndex !== index)
-
- const tabD = this.tabs.length - 1
- const plugObj = this.tabs[tabD].url
-
- theId = this.tabs[tabD].id
- tabId = 'tab-' + theId
- frameId = 'frame-' + theId
- plugId = 'plug-' + theId
- iconId = 'icon-' + theId
-
- var tabActive = this.shadowRoot.getElementById(tabId)
- var frameActive = this.shadowRoot.getElementById(frameId)
- var plugActive = this.shadowRoot.getElementById(plugId)
- var iconActive = this.shadowRoot.getElementById(iconId)
-
- if (plugObj === undefined || "") {
- tabActive.classList.add("active")
- iconActive.classList.remove("iconInactive")
- iconActive.classList.add("iconActive")
- plugActive.classList.remove("hideIframe")
- plugActive.classList.add("showIframe")
- } else {
- tabActive.classList.add("active")
- iconActive.classList.remove("iconInactive")
- iconActive.classList.add("iconActive")
- frameActive.classList.remove("hideIframe")
- frameActive.classList.add("showIframe")
- }
- this.requestUpdate()
- } else {
- // Remove tab from array
- this.tabs = this.tabs.filter((tab, tIndex) => tIndex !== index)
-
- if (this.tabs.length !== 0) {
- this.currentTab = 0
- }
- this.requestUpdate()
- }
- }
-
- createEpmlInstance(frame, index) {
- const showingPluginEpml = new Epml({
- type: 'WINDOW',
- source: frame.contentWindow
- })
-
- addPluginRoutes(showingPluginEpml);
- showingPluginEpml.imReady()
-
- // store Epml instance in tab for later use
- this.tabs[index].epmlInstance = showingPluginEpml
-
- // Register each instance with a unique identifier
- Epml.registerProxyInstance(`visible-plugin-${index}`, showingPluginEpml)
- }
-
- updated(changedProps) {
- if (changedProps.has('url') || changedProps.has('registeredUrls')) {
- const plugArr = []
-
- this.registeredUrls.forEach(myPlugArr => {
- myPlugArr.menus.length === 0 ? plugArr.push(myPlugArr) : myPlugArr.menus.forEach(i => plugArr.push(myPlugArr, i))
- })
-
- const myPlugObj = plugArr.find(pagePlug => {
- return pagePlug.url === this.url
- })
-
- if (this.tabs.length === 0) {
- this.addTab({
- url: this.url,
- myPlugObj,
- id: this.uid()
- })
- } else {
- const copiedTabs = [...this.tabs]
- copiedTabs[this.currentTab] = {
- ...copiedTabs[this.currentTab],
- url: this.url,
- myPlugObj
- }
- this.tabs = copiedTabs
- }
- this.requestUpdate()
- }
-
- if (changedProps.has('computerUrl')) {
- if (this.computedUrl !== 'about:blank') {
- this.loading = true
- }
- }
- }
-
- changePage(page) {
- const copiedTabs = [...this.tabs]
- copiedTabs[this.currentTab] = {
- ...copiedTabs[this.currentTab],
- myPlugObj: page,
- url: page.url
- }
- this.tabs = copiedTabs
- }
-
- async stateChanged(state) {
- const split = state.app.url.split('/')
- const newRegisteredUrls = state.app.registeredUrls
-
- let newUrl, newLinkParam
-
- if (newRegisteredUrls !== this.registeredUrls) {
- this.registeredUrls = newRegisteredUrls
- }
-
- if (split[0] === '' && split[1] === 'app' && split[2] === undefined) {
- newUrl = 'wallet'
- newLinkParam = ''
- } else if (split.length === 5 && split[1] === 'app') {
- newUrl = split[2]
- newLinkParam = split[3] === undefined ? '' : '?' + split[3] + '/' + split[4]
- } else if (split[1] === 'app') {
- newUrl = split[2]
- newLinkParam = ''
- } else {
- newUrl = '404'
- newLinkParam = ''
- }
-
- if (newUrl !== this.url) {
- this.url = newUrl
- }
-
- if (newLinkParam !== this.linkParam) {
- this.linkParam = newLinkParam
- }
- if (this.tabInfo !== state.app.tabInfo) {
- this.tabInfo = state.app.tabInfo
- }
- if (this.chatLastSeen !== state.app.chatLastSeen) {
- this.chatLastSeen = state.app.chatLastSeen
- }
- if (state.app.chatHeads !== this.unModifiedChatHeads) {
- let chatHeads = []
- if (state.app.chatHeads && state.app.chatHeads.groups) {
- chatHeads = [...chatHeads, ...state.app.chatHeads.groups]
- }
- if (state.app.chatHeads && state.app.chatHeads.direct) {
- chatHeads = [...chatHeads, ...state.app.chatHeads.direct]
- }
- this.chatHeads = chatHeads
- this.unModifiedChatHeads = state.app.chatHeads
- }
-
- if (state.app.newTab) {
- const newTab = state.app.newTab
- if (!this.tabs.find((tab) => tab.id === newTab.id)) {
- this.addTab(newTab)
- this.currentTab = this.tabs.length - 1
- store.dispatch(setNewTab(null))
- //clear newTab
- } else {
- const findIndex = this.tabs.findIndex((tab) => tab.id === newTab.id)
- if (findIndex !== -1) {
- const copiedTabs = [...this.tabs]
- copiedTabs[findIndex] = newTab
- this.tabs = copiedTabs
- this.currentTab = findIndex
- }
-
- store.dispatch(setNewTab(null))
- //clear newTab
- }
- }
- }
-}
-
-window.customElements.define('show-plugin', ShowPlugin)
-
-class NavBar extends connect(store)(LitElement) {
- static get properties() {
- return {
- menuList: { type: Array },
- newMenuList: { type: Array },
- myMenuList: { type: Array },
- myMenuPlugins: { type: Array },
- myApps: { type: Array },
- addressInfo: { type: Object },
- changePage: { attribute: false },
- pluginName: { type: String },
- pluginType: { type: String },
- pluginPage: { type: String },
- mwcIcon: { type: String },
- pluginNameToDelete: { type: String },
- pluginNumberToDelete: { type: String },
- textFieldDisabled: { type: Boolean },
- initialName: { type: String },
- newId: { type: String },
- removeTitle: { type: String },
- myFollowedNames: { type: Array },
- myFollowedNamesList: { type: Array },
- searchNameContentString: { type: String },
- searchNameResources: { type: Array }
- }
- }
-
- static styles = css`
- * {
- --mdc-theme-primary: rgb(3, 169, 244);
- --mdc-theme-surface: var(--white);
- --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-dialog-content-ink-color: var(--black);
- --mdc-dialog-shape-radius: 25px;
- --mdc-dialog-min-width: 300px;
- --mdc-dialog-max-width: 700px;
- }
-
- .parent {
- display: flex;
- flex-direction: column;
- flex-flow: column;
- align-items: center;
- padding: 20px;
- height: 100vh;
- overflow-y: auto;
- }
-
- .navbar {
- display: flex;
- justify-content: space-between;
- align-items: center;
- background-color: color: var(--white);
- padding: 10px 20px;
- max-width: 750px;
- width: 80%;
- }
-
- .navbar input {
- font-size: 16px;
- color: #000;
- padding: 5px;
- flex-grow: 1;
- margin-right: 10px;
- border: 1px solid var(--black);
- }
-
- .navbar button {
- padding: 5px 10px;
- font-size: 18px;
- background-color: var(--app-background-1);
- background-image: linear-gradient(315deg, var(--app-background-1) 0%, var(--app-background-2) 74%);
- color: var(--app-icon);
- border: 1px solid transparent;
- border-radius: 3px;
- cursor: pointer;
- }
-
- .navbar button:hover {
- background-color: #45a049;
- }
-
- .app-list {
- display: flex;
- justify-content: space-between;
- padding: 10px 0;
- gap: 10px;
- flex-wrap: wrap;
- }
-
- .app-list .app-icon {
- text-align: center;
- font-size: 15px;
- font-weight: bold;
- color: var(--black);
- width: 175px;
- height: 110px;
- background: transparent;
- padding: 5px;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- gap: 10px;
- }
-
- .text {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- display: block;
- width: 100%;
- min-width: 1px;
- }
-
- .app-list .app-icon span {
- display: block;
- }
-
- .app-icon-box {
- display: flex;
- align-items: center;
- padding-left: 14px;
- width: 80px;
- min-width: 80px;
- height: 80px;
- min-height: 80px;
- background-color: var(--app-background-1);
- background-image: linear-gradient(315deg, var(--app-background-1) 0%, var(--app-background-2) 74%);
- border-top-left-radius: 10px;
- border-top-right-radius: 20px;
- border-bottom-left-radius: 20px;
- border-bottom-right-radius: 10px;
- }
-
- .menuIcon {
- color: var(--app-icon);
- --mdc-icon-size: 64px;
- cursor: pointer;
- }
-
- .menuIconPos {
- position: relative;
- right: 26px;
- }
-
- .removeIcon {
- color: var(--black);
- --mdc-icon-size: 28px;
- cursor: pointer;
- }
-
- .removeIcon:hover {
- color: #C6011F;
- font-weight: bold;
- }
-
- .removeIconPos {
- position: relative;
- top: -36px;
- left: 62px;
- }
-
- .red {
- --mdc-theme-primary: #F44336;
- }
-
- select {
- padding: 10px 10px 10px 10px;
- width: 100%;
- font-size: 16px;
- font-weight: 500;
- background: var(--white);
- color: var(--black);
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none;
- background-image: url('/img/arrow.png');
- background-repeat: no-repeat;
- background-position: right 10px center;
- background-size: 20px;
- }
-
- .resetIcon {
- position: fixed;
- right: 20px;
- top: 116px;
- color: #666;
- --mdc-icon-size: 32px;
- cursor: pointer;
- }
-
- .resetIcon:hover {
- color: #03a9f4;
- font-weight: bold;
- }
-
- .searchIcon {
- position: fixed;
- left: 20px;
- top: 116px;
- color: #666;
- --mdc-icon-size: 32px;
- cursor: pointer;
- }
-
- .searchIcon:hover {
- color: #03a9f4;
- font-weight: bold;
- }
-
- .importIcon {
- position: fixed;
- left: 20px;
- bottom: 16px;
- color: #666;
- --mdc-icon-size: 32px;
- cursor: pointer;
- }
-
- .importIcon:hover {
- color: #03a9f4;
- font-weight: bold;
- }
-
- .exportIcon {
- position: fixed;
- right: 20px;
- bottom: 16px;
- color: #666;
- --mdc-icon-size: 32px;
- cursor: pointer;
- }
-
- .exportIcon:hover {
- color: #03a9f4;
- font-weight: bold;
- }
-
- paper-dialog.searchSettings {
- width: 100%;
- max-width: 550px;
- height: auto;
- max-height: 600px;
- background-color: var(--white);
- color: var(--black);
- line-height: 1.6;
- overflow: hidden;
- border: 1px solid var(--black);
- border-radius: 10px;
- padding: 15px;
- }
-
- paper-dialog button {
- padding: 5px 10px;
- font-size: 18px;
- background-color: #03a9f4;
- color: white;
- border: 1px solid transparent;
- border-radius: 5px;
- cursor: pointer;
- }
-
- paper-dialog button:hover {
- opacity: 0.8;
- cursor: pointer;
- }
-
- .search {
- display: inline;
- width: 50%;
- align-items: center;
- }
-
- .divCard {
- height: auto;
- max-height: 500px;
- border: 1px solid var(--border);
- padding: 1em;
- margin-bottom: 1em;
- }
-
- img {
- border-radius: 25%;
- max-width: 32px;
- height: 100%;
- max-height: 32px;
- }
-
- vaadin-text-field[focused]::part(input-field) {
- border-color: #03a9f4;
- }
- `
-
- constructor() {
- super()
- this.menuList = []
- this.newMenuList = []
- this.myMenuList = []
- this.myMenuPlugins = []
- this.addressInfo = {}
- this.pluginName = ''
- this.pluginType = ''
- this.pluginPage = ''
- this.myApps = ''
- this.mwcIcon = ''
- this.pluginNameToDelete = ''
- this.pluginNumberToDelete = ''
- this.textFieldDisabled = false
- this.initialName = ''
- this.newId = ''
- this.removeTitle = ''
- this.myFollowedNames = []
- this.myFollowedNamesList = []
- this.searchContentString = ''
- this.searchNameResources = []
- }
-
- render() {
- return html`
-
-
this.resetMenu()}" title="${translate("tabmenu.tm29")}">reset_tv
-
this.openNameSearch()}" title="${translate("tabmenu.tm30")}">person_search
-
this.openImportDialog()}" title="${translate("tabmenu.tm33")}">upload
-
this.exportTabMenu()}" title="${translate("tabmenu.tm34")}">download
-
-
-
-
-
- ${repeat(this.myMenuList, (plugin) => plugin.url, (plugin, index) => html`
-
-
- ${this.renderRemoveIcon(plugin.url, plugin.mwcicon, plugin.title, plugin.pluginNumber, plugin)}
-
- ${this.renderTitle(plugin.url, plugin.title)}
-
- `)}
-
this.openAddNewPlugin()}">
-
-
-
-
${translate("tabmenu.tm19")}
-
-
-
-
-
-
${translate("tabmenu.tm26")}
-
-
-
- ${translate("tabmenu.tm24")}
-
-
-
-
-
-
-
- ${translate("tabmenu.tm19")}
-
-
- ${translate("general.close")}
-
-
-
-
-
${translate("tabmenu.tm27")}
-
-
- ${translate("tabmenu.tm23")}
- ${this.removeTitle}
-
- ${translate("general.yes")}
-
-
- ${translate("general.no")}
-
-
-
-
-
-
-
-
this.searchNameResult()}" title="${translate("websitespage.schange35")}">
-
this.closeNameSearch()}" title="${translate("general.close")}">
-
-
-
-
- {
- render(html`${this.renderNameAvatar(data.item)}`, root)
- }}
- >
-
- {
- render(html`${data.item.name}`, root)
- }}
- >
-
- {
- render(html`${this.renderMyFollowUnfollowButton(data.item)}`, root)
- }}
- >
-
-
- ${this.isEmptyArray(this.searchNameResources) ? html`
- ${translate("login.entername")}
- `: ''}
-
-
-
-
-
-
-
-
${translate("tabmenu.tm31")}
-
-
-
-
- {
- render(html`${this.renderNameAvatar(data.item)}`, root)
- }}
- >
-
- {
- render(html`${data.item.name}`, root)
- }}
- >
-
- {
- render(html`${this.renderMyFollowUnfollowButton(data.item)}`, root)
- }}
- >
-
-
- ${this.isEmptyArray(this.myFollowedNamesList) ? html`
- ${translate("tabmenu.tm32")}
- `: ''}
-
-
-
-
-
-
-
- `
- }
-
- async firstUpdated() {
- addPluginRoutes(parentEpml)
- parentEpml.imReady()
-
- const addressInfo = this.addressInfo
- const isMinter = addressInfo?.error !== 124 && +addressInfo?.level > 0
- const isSponsor = +addressInfo?.level >= 5
- const appDelay = ms => new Promise(res => setTimeout(res, ms))
-
- await appDelay(50)
-
- await this.checkMyMenuPlugins()
-
- if (!isMinter) {
- this.newMenuList = this.myMenuPlugins.filter((minter) => {
- return minter.url !== 'minting'
- })
- } else {
- this.newMenuList = this.myMenuPlugins.filter((minter) => {
- return minter.url !== 'become-minter'
- })
- }
-
- if (!isSponsor) {
- this.myMenuList = this.newMenuList.filter((sponsor) => {
- return sponsor.url !== 'sponsorship-list'
- })
- } else {
- this.myMenuList = this.newMenuList
- }
-
- await this.getMyFollowedNames()
- await this.getMyFollowedNamesList()
- }
-
- openImportDialog() {
- this.shadowRoot.getElementById('importTabMenutDialog').show()
- }
-
- importTabMenu(file) {
- this.myMenuPlugins = []
- let myFile = ''
- localStorage.removeItem("myMenuPlugs")
- myFile = file
- const newTabMenu = JSON.parse((myFile) || "[]")
- localStorage.setItem("myMenuPlugs", JSON.stringify(newTabMenu))
- this.shadowRoot.getElementById('importTabMenutDialog').close()
- this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
- this.firstUpdated()
-
- let success5string = get("tabmenu.tm36")
- parentEpml.request('showSnackBar', `${success5string}`)
- }
-
- exportTabMenu() {
- let tabMenu = ""
- const qortalTabMenu = JSON.stringify(localStorage.getItem("myMenuPlugs"))
- const qortalTabMenuSave = JSON.parse((qortalTabMenu) || "[]")
- const blob = new Blob([qortalTabMenuSave ], { type: 'text/plain;charset=utf-8' })
- tabMenu = "qortal.tabmenu"
- this.saveFileToDisk(blob, tabMenu)
- }
-
- 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("tabmenu.tm37")
- parentEpml.request('showSnackBar', `${snack4string} ${fileName}`)
- } catch (error) {
- if (error.name === 'AbortError') {
- return
- }
- FileSaver.saveAs(blob, fileName)
- let snack4string = get("tabmenu.tm37")
- parentEpml.request('showSnackBar', `${snack4string} ${fileName}`)
- }
- }
-
- openNameSearch() {
- this.searchNameResources = []
- this.shadowRoot.getElementById('searchNameContent').value = ''
- this.shadowRoot.getElementById('myFollowedNamesDialog').close()
- this.shadowRoot.getElementById('searchNameDialog').open()
- }
-
- closeNameSearch() {
- this.shadowRoot.getElementById('searchNameDialog').close()
- }
-
- openMyFollowedNames() {
- this.shadowRoot.getElementById('searchNameDialog').close()
- this.shadowRoot.getElementById('myFollowedNamesDialog').open()
- this.getMyFollowedNamesList()
- }
-
- closeMyFollowedNames() {
- this.shadowRoot.getElementById('myFollowedNamesDialog').close()
- }
-
- async getMyFollowedNames() {
- let myFollowedNames = await parentEpml.request('apiCall', {
- url: `/lists/followedNames?apiKey=${this.getApiKey()}`
- })
-
- this.myFollowedNames = myFollowedNames
- }
-
- searchNameKeyListener(e) {
- if (e.key === 'Enter') {
- this.searchNameResult()
- }
- }
-
- async getMyFollowedNamesList() {
- const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
- const myNodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
- const followedNamesUrl = `${myNodeUrl}/lists/followedNames?apiKey=${this.getApiKey()}`
-
- var myFollowedNamesNew = []
-
- this.myFollowedNamesList = []
-
- await fetch(followedNamesUrl).then(response => {
- return response.json()
- }).then(data => {
- return data.map(item => {
- const addListName = {
- name: item
- }
- myFollowedNamesNew.push(addListName)
- })
- })
- this.myFollowedNamesList = myFollowedNamesNew
- if(this.shadowRoot.getElementById('myFollowedNamesDialog').opened) {
- this.shadowRoot.getElementById('myFollowedNamesDialog').notifyResize()
- }
- }
-
- async searchNameResult() {
- let searchMyName = this.shadowRoot.getElementById('searchNameContent').value
- if (searchMyName.length === 0) {
- let err1string = get("appspage.schange34")
- parentEpml.request('showSnackBar', `${err1string}`)
- } else {
- let searchNameResources = await parentEpml.request('apiCall', {
- url: `/names/search?query=${searchMyName}&prefix=true&limit=0&reverse=true`
- })
- if (this.isEmptyArray(searchNameResources)) {
- let err2string = get("appspage.schange17")
- parentEpml.request('showSnackBar', `${err2string}`)
- } else {
- this.searchNameResources = searchNameResources
- if(this.shadowRoot.getElementById('searchNameDialog').opened) {
- this.shadowRoot.getElementById('searchNameDialog').notifyResize()
- }
- }
- }
- }
-
- renderNameAvatar(nameObj) {
- let myName = nameObj.name
- const myNameNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
- const myNodeUrl = myNameNode.protocol + '://' + myNameNode.domain + ':' + myNameNode.port
- const nameUrl = `${myNodeUrl}/arbitrary/THUMBNAIL/${myName}/qortal_avatar?async=true`
- return html`
`
- }
-
- renderMyFollowUnfollowButton(nameObj) {
- let name = nameObj.name
-
- if (this.myFollowedNames == null || !Array.isArray(this.myFollowedNames)) {
- return html``
- }
-
- if (this.myFollowedNames.indexOf(name) === -1) {
- return html` this.myFollowName(nameObj)}>add_to_queue ${translate("appspage.schange29")}`
- } else {
- return html` this.myUnfollowName(nameObj)}>remove_from_queue ${translate("appspage.schange30")}`
- }
- }
-
- async myFollowName(nameObj) {
- let name = nameObj.name
- let items = [
- name
- ]
- let namesJsonString = JSON.stringify({ "items": items })
-
- let ret = await parentEpml.request('apiCall', {
- url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: `${namesJsonString}`
- })
-
- if (ret === true) {
- this.myFollowedNames = this.myFollowedNames.filter(item => item != name)
- this.myFollowedNames.push(name)
- } else {
- let err3string = get("appspage.schange22")
- parentEpml.request('showSnackBar', `${err3string}`)
- }
- this.getMyFollowedNamesList()
- return ret
- }
-
- async myUnfollowName(nameObj) {
- let name = nameObj.name
- let items = [
- name
- ]
- let namesJsonString = JSON.stringify({ "items": items })
-
- let ret = await parentEpml.request('apiCall', {
- url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
- method: 'DELETE',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: `${namesJsonString}`
- })
-
- if (ret === true) {
- this.myFollowedNames = this.myFollowedNames.filter(item => item != name)
- } else {
- let err4string = get("appspage.schange23")
- parentEpml.request('showSnackBar', `${err4string}`)
- }
- this.getMyFollowedNamesList()
- return ret
- }
-
- async checkMyMenuPlugins() {
- const appDelay = ms => new Promise(res => setTimeout(res, ms))
-
- if (localStorage.getItem("myMenuPlugs") === null) {
- await appDelay(1000)
- const myObj = JSON.stringify(this.menuList)
- localStorage.setItem("myMenuPlugs", myObj)
- this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
- } else {
- this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
- }
- }
-
- resetMenu() {
- localStorage.removeItem("myMenuPlugs")
- this.firstUpdated()
- }
-
- val() {
- const theValue = this.shadowRoot.getElementById("pluginTypeInput").value
-
- if (theValue === "reject") {
- this.textFieldDisabled = false
- this.initialName = ''
- this.mwcIcon = ''
- } else if (theValue === "0") {
- this.textFieldDisabled = false
- this.initialName = ''
- this.mwcIcon = ''
- } else if (theValue === "1") {
- this.textFieldDisabled = false
- this.initialName = ''
- this.mwcIcon = ''
- } else if (theValue === 'overview-page') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Overview Page'
- this.mwcIcon = 'home'
- } else if (theValue === 'minting') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Minting Details'
- this.mwcIcon = 'info_outline'
- } else if (theValue === 'become-minter') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Become a Minter'
- this.mwcIcon = 'thumb_up'
- } else if (theValue === 'sponsorship-list') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Sponsorship List'
- this.mwcIcon = 'format_list_numbered'
- } else if (theValue === 'wallet') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Wallets'
- this.mwcIcon = 'account_balance_wallet'
- } else if (theValue === 'trade-portal') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Trade Portal'
- this.mwcIcon = 'format_list_bulleted'
- } else if (theValue === 'trade-bot-portal') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Auto Buy'
- this.mwcIcon = 'shop'
- } else if (theValue === 'reward-share') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Reward Share'
- this.mwcIcon = 'ios_share'
- } else if (theValue === 'q-chat') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Q-Chat'
- this.mwcIcon = 'forum'
- } else if (theValue === 'name-registration') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Name Registration'
- this.mwcIcon = 'manage_accounts'
- } else if (theValue === 'names-market') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Names Market'
- this.mwcIcon = 'store'
- } else if (theValue === 'websites') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Websites'
- this.mwcIcon = 'desktop_mac'
- } else if (theValue === 'qapps') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Q-Apps'
- this.mwcIcon = 'apps'
- } else if (theValue === 'group-management') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Group Management'
- this.mwcIcon = 'group'
- } else if (theValue === 'data-management') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Data Management'
- this.mwcIcon = 'storage'
- } else if (theValue === 'puzzles') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Puzzles'
- this.mwcIcon = 'extension'
- } else if (theValue === 'node-management') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Node Management'
- this.mwcIcon = 'cloud'
- }
- }
-
- filterSelectMenu() {
- const addressInfoSelect = this.addressInfo
- const isMinterSelect = addressInfoSelect?.error !== 124 && +addressInfoSelect?.level > 0
- const isSponsorSelect = +addressInfoSelect?.level >= 5
-
- if (!isMinterSelect) {
- return html`
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `
- } else if (isMinterSelect && isSponsorSelect) {
- return html`
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `
- } else {
- return html`
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `
- }
- }
-
- openAddNewPlugin() {
- this.shadowRoot.getElementById("pluginTypeInput").value = 'reject'
- this.shadowRoot.getElementById("pluginNameInput").value = ''
- this.initialName = ''
- this.textFieldDisabled = false
- this.shadowRoot.querySelector('#addNewPlugin').show()
- }
-
- async addToMyMenuPlugins() {
- this.newId = ''
- const newUid = new ShortUniqueId({ length: 10 })
- this.newId = 'plugin-' + newUid()
-
- this.pluginType = this.shadowRoot.getElementById("pluginTypeInput").value
-
- if (this.pluginType === "reject") {
- let myplugerr = get("tabmenu.tm25")
- parentEpml.request('showSnackBar', `${myplugerr}`)
- return false
- } else if (this.pluginType === "0") {
- this.mwcIcon = ''
- this.pluginName = this.shadowRoot.getElementById('pluginNameInput').value
-
- if (this.pluginName === "Q-Blog") {
- this.mwcIcon = 'rss_feed'
- } else if (this.pluginName === "Q-Mail") {
- this.mwcIcon = 'mail'
- } else {
- this.mwcIcon = 'apps'
- }
-
- var oldMenuPlugs = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
-
- const newMenuPlugsItem = {
- "url": "myapp",
- "domain": "core",
- "page": `qdn/browser/index.html?name=${this.pluginName}&service=APP`,
- "title": this.pluginName,
- "icon": "vaadin:external-browser",
- "mwcicon": this.mwcIcon,
- "pluginNumber": this.newId,
- "menus": [],
- "parent": false
- }
-
- const validatePluginName = async () => {
- if (this.pluginType === "0" && this.pluginName.length == 0) {
- let myplugstring1 = get("walletpage.wchange50")
- parentEpml.request('showSnackBar', `${myplugstring1}`)
- return false
- }
-
- let myPluginName = false
- this.myPluginNameRes = []
-
- await parentEpml.request('apiCall', {
- url: `/arbitrary/resources/search?service=APP&query=${this.pluginName}&exactmatchnames=true&limit=1`
- }).then(res => {
- this.myPluginNameRes = res
- })
-
- if (this.myPluginNameRes === undefined || this.myPluginNameRes.length == 0) {
- myPluginName = false
- } else {
- myPluginName = true
- }
- return myPluginName
- }
-
- let myNameRes = await validatePluginName()
-
- if (myNameRes !== false) {
- oldMenuPlugs.push(newMenuPlugsItem)
-
- localStorage.setItem("myMenuPlugs", JSON.stringify(oldMenuPlugs))
-
- let myplugstring2 = get("walletpage.wchange52")
- parentEpml.request('showSnackBar', `${myplugstring2}`)
-
- this.closeAddNewPlugin()
-
- this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
- this.firstUpdated()
- } else {
- let myplugstring3 = get("websitespage.schange17")
- parentEpml.request('showSnackBar', `${myplugstring3}`)
- return false
- }
- } else if (this.pluginType === "1") {
- this.mwcIcon = ''
- this.pluginName = this.shadowRoot.getElementById('pluginNameInput').value
-
- this.mwcIcon = 'web'
-
- var oldMenuPlugs = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
-
- const newMenuPlugsItem = {
- "url": "myapp",
- "domain": "core",
- "page": `qdn/browser/index.html?name=${this.pluginName}&service=WEBSITE`,
- "title": this.pluginName,
- "icon": "vaadin:external-browser",
- "mwcicon": this.mwcIcon,
- "pluginNumber": this.newId,
- "menus": [],
- "parent": false
- }
-
- const validatePluginName = async () => {
- if (this.pluginType === "1" && this.pluginName.length == 0) {
- let myplugstring1 = get("walletpage.wchange50")
- parentEpml.request('showSnackBar', `${myplugstring1}`)
- return false
- }
-
- let myPluginName = false
- this.myPluginNameRes = []
-
- await parentEpml.request('apiCall', {
- url: `/arbitrary/resources/search?service=WEBSITE&query=${this.pluginName}&exactmatchnames=true&limit=1`
- }).then(res => {
- this.myPluginNameRes = res
- })
-
- if (this.myPluginNameRes === undefined || this.myPluginNameRes.length == 0 ) {
- myPluginName = false
- } else {
- myPluginName = true
- }
- return myPluginName
- }
-
- let myNameRes = await validatePluginName()
-
- if (myNameRes !== false) {
- oldMenuPlugs.push(newMenuPlugsItem)
-
- localStorage.setItem("myMenuPlugs", JSON.stringify(oldMenuPlugs))
-
- let myplugstring2 = get("walletpage.wchange52")
- parentEpml.request('showSnackBar', `${myplugstring2}`)
-
- this.closeAddNewPlugin()
-
- this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
- this.firstUpdated()
- } else {
- let myplugstring3 = get("websitespage.schange17")
- parentEpml.request('showSnackBar', `${myplugstring3}`)
- return false
- }
- } else {
- this.pluginPage = ''
- if (this.pluginType === 'overview-page') {
- this.pluginPage = 'overview-page/index.html'
- } else if (this.pluginType === 'minting') {
- this.pluginPage = 'minting/index.html'
- } else if (this.pluginType === 'become-minter') {
- this.pluginPage = 'become-minter/index.html'
- } else if (this.pluginType === 'sponsorship-list') {
- this.pluginPage = 'sponsorship-list/index.html'
- } else if (this.pluginType === 'wallet') {
- this.pluginPage = 'wallet/index.html'
- } else if (this.pluginType === 'trade-portal') {
- this.pluginPage = 'trade-portal/index.html'
- } else if (this.pluginType === 'trade-bot-portal') {
- this.pluginPage = 'trade-bot/index.html'
- } else if (this.pluginType === 'reward-share') {
- this.pluginPage = 'reward-share/index.html'
- } else if (this.pluginType === 'q-chat') {
- this.pluginPage = 'messaging/q-chat/index.html'
- } else if (this.pluginType === 'name-registration') {
- this.pluginPage = 'name-registration/index.html'
- } else if (this.pluginType === 'names-market') {
- this.pluginPage = 'names-market/index.html'
- } else if (this.pluginType === 'websites') {
- this.pluginPage = 'qdn/index.html'
- } else if (this.pluginType === 'qapps') {
- this.pluginPage = 'q-app/index.html'
- } else if (this.pluginType === 'group-management') {
- this.pluginPage = 'group-management/index.html'
- } else if (this.pluginType === 'data-management') {
- this.pluginPage = 'qdn/data-management/index.html'
- } else if (this.pluginType === 'puzzles') {
- this.pluginPage = 'puzzles/index.html'
- } else if (this.pluginType === 'node-management') {
- this.pluginPage = 'node-management/index.html'
- }
-
- var oldMenuPlugs = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
-
- const newMenuPlugsItem = {
- "url": this.pluginType,
- "domain": "core",
- "page": this.pluginPage,
- "title": this.initialName,
- "icon": "vaadin:external-browser",
- "mwcicon": this.mwcIcon,
- "pluginNumber": this.newId,
- "menus": [],
- "parent": false
- }
-
- oldMenuPlugs.push(newMenuPlugsItem)
-
- localStorage.setItem("myMenuPlugs", JSON.stringify(oldMenuPlugs))
-
- let myplugstring2 = get("walletpage.wchange52")
- parentEpml.request('showSnackBar', `${myplugstring2}`)
-
- this.closeAddNewPlugin()
-
- this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
- this.firstUpdated()
- }
- }
-
- closeAddNewPlugin() {
- this.shadowRoot.querySelector('#addNewPlugin').close()
- this.shadowRoot.getElementById("pluginTypeInput").value = 'reject'
- this.shadowRoot.getElementById("pluginNameInput").value = ''
- this.initialName = ''
- this.textFieldDisabled = false
- }
-
- renderTitle(theUrl, theName) {
- if (theUrl === 'overview-page') {
- return html`${translate('tabmenu.tm28')}`
- } else if (theUrl === 'minting') {
- return html`${translate('tabmenu.tm1')}`
- } else if (theUrl === 'become-minter') {
- return html`${translate('tabmenu.tm2')}`
- } else if (theUrl === 'sponsorship-list') {
- return html`${translate('tabmenu.tm3')}`
- } else if (theUrl === 'wallet') {
- return html`${translate('tabmenu.tm4')}`
- } else if (theUrl === 'trade-portal') {
- return html`${translate('tabmenu.tm5')}`
- } else if (theUrl === 'trade-bot-portal') {
- return html`${translate('tabmenu.tm6')}`
- } else if (theUrl === 'reward-share') {
- return html`${translate('tabmenu.tm7')}`
- } else if (theUrl === 'q-chat') {
- return html`${translate('tabmenu.tm8')}`
- } else if (theUrl === 'name-registration') {
- return html`${translate('tabmenu.tm9')}`
- } else if (theUrl === 'names-market') {
- return html`${translate('tabmenu.tm10')}`
- } else if (theUrl === 'websites') {
- return html`${translate('tabmenu.tm11')}`
- } else if (theUrl === 'qapps') {
- return html`${translate('tabmenu.tm12')}`
- } else if (theUrl === 'group-management') {
- return html`${translate('tabmenu.tm13')}`
- } else if (theUrl === 'data-management') {
- return html`${translate('tabmenu.tm14')}`
- } else if (theUrl === 'puzzles') {
- return html`${translate('tabmenu.tm15')}`
- } else if (theUrl === 'node-management') {
- return html`${translate('tabmenu.tm16')}`
- } else {
- return html`${theName}`
- }
- }
-
- renderRemoveIcon(appurl, appicon, appname, appid, appplugin) {
- return html`
- this.openRemoveApp(appname, appid, appurl)}">
- backspace
-
-
- `
- }
-
- openRemoveApp(pluginNameTD, pluginNumberTD, pluginUrlTD) {
- this.pluginNameToDelete = ''
- this.pluginNameToDelete = pluginNameTD
- this.pluginNumberToDelete = ''
- this.pluginNumberToDelete = pluginNumberTD
- this.removeTitle = ''
- if (pluginUrlTD === 'overview-page') {
- this.removeTitle = html`${translate('tabmenu.tm28')}`
- } else if (pluginUrlTD === 'minting') {
- this.removeTitle = html`${translate('tabmenu.tm1')}`
- } else if (pluginUrlTD === 'become-minter') {
- this.removeTitle = html`${translate('tabmenu.tm2')}`
- } else if (pluginUrlTD === 'sponsorship-list') {
- this.removeTitle = html`${translate('tabmenu.tm3')}`
- } else if (pluginUrlTD === 'wallet') {
- this.removeTitle = html`${translate('tabmenu.tm4')}`
- } else if (pluginUrlTD === 'trade-portal') {
- this.removeTitle = html`${translate('tabmenu.tm5')}`
- } else if (pluginUrlTD === 'trade-bot-portal') {
- this.removeTitle = html`${translate('tabmenu.tm6')}`
- } else if (pluginUrlTD === 'reward-share') {
- this.removeTitle = html`${translate('tabmenu.tm7')}`
- } else if (pluginUrlTD === 'q-chat') {
- this.removeTitle = html`${translate('tabmenu.tm8')}`
- } else if (pluginUrlTD === 'name-registration') {
- this.removeTitle = html`${translate('tabmenu.tm9')}`
- } else if (pluginUrlTD === 'names-market') {
- this.removeTitle = html`${translate('tabmenu.tm10')}`
- } else if (pluginUrlTD === 'websites') {
- this.removeTitle = html`${translate('tabmenu.tm11')}`
- } else if (pluginUrlTD === 'qapps') {
- this.removeTitle = html`${translate('tabmenu.tm12')}`
- } else if (pluginUrlTD === 'group-management') {
- this.removeTitle = html`${translate('tabmenu.tm13')}`
- } else if (pluginUrlTD === 'data-management') {
- this.removeTitle = html`${translate('tabmenu.tm14')}`
- } else if (pluginUrlTD === 'puzzles') {
- this.removeTitle = html`${translate('tabmenu.tm15')}`
- } else if (pluginUrlTD === 'node-management') {
- this.removeTitle = html`${translate('tabmenu.tm16')}`
- } else {
- this.removeTitle = html`${pluginNameTD}`
- }
- this.shadowRoot.querySelector('#removePlugin').show()
- }
-
- removeAppFromArray() {
- const pluginToRemove = this.pluginNumberToDelete
- this.newMenuFilter = []
- this.newMenuFilter = this.myMenuList.filter((item) => item.pluginNumber !== pluginToRemove)
- const myNewObj = JSON.stringify(this.newMenuFilter)
- localStorage.removeItem("myMenuPlugs")
- localStorage.setItem("myMenuPlugs", myNewObj)
- this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
- this.firstUpdated()
- this.closeRemoveApp()
- }
-
- closeRemoveApp() {
- this.shadowRoot.querySelector('#removePlugin').close()
- this.pluginNameToDelete = ''
- this.pluginNumberToDelete = ''
- }
-
- async extractComponents(url) {
- if (!url.startsWith("qortal://")) {
- return null
- }
-
- url = url.replace(/^(qortal\:\/\/)/, "")
- if (url.includes("/")) {
- let parts = url.split("/")
- const service = parts[0].toUpperCase()
- parts.shift()
- const name = parts[0]
- parts.shift()
- let identifier
-
- if (parts.length > 0) {
- identifier = parts[0] // Do not shift yet
- // Check if a resource exists with this service, name and identifier combination
- const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
- const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
- const url = `${nodeUrl}/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${myNode.apiKey}}`
-
- const res = await fetch(url);
- 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
- }
-
- async getQuery(value) {
- let newQuery = value
- 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}`
- }
-
- if (service === "APP") {
- this.changePage({
- "url": "qapp",
- "domain": "core",
- "page": `qdn/browser/index.html${query}`,
- "title": "Q-App",
- "icon": "vaadin:external-browser",
- "mwcicon": "open_in_browser",
- "menus": [],
- "parent": false
- })
- } else if (service === "WEBSITE") {
- this.changePage({
- "url": "websites",
- "domain": "core",
- "page": `qdn/browser/index.html${query}`,
- "title": "Website",
- "icon": "vaadin:desktop",
- "mwcicon": "desktop_mac",
- "menus": [],
- "parent": false
- })
- }
- }
-
- async handlePasteLink(e) {
- try {
- const value = this.shadowRoot.getElementById('linkInput').value
- this.getQuery(value)
- } catch (error) {
- }
- }
-
- async _handleKeyDown(e) {
- if (e.key === 'Enter') {
- try {
- const value = this.shadowRoot.getElementById('linkInput').value
- this.getQuery(value)
- } catch (error) {
- }
- }
- }
-
- getApiKey() {
- const apiNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
- let apiKey = apiNode.apiKey
- return apiKey
- }
-
- isEmptyArray(arr) {
- if (!arr) { return true }
- return arr.length === 0
- }
-
- stateChanged(state) {
- this.menuList = state.app.registeredUrls
- this.addressInfo = state.app.accountInfo.addressInfo
- }
-}
-
-customElements.define('nav-bar', NavBar)
+import { LitElement, html, css } from 'lit'
+import { render } from 'lit/html.js'
+import { connect } from 'pwa-helpers'
+import { store } from '../store.js'
+import { Epml } from '../epml.js'
+import { addPluginRoutes } from '../plugins/addPluginRoutes.js'
+import { repeat } from 'lit/directives/repeat.js';
+import ShortUniqueId from 'short-unique-id';
+import { setNewTab } from '../redux/app/app-actions.js'
+import localForage from 'localforage'
+import FileSaver from 'file-saver'
+import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
+
+registerTranslateConfig({
+ loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
+})
+
+import '@material/mwc-button'
+import '@material/mwc-dialog'
+import '@material/mwc-icon'
+import '@material/mwc-textfield'
+import '@polymer/paper-icon-button/paper-icon-button.js'
+import '@polymer/iron-icons/iron-icons.js'
+import '@polymer/paper-dialog/paper-dialog.js'
+import '@vaadin/grid'
+import '@vaadin/text-field'
+import '../custom-elements/frag-file-input.js'
+
+const chatLastSeen = localForage.createInstance({
+ name: "chat-last-seen",
+})
+
+const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
+
+class ShowPlugin extends connect(store)(LitElement) {
+ static get properties() {
+ return {
+ app: { type: Object },
+ pluginConfig: { type: Object },
+ url: { type: String },
+ linkParam: { type: String },
+ registeredUrls: { type: Array },
+ currentTab: { type: Number },
+ tabs: { type: Array },
+ theme: { type: String, reflect: true },
+ tabInfo: { type: Object },
+ chatLastSeen: { type: Array },
+ chatHeads: { type: Array }
+ }
+ }
+
+ static get styles() {
+ return css`
+ html {
+ --scrollbarBG: #a1a1a1;
+ --thumbBG: #6a6c75;
+ }
+
+ *::-webkit-scrollbar {
+ width: 11px;
+ }
+
+ * {
+ scrollbar-width: thin;
+ scrollbar-color: var(--thumbBG) var(--scrollbarBG);
+ }
+
+ *::-webkit-scrollbar-track {
+ background: var(--scrollbarBG);
+ }
+
+ *::-webkit-scrollbar-thumb {
+ background-color: var(--thumbBG);
+ border-radius: 6px;
+ border: 3px solid var(--scrollbarBG);
+ }
+
+ .hideIframe {
+ display: none;
+ position: absolute;
+ zIndex: -10;
+ }
+
+ .showIframe {
+ display: block;
+ position: relative;
+ zIndex: 1;
+ }
+
+ .tabs {
+ display: flex;
+ width: 100%;
+ max-width: 100%;
+ justify-content: flex-start;
+ padding-top: 0.5em;
+ padding-left: 0.5em;
+ background: var(--sidetopbar);
+ border-bottom: 1px solid var(--black);
+ height: 48px;
+ box-sizing: border-box;
+ }
+
+ .tab {
+ padding: 0.5em;
+ background: var(--white);
+ border-top-right-radius: 10px;
+ border-top-left-radius: 10px;
+ border-top: 1px solid grey;
+ border-left: 1px solid grey;
+ border-right: 1px solid grey;
+ color: grey;
+ cursor: pointer;
+ transition: background 0.3s;
+ position: relative;
+ width: auto;
+ min-width: 110px;
+ max-width: 220px;
+ overflow: hidden;
+ zIndex: 2;
+ }
+
+ .tabCard {
+ display: inline-block;
+ }
+
+ .tabTitle {
+ display: inline-block;
+ position: relative;
+ width: auto;
+ min-width: 1px;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+
+ .tab:hover {
+ background: var(--nav-color-hover);
+ color: var(--black);
+ min-width: fit-content;
+ }
+
+ .tab.active {
+ display: inline-block;
+ min-width: fit-content;
+ max-width: 200px;
+ margin-bottom: -1px;
+ background: var(--white);
+ color: var(--black);
+ border-top-right-radius: 10px;
+ border-top-left-radius: 10px;
+ border-top: 1px solid var(--black);
+ border-left: 1px solid var(--black);
+ border-right: 1px solid var(--black);
+ border-bottom: 1px solid var(--white);
+ zIndex: 1;
+ }
+
+ .close {
+ position: absolute;
+ top: 8px;
+ right: 5px;
+ color: var(--black);
+ --mdc-icon-size: 20px;
+ }
+
+ .close:hover {
+ color: #C6011F;
+ font-weight: bold;
+ }
+
+ .tab .close,
+ .tab .show {
+ display: none;
+ }
+
+ .tab.active .close,
+ .tab.active .show {
+ display: inline-block;
+ color: var(--black);
+ }
+
+ .tab:hover .close,
+ .tab:hover .show {
+ display: inline-block;
+ color: var(--black);
+ }
+
+ .tab .close:hover,
+ .tab.active .close:hover {
+ color: #C6011F;
+ font-weight: bold;
+ }
+
+ .add-tab-button {
+ margin-left: 10px;
+ font-weight: bold;
+ background: none;
+ border: none;
+ color: #03a9f4;
+ font-size: 2em;
+ cursor: pointer;
+ transition: color 0.3s;
+ }
+
+ .add-tab-button:hover {
+ color: var(--black);
+ }
+
+ .iconActive {
+ position: absolute;
+ top: 5px;
+ color: #03a9f4;
+ --mdc-icon-size: 24px;
+ }
+
+ .iconInactive {
+ position: absolute;
+ top: 5px;
+ color: #999;
+ --mdc-icon-size: 24px;
+ }
+
+ .tab:hover .iconInactive {
+ color: #03a9f4;
+ }
+
+ .count {
+ position: relative;
+ top: -5px;
+ font-weight: bold;
+ background-color: #C6011F;
+ color: white;
+ font-size: 12px;
+ padding: 2px 6px;
+ text-align: center;
+ border-radius: 5px;
+ animation: pulse 1500ms infinite;
+ animation-duration: 6s;
+ }
+
+ .ml-5 {
+ margin-left: 5px;
+ }
+
+ .ml-10 {
+ margin-left: 10px;
+ }
+
+ .ml-15 {
+ margin-left: 15px;
+ }
+
+ .ml-20 {
+ margin-left: 20px;
+ }
+
+ .ml-25 {
+ margin-left: 25px;
+ }
+
+ .ml-30 {
+ margin-left: 30px;
+ }
+
+ .ml-35 {
+ margin-left: 35px;
+ }
+
+ .ml-40 {
+ margin-left: 40px;
+ }
+
+ @keyframes pulse {
+ 0% {
+ box-shadow:#C6011F 0 0 0 0;
+ }
+ 75% {
+ box-shadow:#ff69b400 0 0 0 16px;
+ }
+ }
+ `
+ }
+
+ constructor() {
+ super()
+ this.registeredUrls = []
+ this.currentTab = 0
+ this.tabs = []
+ this.uid = new ShortUniqueId()
+ this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
+ this.tabInfo = {}
+ this.chatLastSeen = []
+ this.chatHeads = []
+ }
+
+ render() {
+ const plugSrc = (myPlug) => {
+ return myPlug === undefined ? 'about:blank' : `${window.location.origin}/plugin/${myPlug.domain}/${myPlug.page}${this.linkParam}`
+ }
+
+ return html`
+
+ ${this.tabs.map((tab, index) => {
+ let title = ''
+ let icon = ''
+ let count = 0
+
+ if (tab.myPlugObj && tab.myPlugObj.title === "Overview Page") {
+ title = html`${translate('tabmenu.tm28')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Minting Details") {
+ title = html`${translate('tabmenu.tm1')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Become a Minter") {
+ title = html`${translate('tabmenu.tm2')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Sponsorship List") {
+ title = html`${translate('tabmenu.tm3')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Wallets") {
+ title = html`${translate('tabmenu.tm4')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Trade Portal") {
+ title = html`${translate('tabmenu.tm5')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Auto Buy") {
+ title = html`${translate('tabmenu.tm6')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Reward Share") {
+ title = html`${translate('tabmenu.tm7')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Q-Chat") {
+ title = html`${translate('tabmenu.tm8')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Name Registration") {
+ title = html`${translate('tabmenu.tm9')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Names Market") {
+ title = html`${translate('tabmenu.tm10')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Websites") {
+ title = html`${translate('tabmenu.tm11')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Q-Apps") {
+ title = html`${translate('tabmenu.tm12')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Group Management") {
+ title = html`${translate('tabmenu.tm13')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Data Management") {
+ title = html`${translate('tabmenu.tm14')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Puzzles") {
+ title = html`${translate('tabmenu.tm15')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Node Management") {
+ title = html`${translate('tabmenu.tm16')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.url === "myapp") {
+ title = tab.myPlugObj && tab.myPlugObj.title
+ } else {
+ title = html`${translate('tabmenu.tm17')}`
+ }
+
+ if (tab.myPlugObj && tab.myPlugObj.mwcicon) {
+ icon = tab.myPlugObj.mwcicon
+ } else {
+ icon = 'tab'
+ }
+
+ if (tab.myPlugObj && (tab.myPlugObj.url === 'websites' || tab.myPlugObj.url === 'qapps') && this.tabInfo[tab.id]) {
+ title = this.tabInfo[tab.id].name
+ }
+
+ if (tab.myPlugObj && (tab.myPlugObj.url === 'websites' || tab.myPlugObj.url === 'qapps') && this.tabInfo[tab.id]) {
+ count = this.tabInfo[tab.id].count
+ }
+
+ if (tab.myPlugObj && tab.myPlugObj.url === 'q-chat') {
+ for (const chat of this.chatHeads) {
+
+ const lastReadMessage = this.chatLastSeen.find((ch) => {
+ let id
+ if (chat.groupId === 0) {
+ id = chat.groupId
+ } else if (chat.groupId) {
+ id = chat.groupId
+ } else {
+ id = chat.address
+ }
+ return ch.key.includes(id)
+ })
+ if (lastReadMessage && lastReadMessage.timestamp < chat.timestamp) {
+ count = count + 1
+ }
+ }
+ }
+
+ return html`
+
this.currentTab = index}"
+ >
+
+ ${icon}
+
+
+ ${count ? html`
+ ${title}
+ ${count}
+ {this.removeTab(index, tab.id)}}>close
+ ` : html`
+ ${title}
+ {this.removeTab(index, tab.id)}}>close
+ `}
+
+
+ `
+ })}
+
+
+
+ ${repeat(this.tabs, (tab) => tab.id, (tab, index) => html`
+
+
+ this.changePage(val)}
+ >
+
+
+ `)}
+ `
+ }
+
+ firstUpdated() {
+ this.changeLanguage()
+
+ this.tabs.forEach((tab, index) => {
+ const frame = this.shadowRoot.getElementById(`showPluginFrame${index}`)
+ this.createEpmlInstance(frame, index)
+ })
+
+ window.addEventListener('storage', () => {
+ const checkLanguage = localStorage.getItem('qortalLanguage')
+ const checkTheme = localStorage.getItem('qortalTheme')
+
+ use(checkLanguage)
+
+ if (checkTheme === 'dark') {
+ this.theme = 'dark'
+ } else {
+ this.theme = 'light'
+ }
+ document.querySelector('html').setAttribute('theme', this.theme)
+ })
+ }
+
+ changeLanguage() {
+ const checkLanguage = localStorage.getItem('qortalLanguage')
+
+ if (checkLanguage === null || checkLanguage.length === 0) {
+ localStorage.setItem('qortalLanguage', 'us')
+ use('us')
+ } else {
+ use(checkLanguage)
+ }
+ }
+
+ async getUpdateComplete() {
+ await super.getUpdateComplete()
+ return true
+ }
+
+ async addTab(tab) {
+ if (this.tabs == []) {
+ // ...Nothing to do
+ } else {
+ this.tabs.forEach((rac, index) => {
+ let racId = ''
+ let tabRacId = ''
+ let frameRacId = ''
+ let plugRacId = ''
+ let iconRacId = ''
+
+ racId = rac.id
+ tabRacId = 'tab-' + racId
+ frameRacId = 'frame-' + racId
+ plugRacId = 'plug-' + racId
+ iconRacId = 'icon-' + racId
+
+ const plugObjRac = rac.url
+
+ var tabActiveRac = this.shadowRoot.getElementById(tabRacId)
+ var frameActiveRac = this.shadowRoot.getElementById(frameRacId)
+ var plugActiveRac = this.shadowRoot.getElementById(plugRacId)
+ var iconActiveRac = this.shadowRoot.getElementById(iconRacId)
+
+ if (plugObjRac === undefined || "") {
+ tabActiveRac.classList.remove("active")
+ iconActiveRac.classList.remove("iconActive")
+ iconActiveRac.classList.add("iconInactive")
+ plugActiveRac.classList.remove("showIframe")
+ plugActiveRac.classList.add("hideIframe")
+ } else {
+ tabActiveRac.classList.remove("active")
+ iconActiveRac.classList.remove("iconActive")
+ iconActiveRac.classList.add("iconInactive")
+ frameActiveRac.classList.remove("showIframe")
+ frameActiveRac.classList.add("hideIframe")
+ }
+ })
+ }
+
+ this.tabs = [...this.tabs, tab]
+ await this.getUpdateComplete()
+
+ // add the new tab to the tabs array
+ const newIndex = this.tabs.length - 1
+
+ // render the tab and wait for it to be added to the DOM
+ const frame = this.shadowRoot.getElementById(`showPluginFrame${newIndex}`)
+ this.createEpmlInstance(frame, newIndex)
+ }
+
+ removeTab(index, tabA) {
+ const tabB = this.tabs.length - 1
+ const tabC = this.tabs[tabB].id
+
+ if (tabC === tabA) {
+ let theId = ''
+ let tabId = ''
+ let frameId = ''
+ let plugId = ''
+ let iconId = ''
+
+ this.tabs = this.tabs.filter((tab, tIndex) => tIndex !== index)
+
+ const tabD = this.tabs.length - 1
+ const plugObj = this.tabs[tabD].url
+
+ theId = this.tabs[tabD].id
+ tabId = 'tab-' + theId
+ frameId = 'frame-' + theId
+ plugId = 'plug-' + theId
+ iconId = 'icon-' + theId
+
+ var tabActive = this.shadowRoot.getElementById(tabId)
+ var frameActive = this.shadowRoot.getElementById(frameId)
+ var plugActive = this.shadowRoot.getElementById(plugId)
+ var iconActive = this.shadowRoot.getElementById(iconId)
+
+ if (plugObj === undefined || "") {
+ tabActive.classList.add("active")
+ iconActive.classList.remove("iconInactive")
+ iconActive.classList.add("iconActive")
+ plugActive.classList.remove("hideIframe")
+ plugActive.classList.add("showIframe")
+ } else {
+ tabActive.classList.add("active")
+ iconActive.classList.remove("iconInactive")
+ iconActive.classList.add("iconActive")
+ frameActive.classList.remove("hideIframe")
+ frameActive.classList.add("showIframe")
+ }
+ this.requestUpdate()
+ } else {
+ // Remove tab from array
+ this.tabs = this.tabs.filter((tab, tIndex) => tIndex !== index)
+
+ if (this.tabs.length !== 0) {
+ this.currentTab = 0
+ }
+ this.requestUpdate()
+ }
+ }
+
+ createEpmlInstance(frame, index) {
+ const showingPluginEpml = new Epml({
+ type: 'WINDOW',
+ source: frame.contentWindow
+ })
+
+ addPluginRoutes(showingPluginEpml);
+ showingPluginEpml.imReady()
+
+ // store Epml instance in tab for later use
+ this.tabs[index].epmlInstance = showingPluginEpml
+
+ // Register each instance with a unique identifier
+ Epml.registerProxyInstance(`visible-plugin-${index}`, showingPluginEpml)
+ }
+
+ updated(changedProps) {
+ if (changedProps.has('url') || changedProps.has('registeredUrls')) {
+ const plugArr = []
+
+ this.registeredUrls.forEach(myPlugArr => {
+ myPlugArr.menus.length === 0 ? plugArr.push(myPlugArr) : myPlugArr.menus.forEach(i => plugArr.push(myPlugArr, i))
+ })
+
+ const myPlugObj = plugArr.find(pagePlug => {
+ return pagePlug.url === this.url
+ })
+
+ if (this.tabs.length === 0) {
+ this.addTab({
+ url: this.url,
+ myPlugObj,
+ id: this.uid()
+ })
+ } else {
+ const copiedTabs = [...this.tabs]
+ copiedTabs[this.currentTab] = {
+ ...copiedTabs[this.currentTab],
+ url: this.url,
+ myPlugObj
+ }
+ this.tabs = copiedTabs
+ }
+ this.requestUpdate()
+ }
+
+ if (changedProps.has('computerUrl')) {
+ if (this.computedUrl !== 'about:blank') {
+ this.loading = true
+ }
+ }
+ }
+
+ changePage(page) {
+ const copiedTabs = [...this.tabs]
+ copiedTabs[this.currentTab] = {
+ ...copiedTabs[this.currentTab],
+ myPlugObj: page,
+ url: page.url
+ }
+ this.tabs = copiedTabs
+ }
+
+ async stateChanged(state) {
+ const split = state.app.url.split('/')
+ const newRegisteredUrls = state.app.registeredUrls
+
+ let newUrl, newLinkParam
+
+ if (newRegisteredUrls !== this.registeredUrls) {
+ this.registeredUrls = newRegisteredUrls
+ }
+
+ if (split[0] === '' && split[1] === 'app' && split[2] === undefined) {
+ newUrl = 'wallet'
+ newLinkParam = ''
+ } else if (split.length === 5 && split[1] === 'app') {
+ newUrl = split[2]
+ newLinkParam = split[3] === undefined ? '' : '?' + split[3] + '/' + split[4]
+ } else if (split[1] === 'app') {
+ newUrl = split[2]
+ newLinkParam = ''
+ } else {
+ newUrl = '404'
+ newLinkParam = ''
+ }
+
+ if (newUrl !== this.url) {
+ this.url = newUrl
+ }
+
+ if (newLinkParam !== this.linkParam) {
+ this.linkParam = newLinkParam
+ }
+ if (this.tabInfo !== state.app.tabInfo) {
+ this.tabInfo = state.app.tabInfo
+ }
+ if (this.chatLastSeen !== state.app.chatLastSeen) {
+ this.chatLastSeen = state.app.chatLastSeen
+ }
+ if (state.app.chatHeads !== this.unModifiedChatHeads) {
+ let chatHeads = []
+ if (state.app.chatHeads && state.app.chatHeads.groups) {
+ chatHeads = [...chatHeads, ...state.app.chatHeads.groups]
+ }
+ if (state.app.chatHeads && state.app.chatHeads.direct) {
+ chatHeads = [...chatHeads, ...state.app.chatHeads.direct]
+ }
+ this.chatHeads = chatHeads
+ this.unModifiedChatHeads = state.app.chatHeads
+ }
+
+ if (state.app.newTab) {
+ const newTab = state.app.newTab
+ if (!this.tabs.find((tab) => tab.id === newTab.id)) {
+ this.addTab(newTab)
+ this.currentTab = this.tabs.length - 1
+ store.dispatch(setNewTab(null))
+ //clear newTab
+ } else {
+ const findIndex = this.tabs.findIndex((tab) => tab.id === newTab.id)
+ if (findIndex !== -1) {
+ const copiedTabs = [...this.tabs]
+ copiedTabs[findIndex] = newTab
+ this.tabs = copiedTabs
+ this.currentTab = findIndex
+ }
+
+ store.dispatch(setNewTab(null))
+ //clear newTab
+ }
+ }
+ }
+}
+
+window.customElements.define('show-plugin', ShowPlugin)
+
+class NavBar extends connect(store)(LitElement) {
+ static get properties() {
+ return {
+ menuList: { type: Array },
+ newMenuList: { type: Array },
+ myMenuList: { type: Array },
+ myMenuPlugins: { type: Array },
+ myApps: { type: Array },
+ addressInfo: { type: Object },
+ changePage: { attribute: false },
+ pluginName: { type: String },
+ pluginType: { type: String },
+ pluginPage: { type: String },
+ mwcIcon: { type: String },
+ pluginNameToDelete: { type: String },
+ pluginNumberToDelete: { type: String },
+ textFieldDisabled: { type: Boolean },
+ initialName: { type: String },
+ newId: { type: String },
+ removeTitle: { type: String },
+ myFollowedNames: { type: Array },
+ myFollowedNamesList: { type: Array },
+ searchNameContentString: { type: String },
+ searchNameResources: { type: Array }
+ }
+ }
+
+ static styles = css`
+ * {
+ --mdc-theme-primary: rgb(3, 169, 244);
+ --mdc-theme-surface: var(--white);
+ --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-dialog-content-ink-color: var(--black);
+ --mdc-dialog-shape-radius: 25px;
+ --mdc-dialog-min-width: 300px;
+ --mdc-dialog-max-width: 700px;
+ }
+
+ .parent {
+ display: flex;
+ flex-direction: column;
+ flex-flow: column;
+ align-items: center;
+ padding: 20px;
+ height: 100vh;
+ overflow-y: auto;
+ }
+
+ .navbar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ background-color: color: var(--white);
+ padding: 10px 20px;
+ max-width: 750px;
+ width: 80%;
+ }
+
+ .navbar input {
+ font-size: 16px;
+ color: #000;
+ padding: 5px;
+ flex-grow: 1;
+ margin-right: 10px;
+ border: 1px solid var(--black);
+ }
+
+ .navbar button {
+ padding: 5px 10px;
+ font-size: 18px;
+ background-color: var(--app-background-1);
+ background-image: linear-gradient(315deg, var(--app-background-1) 0%, var(--app-background-2) 74%);
+ color: var(--app-icon);
+ border: 1px solid transparent;
+ border-radius: 3px;
+ cursor: pointer;
+ }
+
+ .navbar button:hover {
+ background-color: #45a049;
+ }
+
+ .app-list {
+ display: flex;
+ justify-content: space-between;
+ padding: 10px 0;
+ gap: 10px;
+ flex-wrap: wrap;
+ }
+
+ .app-list .app-icon {
+ text-align: center;
+ font-size: 15px;
+ font-weight: bold;
+ color: var(--black);
+ width: 175px;
+ height: 110px;
+ background: transparent;
+ padding: 5px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 10px;
+ }
+
+ .text {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ display: block;
+ width: 100%;
+ min-width: 1px;
+ }
+
+ .app-list .app-icon span {
+ display: block;
+ }
+
+ .app-icon-box {
+ display: flex;
+ align-items: center;
+ padding-left: 14px;
+ width: 80px;
+ min-width: 80px;
+ height: 80px;
+ min-height: 80px;
+ background-color: var(--app-background-1);
+ background-image: linear-gradient(315deg, var(--app-background-1) 0%, var(--app-background-2) 74%);
+ border-top-left-radius: 10px;
+ border-top-right-radius: 20px;
+ border-bottom-left-radius: 20px;
+ border-bottom-right-radius: 10px;
+ }
+
+ .menuIcon {
+ color: var(--app-icon);
+ --mdc-icon-size: 64px;
+ cursor: pointer;
+ }
+
+ .menuIconPos {
+ position: relative;
+ right: 26px;
+ }
+
+ .removeIcon {
+ color: var(--black);
+ --mdc-icon-size: 28px;
+ cursor: pointer;
+ }
+
+ .removeIcon:hover {
+ color: #C6011F;
+ font-weight: bold;
+ }
+
+ .removeIconPos {
+ position: relative;
+ top: -36px;
+ left: 62px;
+ }
+
+ .red {
+ --mdc-theme-primary: #F44336;
+ }
+
+ select {
+ padding: 10px 10px 10px 10px;
+ width: 100%;
+ font-size: 16px;
+ font-weight: 500;
+ background: var(--white);
+ color: var(--black);
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ background-image: url('/img/arrow.png');
+ background-repeat: no-repeat;
+ background-position: right 10px center;
+ background-size: 20px;
+ }
+
+ .resetIcon {
+ position: fixed;
+ right: 20px;
+ top: 116px;
+ color: #666;
+ --mdc-icon-size: 32px;
+ cursor: pointer;
+ }
+
+ .resetIcon:hover {
+ color: #03a9f4;
+ font-weight: bold;
+ }
+
+ .searchIcon {
+ position: fixed;
+ left: 20px;
+ top: 116px;
+ color: #666;
+ --mdc-icon-size: 32px;
+ cursor: pointer;
+ }
+
+ .searchIcon:hover {
+ color: #03a9f4;
+ font-weight: bold;
+ }
+
+ .importIcon {
+ position: fixed;
+ left: 20px;
+ bottom: 16px;
+ color: #666;
+ --mdc-icon-size: 32px;
+ cursor: pointer;
+ }
+
+ .importIcon:hover {
+ color: #03a9f4;
+ font-weight: bold;
+ }
+
+ .exportIcon {
+ position: fixed;
+ right: 20px;
+ bottom: 16px;
+ color: #666;
+ --mdc-icon-size: 32px;
+ cursor: pointer;
+ }
+
+ .exportIcon:hover {
+ color: #03a9f4;
+ font-weight: bold;
+ }
+
+ paper-dialog.searchSettings {
+ width: 100%;
+ max-width: 550px;
+ height: auto;
+ max-height: 600px;
+ background-color: var(--white);
+ color: var(--black);
+ line-height: 1.6;
+ overflow: hidden;
+ border: 1px solid var(--black);
+ border-radius: 10px;
+ padding: 15px;
+ }
+
+ paper-dialog button {
+ padding: 5px 10px;
+ font-size: 18px;
+ background-color: #03a9f4;
+ color: white;
+ border: 1px solid transparent;
+ border-radius: 5px;
+ cursor: pointer;
+ }
+
+ paper-dialog button:hover {
+ opacity: 0.8;
+ cursor: pointer;
+ }
+
+ .search {
+ display: inline;
+ width: 50%;
+ align-items: center;
+ }
+
+ .divCard {
+ height: auto;
+ max-height: 500px;
+ border: 1px solid var(--border);
+ padding: 1em;
+ margin-bottom: 1em;
+ }
+
+ img {
+ border-radius: 25%;
+ max-width: 32px;
+ height: 100%;
+ max-height: 32px;
+ }
+
+ vaadin-text-field[focused]::part(input-field) {
+ border-color: #03a9f4;
+ }
+ `
+
+ constructor() {
+ super()
+ this.menuList = []
+ this.newMenuList = []
+ this.myMenuList = []
+ this.myMenuPlugins = []
+ this.addressInfo = {}
+ this.pluginName = ''
+ this.pluginType = ''
+ this.pluginPage = ''
+ this.myApps = ''
+ this.mwcIcon = ''
+ this.pluginNameToDelete = ''
+ this.pluginNumberToDelete = ''
+ this.textFieldDisabled = false
+ this.initialName = ''
+ this.newId = ''
+ this.removeTitle = ''
+ this.myFollowedNames = []
+ this.myFollowedNamesList = []
+ this.searchContentString = ''
+ this.searchNameResources = []
+ }
+
+ render() {
+ return html`
+
+
this.resetMenu()}" title="${translate("tabmenu.tm29")}">reset_tv
+
this.openNameSearch()}" title="${translate("tabmenu.tm30")}">person_search
+
this.openImportDialog()}" title="${translate("tabmenu.tm33")}">upload
+
this.exportTabMenu()}" title="${translate("tabmenu.tm34")}">download
+
+
+
+
+
+ ${repeat(this.myMenuList, (plugin) => plugin.url, (plugin, index) => html`
+
+
+ ${this.renderRemoveIcon(plugin.url, plugin.mwcicon, plugin.title, plugin.pluginNumber, plugin)}
+
+ ${this.renderTitle(plugin.url, plugin.title)}
+
+ `)}
+
this.openAddNewPlugin()}">
+
+
+
+
${translate("tabmenu.tm19")}
+
+
+
+
+
+
${translate("tabmenu.tm26")}
+
+
+
+ ${translate("tabmenu.tm24")}
+
+
+
+
+
+
+
+ ${translate("tabmenu.tm19")}
+
+
+ ${translate("general.close")}
+
+
+
+
+
${translate("tabmenu.tm27")}
+
+
+ ${translate("tabmenu.tm23")}
+ ${this.removeTitle}
+
+ ${translate("general.yes")}
+
+
+ ${translate("general.no")}
+
+
+
+
+
+
+
+
this.searchNameResult()}" title="${translate("websitespage.schange35")}">
+
this.closeNameSearch()}" title="${translate("general.close")}">
+
+
+
+
+ {
+ render(html`${this.renderNameAvatar(data.item)}`, root)
+ }}
+ >
+
+ {
+ render(html`${data.item.name}`, root)
+ }}
+ >
+
+ {
+ render(html`${this.renderMyFollowUnfollowButton(data.item)}`, root)
+ }}
+ >
+
+
+ ${this.isEmptyArray(this.searchNameResources) ? html`
+ ${translate("login.entername")}
+ `: ''}
+
+
+
+
+
+
+
+
${translate("tabmenu.tm31")}
+
+
+
+
+ {
+ render(html`${this.renderNameAvatar(data.item)}`, root)
+ }}
+ >
+
+ {
+ render(html`${data.item.name}`, root)
+ }}
+ >
+
+ {
+ render(html`${this.renderMyFollowUnfollowButton(data.item)}`, root)
+ }}
+ >
+
+
+ ${this.isEmptyArray(this.myFollowedNamesList) ? html`
+ ${translate("tabmenu.tm32")}
+ `: ''}
+
+
+
+
+
+
+
+ `
+ }
+
+ async firstUpdated() {
+ addPluginRoutes(parentEpml)
+ parentEpml.imReady()
+
+ const addressInfo = this.addressInfo
+ const isMinter = addressInfo?.error !== 124 && +addressInfo?.level > 0
+ const isSponsor = +addressInfo?.level >= 5
+ const appDelay = ms => new Promise(res => setTimeout(res, ms))
+
+ await appDelay(50)
+
+ await this.checkMyMenuPlugins()
+
+ if (!isMinter) {
+ this.newMenuList = this.myMenuPlugins.filter((minter) => {
+ return minter.url !== 'minting'
+ })
+ } else {
+ this.newMenuList = this.myMenuPlugins.filter((minter) => {
+ return minter.url !== 'become-minter'
+ })
+ }
+
+ if (!isSponsor) {
+ this.myMenuList = this.newMenuList.filter((sponsor) => {
+ return sponsor.url !== 'sponsorship-list'
+ })
+ } else {
+ this.myMenuList = this.newMenuList
+ }
+
+ await this.getMyFollowedNames()
+ await this.getMyFollowedNamesList()
+ }
+
+ openImportDialog() {
+ this.shadowRoot.getElementById('importTabMenutDialog').show()
+ }
+
+ importTabMenu(file) {
+ this.myMenuPlugins = []
+ let myFile = ''
+ localStorage.removeItem("myMenuPlugs")
+ myFile = file
+ const newTabMenu = JSON.parse((myFile) || "[]")
+ localStorage.setItem("myMenuPlugs", JSON.stringify(newTabMenu))
+ this.shadowRoot.getElementById('importTabMenutDialog').close()
+ this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+ this.firstUpdated()
+
+ let success5string = get("tabmenu.tm36")
+ parentEpml.request('showSnackBar', `${success5string}`)
+ }
+
+ exportTabMenu() {
+ let tabMenu = ""
+ const qortalTabMenu = JSON.stringify(localStorage.getItem("myMenuPlugs"))
+ const qortalTabMenuSave = JSON.parse((qortalTabMenu) || "[]")
+ const blob = new Blob([qortalTabMenuSave ], { type: 'text/plain;charset=utf-8' })
+ tabMenu = "qortal.tabmenu"
+ this.saveFileToDisk(blob, tabMenu)
+ }
+
+ 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("tabmenu.tm37")
+ parentEpml.request('showSnackBar', `${snack4string} ${fileName}`)
+ } catch (error) {
+ if (error.name === 'AbortError') {
+ return
+ }
+ FileSaver.saveAs(blob, fileName)
+ let snack4string = get("tabmenu.tm37")
+ parentEpml.request('showSnackBar', `${snack4string} ${fileName}`)
+ }
+ }
+
+ openNameSearch() {
+ this.searchNameResources = []
+ this.shadowRoot.getElementById('searchNameContent').value = ''
+ this.shadowRoot.getElementById('myFollowedNamesDialog').close()
+ this.shadowRoot.getElementById('searchNameDialog').open()
+ }
+
+ closeNameSearch() {
+ this.shadowRoot.getElementById('searchNameDialog').close()
+ }
+
+ openMyFollowedNames() {
+ this.shadowRoot.getElementById('searchNameDialog').close()
+ this.shadowRoot.getElementById('myFollowedNamesDialog').open()
+ this.getMyFollowedNamesList()
+ }
+
+ closeMyFollowedNames() {
+ this.shadowRoot.getElementById('myFollowedNamesDialog').close()
+ }
+
+ async getMyFollowedNames() {
+ let myFollowedNames = await parentEpml.request('apiCall', {
+ url: `/lists/followedNames?apiKey=${this.getApiKey()}`
+ })
+
+ this.myFollowedNames = myFollowedNames
+ }
+
+ searchNameKeyListener(e) {
+ if (e.key === 'Enter') {
+ this.searchNameResult()
+ }
+ }
+
+ async getMyFollowedNamesList() {
+ const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
+ const myNodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
+ const followedNamesUrl = `${myNodeUrl}/lists/followedNames?apiKey=${this.getApiKey()}`
+
+ var myFollowedNamesNew = []
+
+ this.myFollowedNamesList = []
+
+ await fetch(followedNamesUrl).then(response => {
+ return response.json()
+ }).then(data => {
+ return data.map(item => {
+ const addListName = {
+ name: item
+ }
+ myFollowedNamesNew.push(addListName)
+ })
+ })
+ this.myFollowedNamesList = myFollowedNamesNew
+ if(this.shadowRoot.getElementById('myFollowedNamesDialog').opened) {
+ this.shadowRoot.getElementById('myFollowedNamesDialog').notifyResize()
+ }
+ }
+
+ async searchNameResult() {
+ let searchMyName = this.shadowRoot.getElementById('searchNameContent').value
+ if (searchMyName.length === 0) {
+ let err1string = get("appspage.schange34")
+ parentEpml.request('showSnackBar', `${err1string}`)
+ } else {
+ let searchNameResources = await parentEpml.request('apiCall', {
+ url: `/names/search?query=${searchMyName}&prefix=true&limit=0&reverse=true`
+ })
+ if (this.isEmptyArray(searchNameResources)) {
+ let err2string = get("appspage.schange17")
+ parentEpml.request('showSnackBar', `${err2string}`)
+ } else {
+ this.searchNameResources = searchNameResources
+ if(this.shadowRoot.getElementById('searchNameDialog').opened) {
+ this.shadowRoot.getElementById('searchNameDialog').notifyResize()
+ }
+ }
+ }
+ }
+
+ renderNameAvatar(nameObj) {
+ let myName = nameObj.name
+ const myNameNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
+ const myNodeUrl = myNameNode.protocol + '://' + myNameNode.domain + ':' + myNameNode.port
+ const nameUrl = `${myNodeUrl}/arbitrary/THUMBNAIL/${myName}/qortal_avatar?async=true`
+ return html`
`
+ }
+
+ renderMyFollowUnfollowButton(nameObj) {
+ let name = nameObj.name
+
+ if (this.myFollowedNames == null || !Array.isArray(this.myFollowedNames)) {
+ return html``
+ }
+
+ if (this.myFollowedNames.indexOf(name) === -1) {
+ return html` this.myFollowName(nameObj)}>add_to_queue ${translate("appspage.schange29")}`
+ } else {
+ return html` this.myUnfollowName(nameObj)}>remove_from_queue ${translate("appspage.schange30")}`
+ }
+ }
+
+ async myFollowName(nameObj) {
+ let name = nameObj.name
+ let items = [
+ name
+ ]
+ let namesJsonString = JSON.stringify({ "items": items })
+
+ let ret = await parentEpml.request('apiCall', {
+ url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: `${namesJsonString}`
+ })
+
+ if (ret === true) {
+ this.myFollowedNames = this.myFollowedNames.filter(item => item != name)
+ this.myFollowedNames.push(name)
+ } else {
+ let err3string = get("appspage.schange22")
+ parentEpml.request('showSnackBar', `${err3string}`)
+ }
+ this.getMyFollowedNamesList()
+ return ret
+ }
+
+ async myUnfollowName(nameObj) {
+ let name = nameObj.name
+ let items = [
+ name
+ ]
+ let namesJsonString = JSON.stringify({ "items": items })
+
+ let ret = await parentEpml.request('apiCall', {
+ url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
+ method: 'DELETE',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: `${namesJsonString}`
+ })
+
+ if (ret === true) {
+ this.myFollowedNames = this.myFollowedNames.filter(item => item != name)
+ } else {
+ let err4string = get("appspage.schange23")
+ parentEpml.request('showSnackBar', `${err4string}`)
+ }
+ this.getMyFollowedNamesList()
+ return ret
+ }
+
+ async checkMyMenuPlugins() {
+ const appDelay = ms => new Promise(res => setTimeout(res, ms))
+
+ if (localStorage.getItem("myMenuPlugs") === null) {
+ await appDelay(1000)
+ const myObj = JSON.stringify(this.menuList)
+ localStorage.setItem("myMenuPlugs", myObj)
+ this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+ } else {
+ this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+ }
+ }
+
+ resetMenu() {
+ localStorage.removeItem("myMenuPlugs")
+ this.firstUpdated()
+ }
+
+ val() {
+ const theValue = this.shadowRoot.getElementById("pluginTypeInput").value
+
+ if (theValue === "reject") {
+ this.textFieldDisabled = false
+ this.initialName = ''
+ this.mwcIcon = ''
+ } else if (theValue === "0") {
+ this.textFieldDisabled = false
+ this.initialName = ''
+ this.mwcIcon = ''
+ } else if (theValue === "1") {
+ this.textFieldDisabled = false
+ this.initialName = ''
+ this.mwcIcon = ''
+ } else if (theValue === 'overview-page') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Overview Page'
+ this.mwcIcon = 'home'
+ } else if (theValue === 'minting') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Minting Details'
+ this.mwcIcon = 'info_outline'
+ } else if (theValue === 'become-minter') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Become a Minter'
+ this.mwcIcon = 'thumb_up'
+ } else if (theValue === 'sponsorship-list') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Sponsorship List'
+ this.mwcIcon = 'format_list_numbered'
+ } else if (theValue === 'wallet') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Wallets'
+ this.mwcIcon = 'account_balance_wallet'
+ } else if (theValue === 'trade-portal') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Trade Portal'
+ this.mwcIcon = 'format_list_bulleted'
+ } else if (theValue === 'trade-bot-portal') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Auto Buy'
+ this.mwcIcon = 'shop'
+ } else if (theValue === 'reward-share') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Reward Share'
+ this.mwcIcon = 'ios_share'
+ } else if (theValue === 'q-chat') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Q-Chat'
+ this.mwcIcon = 'forum'
+ } else if (theValue === 'name-registration') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Name Registration'
+ this.mwcIcon = 'manage_accounts'
+ } else if (theValue === 'names-market') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Names Market'
+ this.mwcIcon = 'store'
+ } else if (theValue === 'websites') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Websites'
+ this.mwcIcon = 'desktop_mac'
+ } else if (theValue === 'qapps') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Q-Apps'
+ this.mwcIcon = 'apps'
+ } else if (theValue === 'group-management') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Group Management'
+ this.mwcIcon = 'group'
+ } else if (theValue === 'data-management') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Data Management'
+ this.mwcIcon = 'storage'
+ } else if (theValue === 'puzzles') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Puzzles'
+ this.mwcIcon = 'extension'
+ } else if (theValue === 'node-management') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Node Management'
+ this.mwcIcon = 'cloud'
+ }
+ }
+
+ filterSelectMenu() {
+ const addressInfoSelect = this.addressInfo
+ const isMinterSelect = addressInfoSelect?.error !== 124 && +addressInfoSelect?.level > 0
+ const isSponsorSelect = +addressInfoSelect?.level >= 5
+
+ if (!isMinterSelect) {
+ return html`
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `
+ } else if (isMinterSelect && isSponsorSelect) {
+ return html`
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `
+ } else {
+ return html`
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `
+ }
+ }
+
+ openAddNewPlugin() {
+ this.shadowRoot.getElementById("pluginTypeInput").value = 'reject'
+ this.shadowRoot.getElementById("pluginNameInput").value = ''
+ this.initialName = ''
+ this.textFieldDisabled = false
+ this.shadowRoot.querySelector('#addNewPlugin').show()
+ }
+
+ async addToMyMenuPlugins() {
+ this.newId = ''
+ const newUid = new ShortUniqueId({ length: 10 })
+ this.newId = 'plugin-' + newUid()
+
+ this.pluginType = this.shadowRoot.getElementById("pluginTypeInput").value
+
+ if (this.pluginType === "reject") {
+ let myplugerr = get("tabmenu.tm25")
+ parentEpml.request('showSnackBar', `${myplugerr}`)
+ return false
+ } else if (this.pluginType === "0") {
+ this.mwcIcon = ''
+ this.pluginName = this.shadowRoot.getElementById('pluginNameInput').value
+
+ if (this.pluginName === "Q-Blog") {
+ this.mwcIcon = 'rss_feed'
+ } else if (this.pluginName === "Q-Mail") {
+ this.mwcIcon = 'mail'
+ } else {
+ this.mwcIcon = 'apps'
+ }
+
+ var oldMenuPlugs = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+
+ const newMenuPlugsItem = {
+ "url": "myapp",
+ "domain": "core",
+ "page": `qdn/browser/index.html?name=${this.pluginName}&service=APP`,
+ "title": this.pluginName,
+ "icon": "vaadin:external-browser",
+ "mwcicon": this.mwcIcon,
+ "pluginNumber": this.newId,
+ "menus": [],
+ "parent": false
+ }
+
+ const validatePluginName = async () => {
+ if (this.pluginType === "0" && this.pluginName.length == 0) {
+ let myplugstring1 = get("walletpage.wchange50")
+ parentEpml.request('showSnackBar', `${myplugstring1}`)
+ return false
+ }
+
+ let myPluginName = false
+ this.myPluginNameRes = []
+
+ await parentEpml.request('apiCall', {
+ url: `/arbitrary/resources/search?service=APP&query=${this.pluginName}&exactmatchnames=true&limit=1`
+ }).then(res => {
+ this.myPluginNameRes = res
+ })
+
+ if (this.myPluginNameRes === undefined || this.myPluginNameRes.length == 0) {
+ myPluginName = false
+ } else {
+ myPluginName = true
+ }
+ return myPluginName
+ }
+
+ let myNameRes = await validatePluginName()
+
+ if (myNameRes !== false) {
+ oldMenuPlugs.push(newMenuPlugsItem)
+
+ localStorage.setItem("myMenuPlugs", JSON.stringify(oldMenuPlugs))
+
+ let myplugstring2 = get("walletpage.wchange52")
+ parentEpml.request('showSnackBar', `${myplugstring2}`)
+
+ this.closeAddNewPlugin()
+
+ this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+ this.firstUpdated()
+ } else {
+ let myplugstring3 = get("websitespage.schange17")
+ parentEpml.request('showSnackBar', `${myplugstring3}`)
+ return false
+ }
+ } else if (this.pluginType === "1") {
+ this.mwcIcon = ''
+ this.pluginName = this.shadowRoot.getElementById('pluginNameInput').value
+
+ this.mwcIcon = 'web'
+
+ var oldMenuPlugs = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+
+ const newMenuPlugsItem = {
+ "url": "myapp",
+ "domain": "core",
+ "page": `qdn/browser/index.html?name=${this.pluginName}&service=WEBSITE`,
+ "title": this.pluginName,
+ "icon": "vaadin:external-browser",
+ "mwcicon": this.mwcIcon,
+ "pluginNumber": this.newId,
+ "menus": [],
+ "parent": false
+ }
+
+ const validatePluginName = async () => {
+ if (this.pluginType === "1" && this.pluginName.length == 0) {
+ let myplugstring1 = get("walletpage.wchange50")
+ parentEpml.request('showSnackBar', `${myplugstring1}`)
+ return false
+ }
+
+ let myPluginName = false
+ this.myPluginNameRes = []
+
+ await parentEpml.request('apiCall', {
+ url: `/arbitrary/resources/search?service=WEBSITE&query=${this.pluginName}&exactmatchnames=true&limit=1`
+ }).then(res => {
+ this.myPluginNameRes = res
+ })
+
+ if (this.myPluginNameRes === undefined || this.myPluginNameRes.length == 0 ) {
+ myPluginName = false
+ } else {
+ myPluginName = true
+ }
+ return myPluginName
+ }
+
+ let myNameRes = await validatePluginName()
+
+ if (myNameRes !== false) {
+ oldMenuPlugs.push(newMenuPlugsItem)
+
+ localStorage.setItem("myMenuPlugs", JSON.stringify(oldMenuPlugs))
+
+ let myplugstring2 = get("walletpage.wchange52")
+ parentEpml.request('showSnackBar', `${myplugstring2}`)
+
+ this.closeAddNewPlugin()
+
+ this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+ this.firstUpdated()
+ } else {
+ let myplugstring3 = get("websitespage.schange17")
+ parentEpml.request('showSnackBar', `${myplugstring3}`)
+ return false
+ }
+ } else {
+ this.pluginPage = ''
+ if (this.pluginType === 'overview-page') {
+ this.pluginPage = 'overview-page/index.html'
+ } else if (this.pluginType === 'minting') {
+ this.pluginPage = 'minting/index.html'
+ } else if (this.pluginType === 'become-minter') {
+ this.pluginPage = 'become-minter/index.html'
+ } else if (this.pluginType === 'sponsorship-list') {
+ this.pluginPage = 'sponsorship-list/index.html'
+ } else if (this.pluginType === 'wallet') {
+ this.pluginPage = 'wallet/index.html'
+ } else if (this.pluginType === 'trade-portal') {
+ this.pluginPage = 'trade-portal/index.html'
+ } else if (this.pluginType === 'trade-bot-portal') {
+ this.pluginPage = 'trade-bot/index.html'
+ } else if (this.pluginType === 'reward-share') {
+ this.pluginPage = 'reward-share/index.html'
+ } else if (this.pluginType === 'q-chat') {
+ this.pluginPage = 'messaging/q-chat/index.html'
+ } else if (this.pluginType === 'name-registration') {
+ this.pluginPage = 'name-registration/index.html'
+ } else if (this.pluginType === 'names-market') {
+ this.pluginPage = 'names-market/index.html'
+ } else if (this.pluginType === 'websites') {
+ this.pluginPage = 'qdn/index.html'
+ } else if (this.pluginType === 'qapps') {
+ this.pluginPage = 'q-app/index.html'
+ } else if (this.pluginType === 'group-management') {
+ this.pluginPage = 'group-management/index.html'
+ } else if (this.pluginType === 'data-management') {
+ this.pluginPage = 'qdn/data-management/index.html'
+ } else if (this.pluginType === 'puzzles') {
+ this.pluginPage = 'puzzles/index.html'
+ } else if (this.pluginType === 'node-management') {
+ this.pluginPage = 'node-management/index.html'
+ }
+
+ var oldMenuPlugs = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+
+ const newMenuPlugsItem = {
+ "url": this.pluginType,
+ "domain": "core",
+ "page": this.pluginPage,
+ "title": this.initialName,
+ "icon": "vaadin:external-browser",
+ "mwcicon": this.mwcIcon,
+ "pluginNumber": this.newId,
+ "menus": [],
+ "parent": false
+ }
+
+ oldMenuPlugs.push(newMenuPlugsItem)
+
+ localStorage.setItem("myMenuPlugs", JSON.stringify(oldMenuPlugs))
+
+ let myplugstring2 = get("walletpage.wchange52")
+ parentEpml.request('showSnackBar', `${myplugstring2}`)
+
+ this.closeAddNewPlugin()
+
+ this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+ this.firstUpdated()
+ }
+ }
+
+ closeAddNewPlugin() {
+ this.shadowRoot.querySelector('#addNewPlugin').close()
+ this.shadowRoot.getElementById("pluginTypeInput").value = 'reject'
+ this.shadowRoot.getElementById("pluginNameInput").value = ''
+ this.initialName = ''
+ this.textFieldDisabled = false
+ }
+
+ renderTitle(theUrl, theName) {
+ if (theUrl === 'overview-page') {
+ return html`${translate('tabmenu.tm28')}`
+ } else if (theUrl === 'minting') {
+ return html`${translate('tabmenu.tm1')}`
+ } else if (theUrl === 'become-minter') {
+ return html`${translate('tabmenu.tm2')}`
+ } else if (theUrl === 'sponsorship-list') {
+ return html`${translate('tabmenu.tm3')}`
+ } else if (theUrl === 'wallet') {
+ return html`${translate('tabmenu.tm4')}`
+ } else if (theUrl === 'trade-portal') {
+ return html`${translate('tabmenu.tm5')}`
+ } else if (theUrl === 'trade-bot-portal') {
+ return html`${translate('tabmenu.tm6')}`
+ } else if (theUrl === 'reward-share') {
+ return html`${translate('tabmenu.tm7')}`
+ } else if (theUrl === 'q-chat') {
+ return html`${translate('tabmenu.tm8')}`
+ } else if (theUrl === 'name-registration') {
+ return html`${translate('tabmenu.tm9')}`
+ } else if (theUrl === 'names-market') {
+ return html`${translate('tabmenu.tm10')}`
+ } else if (theUrl === 'websites') {
+ return html`${translate('tabmenu.tm11')}`
+ } else if (theUrl === 'qapps') {
+ return html`${translate('tabmenu.tm12')}`
+ } else if (theUrl === 'group-management') {
+ return html`${translate('tabmenu.tm13')}`
+ } else if (theUrl === 'data-management') {
+ return html`${translate('tabmenu.tm14')}`
+ } else if (theUrl === 'puzzles') {
+ return html`${translate('tabmenu.tm15')}`
+ } else if (theUrl === 'node-management') {
+ return html`${translate('tabmenu.tm16')}`
+ } else {
+ return html`${theName}`
+ }
+ }
+
+ renderRemoveIcon(appurl, appicon, appname, appid, appplugin) {
+ return html`
+ this.openRemoveApp(appname, appid, appurl)}">
+ backspace
+
+
+ `
+ }
+
+ openRemoveApp(pluginNameTD, pluginNumberTD, pluginUrlTD) {
+ this.pluginNameToDelete = ''
+ this.pluginNameToDelete = pluginNameTD
+ this.pluginNumberToDelete = ''
+ this.pluginNumberToDelete = pluginNumberTD
+ this.removeTitle = ''
+ if (pluginUrlTD === 'overview-page') {
+ this.removeTitle = html`${translate('tabmenu.tm28')}`
+ } else if (pluginUrlTD === 'minting') {
+ this.removeTitle = html`${translate('tabmenu.tm1')}`
+ } else if (pluginUrlTD === 'become-minter') {
+ this.removeTitle = html`${translate('tabmenu.tm2')}`
+ } else if (pluginUrlTD === 'sponsorship-list') {
+ this.removeTitle = html`${translate('tabmenu.tm3')}`
+ } else if (pluginUrlTD === 'wallet') {
+ this.removeTitle = html`${translate('tabmenu.tm4')}`
+ } else if (pluginUrlTD === 'trade-portal') {
+ this.removeTitle = html`${translate('tabmenu.tm5')}`
+ } else if (pluginUrlTD === 'trade-bot-portal') {
+ this.removeTitle = html`${translate('tabmenu.tm6')}`
+ } else if (pluginUrlTD === 'reward-share') {
+ this.removeTitle = html`${translate('tabmenu.tm7')}`
+ } else if (pluginUrlTD === 'q-chat') {
+ this.removeTitle = html`${translate('tabmenu.tm8')}`
+ } else if (pluginUrlTD === 'name-registration') {
+ this.removeTitle = html`${translate('tabmenu.tm9')}`
+ } else if (pluginUrlTD === 'names-market') {
+ this.removeTitle = html`${translate('tabmenu.tm10')}`
+ } else if (pluginUrlTD === 'websites') {
+ this.removeTitle = html`${translate('tabmenu.tm11')}`
+ } else if (pluginUrlTD === 'qapps') {
+ this.removeTitle = html`${translate('tabmenu.tm12')}`
+ } else if (pluginUrlTD === 'group-management') {
+ this.removeTitle = html`${translate('tabmenu.tm13')}`
+ } else if (pluginUrlTD === 'data-management') {
+ this.removeTitle = html`${translate('tabmenu.tm14')}`
+ } else if (pluginUrlTD === 'puzzles') {
+ this.removeTitle = html`${translate('tabmenu.tm15')}`
+ } else if (pluginUrlTD === 'node-management') {
+ this.removeTitle = html`${translate('tabmenu.tm16')}`
+ } else {
+ this.removeTitle = html`${pluginNameTD}`
+ }
+ this.shadowRoot.querySelector('#removePlugin').show()
+ }
+
+ removeAppFromArray() {
+ const pluginToRemove = this.pluginNumberToDelete
+ this.newMenuFilter = []
+ this.newMenuFilter = this.myMenuList.filter((item) => item.pluginNumber !== pluginToRemove)
+ const myNewObj = JSON.stringify(this.newMenuFilter)
+ localStorage.removeItem("myMenuPlugs")
+ localStorage.setItem("myMenuPlugs", myNewObj)
+ this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+ this.firstUpdated()
+ this.closeRemoveApp()
+ }
+
+ closeRemoveApp() {
+ this.shadowRoot.querySelector('#removePlugin').close()
+ this.pluginNameToDelete = ''
+ this.pluginNumberToDelete = ''
+ }
+
+ async extractComponents(url) {
+ if (!url.startsWith("qortal://")) {
+ return null
+ }
+
+ url = url.replace(/^(qortal\:\/\/)/, "")
+ if (url.includes("/")) {
+ let parts = url.split("/")
+ const service = parts[0].toUpperCase()
+ parts.shift()
+ const name = parts[0]
+ parts.shift()
+ let identifier
+
+ if (parts.length > 0) {
+ identifier = parts[0] // Do not shift yet
+ // Check if a resource exists with this service, name and identifier combination
+ const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
+ const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
+ const url = `${nodeUrl}/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${myNode.apiKey}}`
+
+ const res = await fetch(url);
+ 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
+ }
+
+ async getQuery(value) {
+ let newQuery = value
+ 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}`
+ }
+
+ if (service === "APP") {
+ this.changePage({
+ "url": "qapp",
+ "domain": "core",
+ "page": `qdn/browser/index.html${query}`,
+ "title": "Q-App",
+ "icon": "vaadin:external-browser",
+ "mwcicon": "open_in_browser",
+ "menus": [],
+ "parent": false
+ })
+ } else if (service === "WEBSITE") {
+ this.changePage({
+ "url": "websites",
+ "domain": "core",
+ "page": `qdn/browser/index.html${query}`,
+ "title": "Website",
+ "icon": "vaadin:desktop",
+ "mwcicon": "desktop_mac",
+ "menus": [],
+ "parent": false
+ })
+ }
+ }
+
+ async handlePasteLink(e) {
+ try {
+ const value = this.shadowRoot.getElementById('linkInput').value
+ this.getQuery(value)
+ } catch (error) {
+ }
+ }
+
+ async _handleKeyDown(e) {
+ if (e.key === 'Enter') {
+ try {
+ const value = this.shadowRoot.getElementById('linkInput').value
+ this.getQuery(value)
+ } catch (error) {
+ }
+ }
+ }
+
+ getApiKey() {
+ const apiNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
+ let apiKey = apiNode.apiKey
+ return apiKey
+ }
+
+ isEmptyArray(arr) {
+ if (!arr) { return true }
+ return arr.length === 0
+ }
+
+ stateChanged(state) {
+ this.menuList = state.app.registeredUrls
+ this.addressInfo = state.app.accountInfo.addressInfo
+ }
+}
+
+customElements.define('nav-bar', NavBar)
From 4ae0ec6a98e4dd40d9d9e430826df8b710d1e3ad Mon Sep 17 00:00:00 2001
From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com>
Date: Fri, 14 Jul 2023 15:11:39 +0200
Subject: [PATCH 2/5] Add Framewrork
---
.../plugins/core/qdn/browser/browser.src.js | 82 +++++++++++--------
1 file changed, 47 insertions(+), 35 deletions(-)
diff --git a/plugins/plugins/core/qdn/browser/browser.src.js b/plugins/plugins/core/qdn/browser/browser.src.js
index 23816ecf..95f18177 100644
--- a/plugins/plugins/core/qdn/browser/browser.src.js
+++ b/plugins/plugins/core/qdn/browser/browser.src.js
@@ -35,6 +35,8 @@ class WebBrowser extends LitElement {
identifier: { type: String },
path: { type: String },
preview: { type: String },
+ dev: { type: String },
+ link: { type: String },
displayUrl: { type: String },
followedNames: { type: Array },
blockedNames: { type: Array },
@@ -130,11 +132,11 @@ class WebBrowser extends LitElement {
constructor() {
super();
this.url = 'about:blank';
- this.myAddress = window.parent.reduxStore.getState().app.selectedAddress;
- this._publicKey = { key: '', hasPubKey: false };
- const urlParams = new URLSearchParams(window.location.search);
- this.name = urlParams.get('name');
- this.service = urlParams.get('service');
+ this.myAddress = window.parent.reduxStore.getState().app.selectedAddress
+ this._publicKey = { key: '', hasPubKey: false }
+ const urlParams = new URLSearchParams(window.location.search)
+ this.name = urlParams.get('name')
+ this.service = urlParams.get('service')
this.identifier =
urlParams.get('identifier') != null
? urlParams.get('identifier')
@@ -145,44 +147,53 @@ class WebBrowser extends LitElement {
urlParams.get('path')
: '';
this.preview = urlParams.get('preview');
- this.followedNames = [];
- this.blockedNames = [];
+ this.link = urlParams.get('link')
+ this.dev = urlParams.get('dev')
+ this.followedNames = []
+ this.blockedNames = []
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
- this.loader = new Loader();
+ this.loader = new Loader()
+
// Build initial display URL
- let displayUrl = 'qortal://' + this.service + '/' + this.name;
- if (
- this.identifier && this.identifier != 'null' &&
- this.identifier != 'default'
- ) {
- displayUrl = displayUrl.concat('/' + this.identifier);
+ let displayUrl = ''
+
+ if (this.dev === 'FRAMEWORK') {
+ displayUrl = 'qortal://app/development'
+ } else {
+ displayUrl = 'qortal://' + this.service + '/' + this.name
+ if ( this.identifier && this.identifier != 'null' && this.identifier != 'default' ) {
+ displayUrl = displayUrl.concat('/' + this.identifier)
+ }
+ if (this.path != null && this.path != '/') {
+ displayUrl = displayUrl.concat(this.path)
+ }
}
- if (this.path != null && this.path != '/')
- displayUrl = displayUrl.concat(this.path);
- this.displayUrl = displayUrl;
+
+ this.displayUrl = displayUrl
+
const getFollowedNames = async () => {
let followedNames = await parentEpml.request('apiCall', {
url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
- });
+ })
- this.followedNames = followedNames;
+ 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 =
@@ -195,8 +206,9 @@ class WebBrowser extends LitElement {
if (this.preview != null && this.preview.length > 0) {
// In preview mode we access the preview URL path directly
this.url = `${nodeUrl}${this.preview}&theme=${this.theme}`
- }
- else {
+ } else if (this.dev === 'FRAMEWORK') {
+ this.url = `${this.link}`
+ } else {
// Normal mode
this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : ''
@@ -2741,15 +2753,15 @@ class WebBrowser extends LitElement {
}
refresh() {
- 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}${this.path != null ? this.path : ''
- }?theme=${this.theme}&identifier=${this.identifier != null ? this.identifier : ''
- }&time=${new Date().getMilliseconds()}`;
+ const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
+ const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
+ if (this.dev === 'FRAMEWORK') {
+ this.url = `${this.link}`
+ } else {
+ this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : ''
+ }?theme=${this.theme}&identifier=${this.identifier != null ? this.identifier : ''
+ }&time=${new Date().getMilliseconds()}`
+ }
}
goBackToList() {
From 1755e90731b67055b1fcab0401462c96a51e7d49 Mon Sep 17 00:00:00 2001
From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com>
Date: Fri, 14 Jul 2023 15:12:47 +0200
Subject: [PATCH 3/5] Add Dev button
---
core/src/components/show-plugin.js | 4483 ++++++++++++++--------------
1 file changed, 2305 insertions(+), 2178 deletions(-)
diff --git a/core/src/components/show-plugin.js b/core/src/components/show-plugin.js
index e32d08e6..c1ba4afc 100644
--- a/core/src/components/show-plugin.js
+++ b/core/src/components/show-plugin.js
@@ -1,2178 +1,2305 @@
-import { LitElement, html, css } from 'lit'
-import { render } from 'lit/html.js'
-import { connect } from 'pwa-helpers'
-import { store } from '../store.js'
-import { Epml } from '../epml.js'
-import { addPluginRoutes } from '../plugins/addPluginRoutes.js'
-import { repeat } from 'lit/directives/repeat.js';
-import ShortUniqueId from 'short-unique-id';
-import { setNewTab } from '../redux/app/app-actions.js'
-import localForage from 'localforage'
-import FileSaver from 'file-saver'
-import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
-
-registerTranslateConfig({
- loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
-})
-
-import '@material/mwc-button'
-import '@material/mwc-dialog'
-import '@material/mwc-icon'
-import '@material/mwc-textfield'
-import '@polymer/paper-icon-button/paper-icon-button.js'
-import '@polymer/iron-icons/iron-icons.js'
-import '@polymer/paper-dialog/paper-dialog.js'
-import '@vaadin/grid'
-import '@vaadin/text-field'
-import '../custom-elements/frag-file-input.js'
-
-const chatLastSeen = localForage.createInstance({
- name: "chat-last-seen",
-})
-
-const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
-
-class ShowPlugin extends connect(store)(LitElement) {
- static get properties() {
- return {
- app: { type: Object },
- pluginConfig: { type: Object },
- url: { type: String },
- linkParam: { type: String },
- registeredUrls: { type: Array },
- currentTab: { type: Number },
- tabs: { type: Array },
- theme: { type: String, reflect: true },
- tabInfo: { type: Object },
- chatLastSeen: { type: Array },
- chatHeads: { type: Array }
- }
- }
-
- static get styles() {
- return css`
- html {
- --scrollbarBG: #a1a1a1;
- --thumbBG: #6a6c75;
- }
-
- *::-webkit-scrollbar {
- width: 11px;
- }
-
- * {
- scrollbar-width: thin;
- scrollbar-color: var(--thumbBG) var(--scrollbarBG);
- }
-
- *::-webkit-scrollbar-track {
- background: var(--scrollbarBG);
- }
-
- *::-webkit-scrollbar-thumb {
- background-color: var(--thumbBG);
- border-radius: 6px;
- border: 3px solid var(--scrollbarBG);
- }
-
- .hideIframe {
- display: none;
- position: absolute;
- zIndex: -10;
- }
-
- .showIframe {
- display: block;
- position: relative;
- zIndex: 1;
- }
-
- .tabs {
- display: flex;
- width: 100%;
- max-width: 100%;
- justify-content: flex-start;
- padding-top: 0.5em;
- padding-left: 0.5em;
- background: var(--sidetopbar);
- border-bottom: 1px solid var(--black);
- height: 48px;
- box-sizing: border-box;
- }
-
- .tab {
- padding: 0.5em;
- background: var(--white);
- border-top-right-radius: 10px;
- border-top-left-radius: 10px;
- border-top: 1px solid grey;
- border-left: 1px solid grey;
- border-right: 1px solid grey;
- color: grey;
- cursor: pointer;
- transition: background 0.3s;
- position: relative;
- width: auto;
- min-width: 110px;
- max-width: 220px;
- overflow: hidden;
- zIndex: 2;
- }
-
- .tabCard {
- display: inline-block;
- }
-
- .tabTitle {
- display: inline-block;
- position: relative;
- width: auto;
- min-width: 1px;
- overflow: hidden;
- white-space: nowrap;
- text-overflow: ellipsis;
- }
-
- .tab:hover {
- background: var(--nav-color-hover);
- color: var(--black);
- min-width: fit-content;
- }
-
- .tab.active {
- display: inline-block;
- min-width: fit-content;
- max-width: 200px;
- margin-bottom: -1px;
- background: var(--white);
- color: var(--black);
- border-top-right-radius: 10px;
- border-top-left-radius: 10px;
- border-top: 1px solid var(--black);
- border-left: 1px solid var(--black);
- border-right: 1px solid var(--black);
- border-bottom: 1px solid var(--white);
- zIndex: 1;
- }
-
- .close {
- position: absolute;
- top: 8px;
- right: 5px;
- color: var(--black);
- --mdc-icon-size: 20px;
- }
-
- .close:hover {
- color: #C6011F;
- font-weight: bold;
- }
-
- .tab .close,
- .tab .show {
- display: none;
- }
-
- .tab.active .close,
- .tab.active .show {
- display: inline-block;
- color: var(--black);
- }
-
- .tab:hover .close,
- .tab:hover .show {
- display: inline-block;
- color: var(--black);
- }
-
- .tab .close:hover,
- .tab.active .close:hover {
- color: #C6011F;
- font-weight: bold;
- }
-
- .add-tab-button {
- margin-left: 10px;
- font-weight: bold;
- background: none;
- border: none;
- color: #03a9f4;
- font-size: 2em;
- cursor: pointer;
- transition: color 0.3s;
- }
-
- .add-tab-button:hover {
- color: var(--black);
- }
-
- .iconActive {
- position: absolute;
- top: 5px;
- color: #03a9f4;
- --mdc-icon-size: 24px;
- }
-
- .iconInactive {
- position: absolute;
- top: 5px;
- color: #999;
- --mdc-icon-size: 24px;
- }
-
- .tab:hover .iconInactive {
- color: #03a9f4;
- }
-
- .count {
- position: relative;
- top: -5px;
- font-weight: bold;
- background-color: #C6011F;
- color: white;
- font-size: 12px;
- padding: 2px 6px;
- text-align: center;
- border-radius: 5px;
- animation: pulse 1500ms infinite;
- animation-duration: 6s;
- }
-
- .ml-5 {
- margin-left: 5px;
- }
-
- .ml-10 {
- margin-left: 10px;
- }
-
- .ml-15 {
- margin-left: 15px;
- }
-
- .ml-20 {
- margin-left: 20px;
- }
-
- .ml-25 {
- margin-left: 25px;
- }
-
- .ml-30 {
- margin-left: 30px;
- }
-
- .ml-35 {
- margin-left: 35px;
- }
-
- .ml-40 {
- margin-left: 40px;
- }
-
- @keyframes pulse {
- 0% {
- box-shadow:#C6011F 0 0 0 0;
- }
- 75% {
- box-shadow:#ff69b400 0 0 0 16px;
- }
- }
- `
- }
-
- constructor() {
- super()
- this.registeredUrls = []
- this.currentTab = 0
- this.tabs = []
- this.uid = new ShortUniqueId()
- this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
- this.tabInfo = {}
- this.chatLastSeen = []
- this.chatHeads = []
- }
-
- render() {
- const plugSrc = (myPlug) => {
- return myPlug === undefined ? 'about:blank' : `${window.location.origin}/plugin/${myPlug.domain}/${myPlug.page}${this.linkParam}`
- }
-
- return html`
-
- ${this.tabs.map((tab, index) => {
- let title = ''
- let icon = ''
- let count = 0
-
- if (tab.myPlugObj && tab.myPlugObj.title === "Overview Page") {
- title = html`${translate('tabmenu.tm28')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Minting Details") {
- title = html`${translate('tabmenu.tm1')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Become a Minter") {
- title = html`${translate('tabmenu.tm2')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Sponsorship List") {
- title = html`${translate('tabmenu.tm3')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Wallets") {
- title = html`${translate('tabmenu.tm4')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Trade Portal") {
- title = html`${translate('tabmenu.tm5')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Auto Buy") {
- title = html`${translate('tabmenu.tm6')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Reward Share") {
- title = html`${translate('tabmenu.tm7')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Q-Chat") {
- title = html`${translate('tabmenu.tm8')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Name Registration") {
- title = html`${translate('tabmenu.tm9')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Names Market") {
- title = html`${translate('tabmenu.tm10')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Websites") {
- title = html`${translate('tabmenu.tm11')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Q-Apps") {
- title = html`${translate('tabmenu.tm12')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Group Management") {
- title = html`${translate('tabmenu.tm13')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Data Management") {
- title = html`${translate('tabmenu.tm14')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Puzzles") {
- title = html`${translate('tabmenu.tm15')}`
- } else if (tab.myPlugObj && tab.myPlugObj.title === "Node Management") {
- title = html`${translate('tabmenu.tm16')}`
- } else if (tab.myPlugObj && tab.myPlugObj.url === "myapp") {
- title = tab.myPlugObj && tab.myPlugObj.title
- } else {
- title = html`${translate('tabmenu.tm17')}`
- }
-
- if (tab.myPlugObj && tab.myPlugObj.mwcicon) {
- icon = tab.myPlugObj.mwcicon
- } else {
- icon = 'tab'
- }
-
- if (tab.myPlugObj && (tab.myPlugObj.url === 'websites' || tab.myPlugObj.url === 'qapps') && this.tabInfo[tab.id]) {
- title = this.tabInfo[tab.id].name
- }
-
- if (tab.myPlugObj && (tab.myPlugObj.url === 'websites' || tab.myPlugObj.url === 'qapps') && this.tabInfo[tab.id]) {
- count = this.tabInfo[tab.id].count
- }
-
- if (tab.myPlugObj && tab.myPlugObj.url === 'q-chat') {
- for (const chat of this.chatHeads) {
-
- const lastReadMessage = this.chatLastSeen.find((ch) => {
- let id
- if (chat.groupId === 0) {
- id = chat.groupId
- } else if (chat.groupId) {
- id = chat.groupId
- } else {
- id = chat.address
- }
- return ch.key.includes(id)
- })
- if (lastReadMessage && lastReadMessage.timestamp < chat.timestamp) {
- count = count + 1
- }
- }
- }
-
- return html`
-
this.currentTab = index}"
- >
-
- ${icon}
-
-
- ${count ? html`
- ${title}
- ${count}
- {this.removeTab(index, tab.id)}}>close
- ` : html`
- ${title}
- {this.removeTab(index, tab.id)}}>close
- `}
-
-
- `
- })}
-
-
-
- ${repeat(this.tabs, (tab) => tab.id, (tab, index) => html`
-
-
- this.changePage(val)}
- >
-
-
- `)}
- `
- }
-
- firstUpdated() {
- this.changeLanguage()
-
- this.tabs.forEach((tab, index) => {
- const frame = this.shadowRoot.getElementById(`showPluginFrame${index}`)
- this.createEpmlInstance(frame, index)
- })
-
- window.addEventListener('storage', () => {
- const checkLanguage = localStorage.getItem('qortalLanguage')
- const checkTheme = localStorage.getItem('qortalTheme')
-
- use(checkLanguage)
-
- if (checkTheme === 'dark') {
- this.theme = 'dark'
- } else {
- this.theme = 'light'
- }
- document.querySelector('html').setAttribute('theme', this.theme)
- })
- }
-
- changeLanguage() {
- const checkLanguage = localStorage.getItem('qortalLanguage')
-
- if (checkLanguage === null || checkLanguage.length === 0) {
- localStorage.setItem('qortalLanguage', 'us')
- use('us')
- } else {
- use(checkLanguage)
- }
- }
-
- async getUpdateComplete() {
- await super.getUpdateComplete()
- return true
- }
-
- async addTab(tab) {
- if (this.tabs == []) {
- // ...Nothing to do
- } else {
- this.tabs.forEach((rac, index) => {
- let racId = ''
- let tabRacId = ''
- let frameRacId = ''
- let plugRacId = ''
- let iconRacId = ''
-
- racId = rac.id
- tabRacId = 'tab-' + racId
- frameRacId = 'frame-' + racId
- plugRacId = 'plug-' + racId
- iconRacId = 'icon-' + racId
-
- const plugObjRac = rac.url
-
- var tabActiveRac = this.shadowRoot.getElementById(tabRacId)
- var frameActiveRac = this.shadowRoot.getElementById(frameRacId)
- var plugActiveRac = this.shadowRoot.getElementById(plugRacId)
- var iconActiveRac = this.shadowRoot.getElementById(iconRacId)
-
- if (plugObjRac === undefined || "") {
- tabActiveRac.classList.remove("active")
- iconActiveRac.classList.remove("iconActive")
- iconActiveRac.classList.add("iconInactive")
- plugActiveRac.classList.remove("showIframe")
- plugActiveRac.classList.add("hideIframe")
- } else {
- tabActiveRac.classList.remove("active")
- iconActiveRac.classList.remove("iconActive")
- iconActiveRac.classList.add("iconInactive")
- frameActiveRac.classList.remove("showIframe")
- frameActiveRac.classList.add("hideIframe")
- }
- })
- }
-
- this.tabs = [...this.tabs, tab]
- await this.getUpdateComplete()
-
- // add the new tab to the tabs array
- const newIndex = this.tabs.length - 1
-
- // render the tab and wait for it to be added to the DOM
- const frame = this.shadowRoot.getElementById(`showPluginFrame${newIndex}`)
- this.createEpmlInstance(frame, newIndex)
- }
-
- removeTab(index, tabA) {
- const tabB = this.tabs.length - 1
- const tabC = this.tabs[tabB].id
-
- if (tabC === tabA) {
- let theId = ''
- let tabId = ''
- let frameId = ''
- let plugId = ''
- let iconId = ''
-
- this.tabs = this.tabs.filter((tab, tIndex) => tIndex !== index)
-
- const tabD = this.tabs.length - 1
- const plugObj = this.tabs[tabD].url
-
- theId = this.tabs[tabD].id
- tabId = 'tab-' + theId
- frameId = 'frame-' + theId
- plugId = 'plug-' + theId
- iconId = 'icon-' + theId
-
- var tabActive = this.shadowRoot.getElementById(tabId)
- var frameActive = this.shadowRoot.getElementById(frameId)
- var plugActive = this.shadowRoot.getElementById(plugId)
- var iconActive = this.shadowRoot.getElementById(iconId)
-
- if (plugObj === undefined || "") {
- tabActive.classList.add("active")
- iconActive.classList.remove("iconInactive")
- iconActive.classList.add("iconActive")
- plugActive.classList.remove("hideIframe")
- plugActive.classList.add("showIframe")
- } else {
- tabActive.classList.add("active")
- iconActive.classList.remove("iconInactive")
- iconActive.classList.add("iconActive")
- frameActive.classList.remove("hideIframe")
- frameActive.classList.add("showIframe")
- }
- this.requestUpdate()
- } else {
- // Remove tab from array
- this.tabs = this.tabs.filter((tab, tIndex) => tIndex !== index)
-
- if (this.tabs.length !== 0) {
- this.currentTab = 0
- }
- this.requestUpdate()
- }
- }
-
- createEpmlInstance(frame, index) {
- const showingPluginEpml = new Epml({
- type: 'WINDOW',
- source: frame.contentWindow
- })
-
- addPluginRoutes(showingPluginEpml);
- showingPluginEpml.imReady()
-
- // store Epml instance in tab for later use
- this.tabs[index].epmlInstance = showingPluginEpml
-
- // Register each instance with a unique identifier
- Epml.registerProxyInstance(`visible-plugin-${index}`, showingPluginEpml)
- }
-
- updated(changedProps) {
- if (changedProps.has('url') || changedProps.has('registeredUrls')) {
- const plugArr = []
-
- this.registeredUrls.forEach(myPlugArr => {
- myPlugArr.menus.length === 0 ? plugArr.push(myPlugArr) : myPlugArr.menus.forEach(i => plugArr.push(myPlugArr, i))
- })
-
- const myPlugObj = plugArr.find(pagePlug => {
- return pagePlug.url === this.url
- })
-
- if (this.tabs.length === 0) {
- this.addTab({
- url: this.url,
- myPlugObj,
- id: this.uid()
- })
- } else {
- const copiedTabs = [...this.tabs]
- copiedTabs[this.currentTab] = {
- ...copiedTabs[this.currentTab],
- url: this.url,
- myPlugObj
- }
- this.tabs = copiedTabs
- }
- this.requestUpdate()
- }
-
- if (changedProps.has('computerUrl')) {
- if (this.computedUrl !== 'about:blank') {
- this.loading = true
- }
- }
- }
-
- changePage(page) {
- const copiedTabs = [...this.tabs]
- copiedTabs[this.currentTab] = {
- ...copiedTabs[this.currentTab],
- myPlugObj: page,
- url: page.url
- }
- this.tabs = copiedTabs
- }
-
- async stateChanged(state) {
- const split = state.app.url.split('/')
- const newRegisteredUrls = state.app.registeredUrls
-
- let newUrl, newLinkParam
-
- if (newRegisteredUrls !== this.registeredUrls) {
- this.registeredUrls = newRegisteredUrls
- }
-
- if (split[0] === '' && split[1] === 'app' && split[2] === undefined) {
- newUrl = 'wallet'
- newLinkParam = ''
- } else if (split.length === 5 && split[1] === 'app') {
- newUrl = split[2]
- newLinkParam = split[3] === undefined ? '' : '?' + split[3] + '/' + split[4]
- } else if (split[1] === 'app') {
- newUrl = split[2]
- newLinkParam = ''
- } else {
- newUrl = '404'
- newLinkParam = ''
- }
-
- if (newUrl !== this.url) {
- this.url = newUrl
- }
-
- if (newLinkParam !== this.linkParam) {
- this.linkParam = newLinkParam
- }
- if (this.tabInfo !== state.app.tabInfo) {
- this.tabInfo = state.app.tabInfo
- }
- if (this.chatLastSeen !== state.app.chatLastSeen) {
- this.chatLastSeen = state.app.chatLastSeen
- }
- if (state.app.chatHeads !== this.unModifiedChatHeads) {
- let chatHeads = []
- if (state.app.chatHeads && state.app.chatHeads.groups) {
- chatHeads = [...chatHeads, ...state.app.chatHeads.groups]
- }
- if (state.app.chatHeads && state.app.chatHeads.direct) {
- chatHeads = [...chatHeads, ...state.app.chatHeads.direct]
- }
- this.chatHeads = chatHeads
- this.unModifiedChatHeads = state.app.chatHeads
- }
-
- if (state.app.newTab) {
- const newTab = state.app.newTab
- if (!this.tabs.find((tab) => tab.id === newTab.id)) {
- this.addTab(newTab)
- this.currentTab = this.tabs.length - 1
- store.dispatch(setNewTab(null))
- //clear newTab
- } else {
- const findIndex = this.tabs.findIndex((tab) => tab.id === newTab.id)
- if (findIndex !== -1) {
- const copiedTabs = [...this.tabs]
- copiedTabs[findIndex] = newTab
- this.tabs = copiedTabs
- this.currentTab = findIndex
- }
-
- store.dispatch(setNewTab(null))
- //clear newTab
- }
- }
- }
-}
-
-window.customElements.define('show-plugin', ShowPlugin)
-
-class NavBar extends connect(store)(LitElement) {
- static get properties() {
- return {
- menuList: { type: Array },
- newMenuList: { type: Array },
- myMenuList: { type: Array },
- myMenuPlugins: { type: Array },
- myApps: { type: Array },
- addressInfo: { type: Object },
- changePage: { attribute: false },
- pluginName: { type: String },
- pluginType: { type: String },
- pluginPage: { type: String },
- mwcIcon: { type: String },
- pluginNameToDelete: { type: String },
- pluginNumberToDelete: { type: String },
- textFieldDisabled: { type: Boolean },
- initialName: { type: String },
- newId: { type: String },
- removeTitle: { type: String },
- myFollowedNames: { type: Array },
- myFollowedNamesList: { type: Array },
- searchNameContentString: { type: String },
- searchNameResources: { type: Array }
- }
- }
-
- static styles = css`
- * {
- --mdc-theme-primary: rgb(3, 169, 244);
- --mdc-theme-surface: var(--white);
- --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-dialog-content-ink-color: var(--black);
- --mdc-dialog-shape-radius: 25px;
- --mdc-dialog-min-width: 300px;
- --mdc-dialog-max-width: 700px;
- }
-
- .parent {
- display: flex;
- flex-direction: column;
- flex-flow: column;
- align-items: center;
- padding: 20px;
- height: 100vh;
- overflow-y: auto;
- }
-
- .navbar {
- display: flex;
- justify-content: space-between;
- align-items: center;
- background-color: color: var(--white);
- padding: 10px 20px;
- max-width: 750px;
- width: 80%;
- }
-
- .navbar input {
- font-size: 16px;
- color: #000;
- padding: 5px;
- flex-grow: 1;
- margin-right: 10px;
- border: 1px solid var(--black);
- }
-
- .navbar button {
- padding: 5px 10px;
- font-size: 18px;
- background-color: var(--app-background-1);
- background-image: linear-gradient(315deg, var(--app-background-1) 0%, var(--app-background-2) 74%);
- color: var(--app-icon);
- border: 1px solid transparent;
- border-radius: 3px;
- cursor: pointer;
- }
-
- .navbar button:hover {
- background-color: #45a049;
- }
-
- .app-list {
- display: flex;
- justify-content: space-between;
- padding: 10px 0;
- gap: 10px;
- flex-wrap: wrap;
- }
-
- .app-list .app-icon {
- text-align: center;
- font-size: 15px;
- font-weight: bold;
- color: var(--black);
- width: 175px;
- height: 110px;
- background: transparent;
- padding: 5px;
- display: flex;
- flex-direction: column;
- align-items: center;
- justify-content: center;
- gap: 10px;
- }
-
- .text {
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- display: block;
- width: 100%;
- min-width: 1px;
- }
-
- .app-list .app-icon span {
- display: block;
- }
-
- .app-icon-box {
- display: flex;
- align-items: center;
- padding-left: 14px;
- width: 80px;
- min-width: 80px;
- height: 80px;
- min-height: 80px;
- background-color: var(--app-background-1);
- background-image: linear-gradient(315deg, var(--app-background-1) 0%, var(--app-background-2) 74%);
- border-top-left-radius: 10px;
- border-top-right-radius: 20px;
- border-bottom-left-radius: 20px;
- border-bottom-right-radius: 10px;
- }
-
- .menuIcon {
- color: var(--app-icon);
- --mdc-icon-size: 64px;
- cursor: pointer;
- }
-
- .menuIconPos {
- position: relative;
- right: 26px;
- }
-
- .removeIcon {
- color: var(--black);
- --mdc-icon-size: 28px;
- cursor: pointer;
- }
-
- .removeIcon:hover {
- color: #C6011F;
- font-weight: bold;
- }
-
- .removeIconPos {
- position: relative;
- top: -36px;
- left: 62px;
- }
-
- .red {
- --mdc-theme-primary: #F44336;
- }
-
- select {
- padding: 10px 10px 10px 10px;
- width: 100%;
- font-size: 16px;
- font-weight: 500;
- background: var(--white);
- color: var(--black);
- -webkit-appearance: none;
- -moz-appearance: none;
- appearance: none;
- background-image: url('/img/arrow.png');
- background-repeat: no-repeat;
- background-position: right 10px center;
- background-size: 20px;
- }
-
- .resetIcon {
- position: fixed;
- right: 20px;
- top: 116px;
- color: #666;
- --mdc-icon-size: 32px;
- cursor: pointer;
- }
-
- .resetIcon:hover {
- color: #03a9f4;
- font-weight: bold;
- }
-
- .searchIcon {
- position: fixed;
- left: 20px;
- top: 116px;
- color: #666;
- --mdc-icon-size: 32px;
- cursor: pointer;
- }
-
- .searchIcon:hover {
- color: #03a9f4;
- font-weight: bold;
- }
-
- .importIcon {
- position: fixed;
- left: 20px;
- bottom: 16px;
- color: #666;
- --mdc-icon-size: 32px;
- cursor: pointer;
- }
-
- .importIcon:hover {
- color: #03a9f4;
- font-weight: bold;
- }
-
- .exportIcon {
- position: fixed;
- right: 20px;
- bottom: 16px;
- color: #666;
- --mdc-icon-size: 32px;
- cursor: pointer;
- }
-
- .exportIcon:hover {
- color: #03a9f4;
- font-weight: bold;
- }
-
- paper-dialog.searchSettings {
- width: 100%;
- max-width: 550px;
- height: auto;
- max-height: 600px;
- background-color: var(--white);
- color: var(--black);
- line-height: 1.6;
- overflow: hidden;
- border: 1px solid var(--black);
- border-radius: 10px;
- padding: 15px;
- }
-
- paper-dialog button {
- padding: 5px 10px;
- font-size: 18px;
- background-color: #03a9f4;
- color: white;
- border: 1px solid transparent;
- border-radius: 5px;
- cursor: pointer;
- }
-
- paper-dialog button:hover {
- opacity: 0.8;
- cursor: pointer;
- }
-
- .search {
- display: inline;
- width: 50%;
- align-items: center;
- }
-
- .divCard {
- height: auto;
- max-height: 500px;
- border: 1px solid var(--border);
- padding: 1em;
- margin-bottom: 1em;
- }
-
- img {
- border-radius: 25%;
- max-width: 32px;
- height: 100%;
- max-height: 32px;
- }
-
- vaadin-text-field[focused]::part(input-field) {
- border-color: #03a9f4;
- }
- `
-
- constructor() {
- super()
- this.menuList = []
- this.newMenuList = []
- this.myMenuList = []
- this.myMenuPlugins = []
- this.addressInfo = {}
- this.pluginName = ''
- this.pluginType = ''
- this.pluginPage = ''
- this.myApps = ''
- this.mwcIcon = ''
- this.pluginNameToDelete = ''
- this.pluginNumberToDelete = ''
- this.textFieldDisabled = false
- this.initialName = ''
- this.newId = ''
- this.removeTitle = ''
- this.myFollowedNames = []
- this.myFollowedNamesList = []
- this.searchContentString = ''
- this.searchNameResources = []
- }
-
- render() {
- return html`
-
-
this.resetMenu()}" title="${translate("tabmenu.tm29")}">reset_tv
-
this.openNameSearch()}" title="${translate("tabmenu.tm30")}">person_search
-
this.openImportDialog()}" title="${translate("tabmenu.tm33")}">upload
-
this.exportTabMenu()}" title="${translate("tabmenu.tm34")}">download
-
-
-
-
-
- ${repeat(this.myMenuList, (plugin) => plugin.url, (plugin, index) => html`
-
-
- ${this.renderRemoveIcon(plugin.url, plugin.mwcicon, plugin.title, plugin.pluginNumber, plugin)}
-
- ${this.renderTitle(plugin.url, plugin.title)}
-
- `)}
-
this.openAddNewPlugin()}">
-
-
-
-
${translate("tabmenu.tm19")}
-
-
-
-
-
-
${translate("tabmenu.tm26")}
-
-
-
- ${translate("tabmenu.tm24")}
-
-
-
-
-
-
-
- ${translate("tabmenu.tm19")}
-
-
- ${translate("general.close")}
-
-
-
-
-
${translate("tabmenu.tm27")}
-
-
- ${translate("tabmenu.tm23")}
- ${this.removeTitle}
-
- ${translate("general.yes")}
-
-
- ${translate("general.no")}
-
-
-
-
-
-
-
-
this.searchNameResult()}" title="${translate("websitespage.schange35")}">
-
this.closeNameSearch()}" title="${translate("general.close")}">
-
-
-
-
- {
- render(html`${this.renderNameAvatar(data.item)}`, root)
- }}
- >
-
- {
- render(html`${data.item.name}`, root)
- }}
- >
-
- {
- render(html`${this.renderMyFollowUnfollowButton(data.item)}`, root)
- }}
- >
-
-
- ${this.isEmptyArray(this.searchNameResources) ? html`
- ${translate("login.entername")}
- `: ''}
-
-
-
-
-
-
-
-
${translate("tabmenu.tm31")}
-
-
-
-
- {
- render(html`${this.renderNameAvatar(data.item)}`, root)
- }}
- >
-
- {
- render(html`${data.item.name}`, root)
- }}
- >
-
- {
- render(html`${this.renderMyFollowUnfollowButton(data.item)}`, root)
- }}
- >
-
-
- ${this.isEmptyArray(this.myFollowedNamesList) ? html`
- ${translate("tabmenu.tm32")}
- `: ''}
-
-
-
-
-
-
-
- `
- }
-
- async firstUpdated() {
- addPluginRoutes(parentEpml)
- parentEpml.imReady()
-
- const addressInfo = this.addressInfo
- const isMinter = addressInfo?.error !== 124 && +addressInfo?.level > 0
- const isSponsor = +addressInfo?.level >= 5
- const appDelay = ms => new Promise(res => setTimeout(res, ms))
-
- await appDelay(50)
-
- await this.checkMyMenuPlugins()
-
- if (!isMinter) {
- this.newMenuList = this.myMenuPlugins.filter((minter) => {
- return minter.url !== 'minting'
- })
- } else {
- this.newMenuList = this.myMenuPlugins.filter((minter) => {
- return minter.url !== 'become-minter'
- })
- }
-
- if (!isSponsor) {
- this.myMenuList = this.newMenuList.filter((sponsor) => {
- return sponsor.url !== 'sponsorship-list'
- })
- } else {
- this.myMenuList = this.newMenuList
- }
-
- await this.getMyFollowedNames()
- await this.getMyFollowedNamesList()
- }
-
- openImportDialog() {
- this.shadowRoot.getElementById('importTabMenutDialog').show()
- }
-
- importTabMenu(file) {
- this.myMenuPlugins = []
- let myFile = ''
- localStorage.removeItem("myMenuPlugs")
- myFile = file
- const newTabMenu = JSON.parse((myFile) || "[]")
- localStorage.setItem("myMenuPlugs", JSON.stringify(newTabMenu))
- this.shadowRoot.getElementById('importTabMenutDialog').close()
- this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
- this.firstUpdated()
-
- let success5string = get("tabmenu.tm36")
- parentEpml.request('showSnackBar', `${success5string}`)
- }
-
- exportTabMenu() {
- let tabMenu = ""
- const qortalTabMenu = JSON.stringify(localStorage.getItem("myMenuPlugs"))
- const qortalTabMenuSave = JSON.parse((qortalTabMenu) || "[]")
- const blob = new Blob([qortalTabMenuSave ], { type: 'text/plain;charset=utf-8' })
- tabMenu = "qortal.tabmenu"
- this.saveFileToDisk(blob, tabMenu)
- }
-
- 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("tabmenu.tm37")
- parentEpml.request('showSnackBar', `${snack4string} ${fileName}`)
- } catch (error) {
- if (error.name === 'AbortError') {
- return
- }
- FileSaver.saveAs(blob, fileName)
- let snack4string = get("tabmenu.tm37")
- parentEpml.request('showSnackBar', `${snack4string} ${fileName}`)
- }
- }
-
- openNameSearch() {
- this.searchNameResources = []
- this.shadowRoot.getElementById('searchNameContent').value = ''
- this.shadowRoot.getElementById('myFollowedNamesDialog').close()
- this.shadowRoot.getElementById('searchNameDialog').open()
- }
-
- closeNameSearch() {
- this.shadowRoot.getElementById('searchNameDialog').close()
- }
-
- openMyFollowedNames() {
- this.shadowRoot.getElementById('searchNameDialog').close()
- this.shadowRoot.getElementById('myFollowedNamesDialog').open()
- this.getMyFollowedNamesList()
- }
-
- closeMyFollowedNames() {
- this.shadowRoot.getElementById('myFollowedNamesDialog').close()
- }
-
- async getMyFollowedNames() {
- let myFollowedNames = await parentEpml.request('apiCall', {
- url: `/lists/followedNames?apiKey=${this.getApiKey()}`
- })
-
- this.myFollowedNames = myFollowedNames
- }
-
- searchNameKeyListener(e) {
- if (e.key === 'Enter') {
- this.searchNameResult()
- }
- }
-
- async getMyFollowedNamesList() {
- const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
- const myNodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
- const followedNamesUrl = `${myNodeUrl}/lists/followedNames?apiKey=${this.getApiKey()}`
-
- var myFollowedNamesNew = []
-
- this.myFollowedNamesList = []
-
- await fetch(followedNamesUrl).then(response => {
- return response.json()
- }).then(data => {
- return data.map(item => {
- const addListName = {
- name: item
- }
- myFollowedNamesNew.push(addListName)
- })
- })
- this.myFollowedNamesList = myFollowedNamesNew
- if(this.shadowRoot.getElementById('myFollowedNamesDialog').opened) {
- this.shadowRoot.getElementById('myFollowedNamesDialog').notifyResize()
- }
- }
-
- async searchNameResult() {
- let searchMyName = this.shadowRoot.getElementById('searchNameContent').value
- if (searchMyName.length === 0) {
- let err1string = get("appspage.schange34")
- parentEpml.request('showSnackBar', `${err1string}`)
- } else {
- let searchNameResources = await parentEpml.request('apiCall', {
- url: `/names/search?query=${searchMyName}&prefix=true&limit=0&reverse=true`
- })
- if (this.isEmptyArray(searchNameResources)) {
- let err2string = get("appspage.schange17")
- parentEpml.request('showSnackBar', `${err2string}`)
- } else {
- this.searchNameResources = searchNameResources
- if(this.shadowRoot.getElementById('searchNameDialog').opened) {
- this.shadowRoot.getElementById('searchNameDialog').notifyResize()
- }
- }
- }
- }
-
- renderNameAvatar(nameObj) {
- let myName = nameObj.name
- const myNameNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
- const myNodeUrl = myNameNode.protocol + '://' + myNameNode.domain + ':' + myNameNode.port
- const nameUrl = `${myNodeUrl}/arbitrary/THUMBNAIL/${myName}/qortal_avatar?async=true`
- return html`
`
- }
-
- renderMyFollowUnfollowButton(nameObj) {
- let name = nameObj.name
-
- if (this.myFollowedNames == null || !Array.isArray(this.myFollowedNames)) {
- return html``
- }
-
- if (this.myFollowedNames.indexOf(name) === -1) {
- return html` this.myFollowName(nameObj)}>add_to_queue ${translate("appspage.schange29")}`
- } else {
- return html` this.myUnfollowName(nameObj)}>remove_from_queue ${translate("appspage.schange30")}`
- }
- }
-
- async myFollowName(nameObj) {
- let name = nameObj.name
- let items = [
- name
- ]
- let namesJsonString = JSON.stringify({ "items": items })
-
- let ret = await parentEpml.request('apiCall', {
- url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
- method: 'POST',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: `${namesJsonString}`
- })
-
- if (ret === true) {
- this.myFollowedNames = this.myFollowedNames.filter(item => item != name)
- this.myFollowedNames.push(name)
- } else {
- let err3string = get("appspage.schange22")
- parentEpml.request('showSnackBar', `${err3string}`)
- }
- this.getMyFollowedNamesList()
- return ret
- }
-
- async myUnfollowName(nameObj) {
- let name = nameObj.name
- let items = [
- name
- ]
- let namesJsonString = JSON.stringify({ "items": items })
-
- let ret = await parentEpml.request('apiCall', {
- url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
- method: 'DELETE',
- headers: {
- 'Content-Type': 'application/json'
- },
- body: `${namesJsonString}`
- })
-
- if (ret === true) {
- this.myFollowedNames = this.myFollowedNames.filter(item => item != name)
- } else {
- let err4string = get("appspage.schange23")
- parentEpml.request('showSnackBar', `${err4string}`)
- }
- this.getMyFollowedNamesList()
- return ret
- }
-
- async checkMyMenuPlugins() {
- const appDelay = ms => new Promise(res => setTimeout(res, ms))
-
- if (localStorage.getItem("myMenuPlugs") === null) {
- await appDelay(1000)
- const myObj = JSON.stringify(this.menuList)
- localStorage.setItem("myMenuPlugs", myObj)
- this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
- } else {
- this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
- }
- }
-
- resetMenu() {
- localStorage.removeItem("myMenuPlugs")
- this.firstUpdated()
- }
-
- val() {
- const theValue = this.shadowRoot.getElementById("pluginTypeInput").value
-
- if (theValue === "reject") {
- this.textFieldDisabled = false
- this.initialName = ''
- this.mwcIcon = ''
- } else if (theValue === "0") {
- this.textFieldDisabled = false
- this.initialName = ''
- this.mwcIcon = ''
- } else if (theValue === "1") {
- this.textFieldDisabled = false
- this.initialName = ''
- this.mwcIcon = ''
- } else if (theValue === 'overview-page') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Overview Page'
- this.mwcIcon = 'home'
- } else if (theValue === 'minting') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Minting Details'
- this.mwcIcon = 'info_outline'
- } else if (theValue === 'become-minter') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Become a Minter'
- this.mwcIcon = 'thumb_up'
- } else if (theValue === 'sponsorship-list') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Sponsorship List'
- this.mwcIcon = 'format_list_numbered'
- } else if (theValue === 'wallet') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Wallets'
- this.mwcIcon = 'account_balance_wallet'
- } else if (theValue === 'trade-portal') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Trade Portal'
- this.mwcIcon = 'format_list_bulleted'
- } else if (theValue === 'trade-bot-portal') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Auto Buy'
- this.mwcIcon = 'shop'
- } else if (theValue === 'reward-share') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Reward Share'
- this.mwcIcon = 'ios_share'
- } else if (theValue === 'q-chat') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Q-Chat'
- this.mwcIcon = 'forum'
- } else if (theValue === 'name-registration') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Name Registration'
- this.mwcIcon = 'manage_accounts'
- } else if (theValue === 'names-market') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Names Market'
- this.mwcIcon = 'store'
- } else if (theValue === 'websites') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Websites'
- this.mwcIcon = 'desktop_mac'
- } else if (theValue === 'qapps') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Q-Apps'
- this.mwcIcon = 'apps'
- } else if (theValue === 'group-management') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Group Management'
- this.mwcIcon = 'group'
- } else if (theValue === 'data-management') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Data Management'
- this.mwcIcon = 'storage'
- } else if (theValue === 'puzzles') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Puzzles'
- this.mwcIcon = 'extension'
- } else if (theValue === 'node-management') {
- this.mwcIcon = ''
- this.initialName = ''
- this.textFieldDisabled = true
- this.initialName = 'Node Management'
- this.mwcIcon = 'cloud'
- }
- }
-
- filterSelectMenu() {
- const addressInfoSelect = this.addressInfo
- const isMinterSelect = addressInfoSelect?.error !== 124 && +addressInfoSelect?.level > 0
- const isSponsorSelect = +addressInfoSelect?.level >= 5
-
- if (!isMinterSelect) {
- return html`
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `
- } else if (isMinterSelect && isSponsorSelect) {
- return html`
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `
- } else {
- return html`
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- `
- }
- }
-
- openAddNewPlugin() {
- this.shadowRoot.getElementById("pluginTypeInput").value = 'reject'
- this.shadowRoot.getElementById("pluginNameInput").value = ''
- this.initialName = ''
- this.textFieldDisabled = false
- this.shadowRoot.querySelector('#addNewPlugin').show()
- }
-
- async addToMyMenuPlugins() {
- this.newId = ''
- const newUid = new ShortUniqueId({ length: 10 })
- this.newId = 'plugin-' + newUid()
-
- this.pluginType = this.shadowRoot.getElementById("pluginTypeInput").value
-
- if (this.pluginType === "reject") {
- let myplugerr = get("tabmenu.tm25")
- parentEpml.request('showSnackBar', `${myplugerr}`)
- return false
- } else if (this.pluginType === "0") {
- this.mwcIcon = ''
- this.pluginName = this.shadowRoot.getElementById('pluginNameInput').value
-
- if (this.pluginName === "Q-Blog") {
- this.mwcIcon = 'rss_feed'
- } else if (this.pluginName === "Q-Mail") {
- this.mwcIcon = 'mail'
- } else {
- this.mwcIcon = 'apps'
- }
-
- var oldMenuPlugs = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
-
- const newMenuPlugsItem = {
- "url": "myapp",
- "domain": "core",
- "page": `qdn/browser/index.html?name=${this.pluginName}&service=APP`,
- "title": this.pluginName,
- "icon": "vaadin:external-browser",
- "mwcicon": this.mwcIcon,
- "pluginNumber": this.newId,
- "menus": [],
- "parent": false
- }
-
- const validatePluginName = async () => {
- if (this.pluginType === "0" && this.pluginName.length == 0) {
- let myplugstring1 = get("walletpage.wchange50")
- parentEpml.request('showSnackBar', `${myplugstring1}`)
- return false
- }
-
- let myPluginName = false
- this.myPluginNameRes = []
-
- await parentEpml.request('apiCall', {
- url: `/arbitrary/resources/search?service=APP&query=${this.pluginName}&exactmatchnames=true&limit=1`
- }).then(res => {
- this.myPluginNameRes = res
- })
-
- if (this.myPluginNameRes === undefined || this.myPluginNameRes.length == 0) {
- myPluginName = false
- } else {
- myPluginName = true
- }
- return myPluginName
- }
-
- let myNameRes = await validatePluginName()
-
- if (myNameRes !== false) {
- oldMenuPlugs.push(newMenuPlugsItem)
-
- localStorage.setItem("myMenuPlugs", JSON.stringify(oldMenuPlugs))
-
- let myplugstring2 = get("walletpage.wchange52")
- parentEpml.request('showSnackBar', `${myplugstring2}`)
-
- this.closeAddNewPlugin()
-
- this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
- this.firstUpdated()
- } else {
- let myplugstring3 = get("websitespage.schange17")
- parentEpml.request('showSnackBar', `${myplugstring3}`)
- return false
- }
- } else if (this.pluginType === "1") {
- this.mwcIcon = ''
- this.pluginName = this.shadowRoot.getElementById('pluginNameInput').value
-
- this.mwcIcon = 'web'
-
- var oldMenuPlugs = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
-
- const newMenuPlugsItem = {
- "url": "myapp",
- "domain": "core",
- "page": `qdn/browser/index.html?name=${this.pluginName}&service=WEBSITE`,
- "title": this.pluginName,
- "icon": "vaadin:external-browser",
- "mwcicon": this.mwcIcon,
- "pluginNumber": this.newId,
- "menus": [],
- "parent": false
- }
-
- const validatePluginName = async () => {
- if (this.pluginType === "1" && this.pluginName.length == 0) {
- let myplugstring1 = get("walletpage.wchange50")
- parentEpml.request('showSnackBar', `${myplugstring1}`)
- return false
- }
-
- let myPluginName = false
- this.myPluginNameRes = []
-
- await parentEpml.request('apiCall', {
- url: `/arbitrary/resources/search?service=WEBSITE&query=${this.pluginName}&exactmatchnames=true&limit=1`
- }).then(res => {
- this.myPluginNameRes = res
- })
-
- if (this.myPluginNameRes === undefined || this.myPluginNameRes.length == 0 ) {
- myPluginName = false
- } else {
- myPluginName = true
- }
- return myPluginName
- }
-
- let myNameRes = await validatePluginName()
-
- if (myNameRes !== false) {
- oldMenuPlugs.push(newMenuPlugsItem)
-
- localStorage.setItem("myMenuPlugs", JSON.stringify(oldMenuPlugs))
-
- let myplugstring2 = get("walletpage.wchange52")
- parentEpml.request('showSnackBar', `${myplugstring2}`)
-
- this.closeAddNewPlugin()
-
- this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
- this.firstUpdated()
- } else {
- let myplugstring3 = get("websitespage.schange17")
- parentEpml.request('showSnackBar', `${myplugstring3}`)
- return false
- }
- } else {
- this.pluginPage = ''
- if (this.pluginType === 'overview-page') {
- this.pluginPage = 'overview-page/index.html'
- } else if (this.pluginType === 'minting') {
- this.pluginPage = 'minting/index.html'
- } else if (this.pluginType === 'become-minter') {
- this.pluginPage = 'become-minter/index.html'
- } else if (this.pluginType === 'sponsorship-list') {
- this.pluginPage = 'sponsorship-list/index.html'
- } else if (this.pluginType === 'wallet') {
- this.pluginPage = 'wallet/index.html'
- } else if (this.pluginType === 'trade-portal') {
- this.pluginPage = 'trade-portal/index.html'
- } else if (this.pluginType === 'trade-bot-portal') {
- this.pluginPage = 'trade-bot/index.html'
- } else if (this.pluginType === 'reward-share') {
- this.pluginPage = 'reward-share/index.html'
- } else if (this.pluginType === 'q-chat') {
- this.pluginPage = 'messaging/q-chat/index.html'
- } else if (this.pluginType === 'name-registration') {
- this.pluginPage = 'name-registration/index.html'
- } else if (this.pluginType === 'names-market') {
- this.pluginPage = 'names-market/index.html'
- } else if (this.pluginType === 'websites') {
- this.pluginPage = 'qdn/index.html'
- } else if (this.pluginType === 'qapps') {
- this.pluginPage = 'q-app/index.html'
- } else if (this.pluginType === 'group-management') {
- this.pluginPage = 'group-management/index.html'
- } else if (this.pluginType === 'data-management') {
- this.pluginPage = 'qdn/data-management/index.html'
- } else if (this.pluginType === 'puzzles') {
- this.pluginPage = 'puzzles/index.html'
- } else if (this.pluginType === 'node-management') {
- this.pluginPage = 'node-management/index.html'
- }
-
- var oldMenuPlugs = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
-
- const newMenuPlugsItem = {
- "url": this.pluginType,
- "domain": "core",
- "page": this.pluginPage,
- "title": this.initialName,
- "icon": "vaadin:external-browser",
- "mwcicon": this.mwcIcon,
- "pluginNumber": this.newId,
- "menus": [],
- "parent": false
- }
-
- oldMenuPlugs.push(newMenuPlugsItem)
-
- localStorage.setItem("myMenuPlugs", JSON.stringify(oldMenuPlugs))
-
- let myplugstring2 = get("walletpage.wchange52")
- parentEpml.request('showSnackBar', `${myplugstring2}`)
-
- this.closeAddNewPlugin()
-
- this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
- this.firstUpdated()
- }
- }
-
- closeAddNewPlugin() {
- this.shadowRoot.querySelector('#addNewPlugin').close()
- this.shadowRoot.getElementById("pluginTypeInput").value = 'reject'
- this.shadowRoot.getElementById("pluginNameInput").value = ''
- this.initialName = ''
- this.textFieldDisabled = false
- }
-
- renderTitle(theUrl, theName) {
- if (theUrl === 'overview-page') {
- return html`${translate('tabmenu.tm28')}`
- } else if (theUrl === 'minting') {
- return html`${translate('tabmenu.tm1')}`
- } else if (theUrl === 'become-minter') {
- return html`${translate('tabmenu.tm2')}`
- } else if (theUrl === 'sponsorship-list') {
- return html`${translate('tabmenu.tm3')}`
- } else if (theUrl === 'wallet') {
- return html`${translate('tabmenu.tm4')}`
- } else if (theUrl === 'trade-portal') {
- return html`${translate('tabmenu.tm5')}`
- } else if (theUrl === 'trade-bot-portal') {
- return html`${translate('tabmenu.tm6')}`
- } else if (theUrl === 'reward-share') {
- return html`${translate('tabmenu.tm7')}`
- } else if (theUrl === 'q-chat') {
- return html`${translate('tabmenu.tm8')}`
- } else if (theUrl === 'name-registration') {
- return html`${translate('tabmenu.tm9')}`
- } else if (theUrl === 'names-market') {
- return html`${translate('tabmenu.tm10')}`
- } else if (theUrl === 'websites') {
- return html`${translate('tabmenu.tm11')}`
- } else if (theUrl === 'qapps') {
- return html`${translate('tabmenu.tm12')}`
- } else if (theUrl === 'group-management') {
- return html`${translate('tabmenu.tm13')}`
- } else if (theUrl === 'data-management') {
- return html`${translate('tabmenu.tm14')}`
- } else if (theUrl === 'puzzles') {
- return html`${translate('tabmenu.tm15')}`
- } else if (theUrl === 'node-management') {
- return html`${translate('tabmenu.tm16')}`
- } else {
- return html`${theName}`
- }
- }
-
- renderRemoveIcon(appurl, appicon, appname, appid, appplugin) {
- return html`
- this.openRemoveApp(appname, appid, appurl)}">
- backspace
-
-
- `
- }
-
- openRemoveApp(pluginNameTD, pluginNumberTD, pluginUrlTD) {
- this.pluginNameToDelete = ''
- this.pluginNameToDelete = pluginNameTD
- this.pluginNumberToDelete = ''
- this.pluginNumberToDelete = pluginNumberTD
- this.removeTitle = ''
- if (pluginUrlTD === 'overview-page') {
- this.removeTitle = html`${translate('tabmenu.tm28')}`
- } else if (pluginUrlTD === 'minting') {
- this.removeTitle = html`${translate('tabmenu.tm1')}`
- } else if (pluginUrlTD === 'become-minter') {
- this.removeTitle = html`${translate('tabmenu.tm2')}`
- } else if (pluginUrlTD === 'sponsorship-list') {
- this.removeTitle = html`${translate('tabmenu.tm3')}`
- } else if (pluginUrlTD === 'wallet') {
- this.removeTitle = html`${translate('tabmenu.tm4')}`
- } else if (pluginUrlTD === 'trade-portal') {
- this.removeTitle = html`${translate('tabmenu.tm5')}`
- } else if (pluginUrlTD === 'trade-bot-portal') {
- this.removeTitle = html`${translate('tabmenu.tm6')}`
- } else if (pluginUrlTD === 'reward-share') {
- this.removeTitle = html`${translate('tabmenu.tm7')}`
- } else if (pluginUrlTD === 'q-chat') {
- this.removeTitle = html`${translate('tabmenu.tm8')}`
- } else if (pluginUrlTD === 'name-registration') {
- this.removeTitle = html`${translate('tabmenu.tm9')}`
- } else if (pluginUrlTD === 'names-market') {
- this.removeTitle = html`${translate('tabmenu.tm10')}`
- } else if (pluginUrlTD === 'websites') {
- this.removeTitle = html`${translate('tabmenu.tm11')}`
- } else if (pluginUrlTD === 'qapps') {
- this.removeTitle = html`${translate('tabmenu.tm12')}`
- } else if (pluginUrlTD === 'group-management') {
- this.removeTitle = html`${translate('tabmenu.tm13')}`
- } else if (pluginUrlTD === 'data-management') {
- this.removeTitle = html`${translate('tabmenu.tm14')}`
- } else if (pluginUrlTD === 'puzzles') {
- this.removeTitle = html`${translate('tabmenu.tm15')}`
- } else if (pluginUrlTD === 'node-management') {
- this.removeTitle = html`${translate('tabmenu.tm16')}`
- } else {
- this.removeTitle = html`${pluginNameTD}`
- }
- this.shadowRoot.querySelector('#removePlugin').show()
- }
-
- removeAppFromArray() {
- const pluginToRemove = this.pluginNumberToDelete
- this.newMenuFilter = []
- this.newMenuFilter = this.myMenuList.filter((item) => item.pluginNumber !== pluginToRemove)
- const myNewObj = JSON.stringify(this.newMenuFilter)
- localStorage.removeItem("myMenuPlugs")
- localStorage.setItem("myMenuPlugs", myNewObj)
- this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
- this.firstUpdated()
- this.closeRemoveApp()
- }
-
- closeRemoveApp() {
- this.shadowRoot.querySelector('#removePlugin').close()
- this.pluginNameToDelete = ''
- this.pluginNumberToDelete = ''
- }
-
- async extractComponents(url) {
- if (!url.startsWith("qortal://")) {
- return null
- }
-
- url = url.replace(/^(qortal\:\/\/)/, "")
- if (url.includes("/")) {
- let parts = url.split("/")
- const service = parts[0].toUpperCase()
- parts.shift()
- const name = parts[0]
- parts.shift()
- let identifier
-
- if (parts.length > 0) {
- identifier = parts[0] // Do not shift yet
- // Check if a resource exists with this service, name and identifier combination
- const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
- const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
- const url = `${nodeUrl}/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${myNode.apiKey}}`
-
- const res = await fetch(url);
- 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
- }
-
- async getQuery(value) {
- let newQuery = value
- 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}`
- }
-
- if (service === "APP") {
- this.changePage({
- "url": "qapp",
- "domain": "core",
- "page": `qdn/browser/index.html${query}`,
- "title": "Q-App",
- "icon": "vaadin:external-browser",
- "mwcicon": "open_in_browser",
- "menus": [],
- "parent": false
- })
- } else if (service === "WEBSITE") {
- this.changePage({
- "url": "websites",
- "domain": "core",
- "page": `qdn/browser/index.html${query}`,
- "title": "Website",
- "icon": "vaadin:desktop",
- "mwcicon": "desktop_mac",
- "menus": [],
- "parent": false
- })
- }
- }
-
- async handlePasteLink(e) {
- try {
- const value = this.shadowRoot.getElementById('linkInput').value
- this.getQuery(value)
- } catch (error) {
- }
- }
-
- async _handleKeyDown(e) {
- if (e.key === 'Enter') {
- try {
- const value = this.shadowRoot.getElementById('linkInput').value
- this.getQuery(value)
- } catch (error) {
- }
- }
- }
-
- getApiKey() {
- const apiNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
- let apiKey = apiNode.apiKey
- return apiKey
- }
-
- isEmptyArray(arr) {
- if (!arr) { return true }
- return arr.length === 0
- }
-
- stateChanged(state) {
- this.menuList = state.app.registeredUrls
- this.addressInfo = state.app.accountInfo.addressInfo
- }
-}
-
-customElements.define('nav-bar', NavBar)
+import { LitElement, html, css } from 'lit'
+import { render } from 'lit/html.js'
+import { connect } from 'pwa-helpers'
+import { store } from '../store.js'
+import { Epml } from '../epml.js'
+import { addPluginRoutes } from '../plugins/addPluginRoutes.js'
+import { repeat } from 'lit/directives/repeat.js';
+import ShortUniqueId from 'short-unique-id';
+import { setNewTab } from '../redux/app/app-actions.js'
+import localForage from 'localforage'
+import FileSaver from 'file-saver'
+import { use, get, translate, translateUnsafeHTML, registerTranslateConfig } from 'lit-translate'
+
+registerTranslateConfig({
+ loader: lang => fetch(`/language/${lang}.json`).then(res => res.json())
+})
+
+import '@material/mwc-button'
+import '@material/mwc-dialog'
+import '@material/mwc-icon'
+import '@material/mwc-textfield'
+import '@polymer/paper-icon-button/paper-icon-button.js'
+import '@polymer/iron-icons/iron-icons.js'
+import '@polymer/paper-dialog/paper-dialog.js'
+import '@vaadin/grid'
+import '@vaadin/text-field'
+import '../custom-elements/frag-file-input.js'
+
+const chatLastSeen = localForage.createInstance({
+ name: "chat-last-seen",
+})
+
+const parentEpml = new Epml({ type: 'WINDOW', source: window.parent })
+
+class ShowPlugin extends connect(store)(LitElement) {
+ static get properties() {
+ return {
+ app: { type: Object },
+ pluginConfig: { type: Object },
+ url: { type: String },
+ linkParam: { type: String },
+ registeredUrls: { type: Array },
+ currentTab: { type: Number },
+ tabs: { type: Array },
+ theme: { type: String, reflect: true },
+ tabInfo: { type: Object },
+ chatLastSeen: { type: Array },
+ chatHeads: { type: Array },
+ proxyPort: { type: Number }
+ }
+ }
+
+ static get styles() {
+ return css`
+ html {
+ --scrollbarBG: #a1a1a1;
+ --thumbBG: #6a6c75;
+ }
+
+ *::-webkit-scrollbar {
+ width: 11px;
+ }
+
+ * {
+ scrollbar-width: thin;
+ scrollbar-color: var(--thumbBG) var(--scrollbarBG);
+ --mdc-theme-primary: rgb(3, 169, 244);
+ --mdc-theme-surface: var(--white);
+ --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-ink-color: var(--black);
+ --mdc-select-fill-color: var(--black);
+ --mdc-select-label-ink-color: var(--black);
+ --mdc-select-idle-line-color: var(--black);
+ --mdc-select-hover-line-color: var(--black);
+ --mdc-select-outlined-idle-border-color: var(--txtfieldborder);
+ --mdc-select-outlined-hover-border-color: var(--txtfieldhoverborder);
+ --mdc-dialog-content-ink-color: var(--black);
+ --mdc-dialog-shape-radius: 25px;
+ --mdc-dialog-min-width: 400px;
+ --mdc-dialog-max-width: 700px;
+ }
+
+ *::-webkit-scrollbar-track {
+ background: var(--scrollbarBG);
+ }
+
+ *::-webkit-scrollbar-thumb {
+ background-color: var(--thumbBG);
+ border-radius: 6px;
+ border: 3px solid var(--scrollbarBG);
+ }
+
+ .hideIframe {
+ display: none;
+ position: absolute;
+ zIndex: -10;
+ }
+
+ .showIframe {
+ display: block;
+ position: relative;
+ zIndex: 1;
+ }
+
+ .tabs {
+ display: flex;
+ width: 100%;
+ max-width: 100%;
+ justify-content: flex-start;
+ padding-top: 0.5em;
+ padding-left: 0.5em;
+ background: var(--sidetopbar);
+ border-bottom: 1px solid var(--black);
+ height: 48px;
+ box-sizing: border-box;
+ }
+
+ .tab {
+ padding: 0.5em;
+ background: var(--white);
+ border-top-right-radius: 10px;
+ border-top-left-radius: 10px;
+ border-top: 1px solid grey;
+ border-left: 1px solid grey;
+ border-right: 1px solid grey;
+ color: grey;
+ cursor: pointer;
+ transition: background 0.3s;
+ position: relative;
+ width: auto;
+ min-width: 110px;
+ max-width: 220px;
+ overflow: hidden;
+ zIndex: 2;
+ }
+
+ .tabCard {
+ display: inline-block;
+ }
+
+ .tabTitle {
+ display: inline-block;
+ position: relative;
+ width: auto;
+ min-width: 1px;
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ }
+
+ .tab:hover {
+ background: var(--nav-color-hover);
+ color: var(--black);
+ min-width: fit-content;
+ }
+
+ .tab.active {
+ display: inline-block;
+ min-width: fit-content;
+ max-width: 200px;
+ margin-bottom: -1px;
+ background: var(--white);
+ color: var(--black);
+ border-top-right-radius: 10px;
+ border-top-left-radius: 10px;
+ border-top: 1px solid var(--black);
+ border-left: 1px solid var(--black);
+ border-right: 1px solid var(--black);
+ border-bottom: 1px solid var(--white);
+ zIndex: 1;
+ }
+
+ .close {
+ position: absolute;
+ top: 8px;
+ right: 5px;
+ color: var(--black);
+ --mdc-icon-size: 20px;
+ }
+
+ .close:hover {
+ color: #C6011F;
+ font-weight: bold;
+ }
+
+ .tab .close,
+ .tab .show {
+ display: none;
+ }
+
+ .tab.active .close,
+ .tab.active .show {
+ display: inline-block;
+ color: var(--black);
+ }
+
+ .tab:hover .close,
+ .tab:hover .show {
+ display: inline-block;
+ color: var(--black);
+ }
+
+ .tab .close:hover,
+ .tab.active .close:hover {
+ color: #C6011F;
+ font-weight: bold;
+ }
+
+ .add-tab-button {
+ margin-left: 10px;
+ font-weight: bold;
+ background: none;
+ border: none;
+ color: #03a9f4;
+ font-size: 2em;
+ cursor: pointer;
+ transition: color 0.3s;
+ }
+
+ .add-tab-button:hover {
+ color: var(--black);
+ }
+
+ .add-dev-button {
+ position: fixed;
+ right: 20px;
+ margin-left: 10px;
+ margin-top: 4px;
+ max-height: 28px;
+ padding: 5px 5px;
+ font-size: 14px;
+ background-color: #03a9f4;
+ color: white;
+ border: 1px solid transparent;
+ border-radius: 3px;
+ cursor: pointer;
+ }
+
+ .add-dev-button:hover {
+ opacity: 0.8;
+ cursor: pointer;
+ }
+
+ .red {
+ --mdc-theme-primary: #F44336;
+ }
+
+ .iconActive {
+ position: absolute;
+ top: 5px;
+ color: #03a9f4;
+ --mdc-icon-size: 24px;
+ }
+
+ .iconInactive {
+ position: absolute;
+ top: 5px;
+ color: #999;
+ --mdc-icon-size: 24px;
+ }
+
+ .tab:hover .iconInactive {
+ color: #03a9f4;
+ }
+
+ .count {
+ position: relative;
+ top: -5px;
+ font-weight: bold;
+ background-color: #C6011F;
+ color: white;
+ font-size: 12px;
+ padding: 2px 6px;
+ text-align: center;
+ border-radius: 5px;
+ animation: pulse 1500ms infinite;
+ animation-duration: 6s;
+ }
+
+ .ml-5 {
+ margin-left: 5px;
+ }
+
+ .ml-10 {
+ margin-left: 10px;
+ }
+
+ .ml-15 {
+ margin-left: 15px;
+ }
+
+ .ml-20 {
+ margin-left: 20px;
+ }
+
+ .ml-25 {
+ margin-left: 25px;
+ }
+
+ .ml-30 {
+ margin-left: 30px;
+ }
+
+ .ml-35 {
+ margin-left: 35px;
+ }
+
+ .ml-40 {
+ margin-left: 40px;
+ }
+
+ @keyframes pulse {
+ 0% {
+ box-shadow:#C6011F 0 0 0 0;
+ }
+ 75% {
+ box-shadow:#ff69b400 0 0 0 16px;
+ }
+ }
+ `
+ }
+
+ constructor() {
+ super()
+ this.registeredUrls = []
+ this.currentTab = 0
+ this.tabs = []
+ this.uid = new ShortUniqueId()
+ this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
+ this.tabInfo = {}
+ this.chatLastSeen = []
+ this.chatHeads = []
+ this.proxyPort = 0
+ }
+
+ render() {
+ const plugSrc = (myPlug) => {
+ return myPlug === undefined ? 'about:blank' : `${window.location.origin}/plugin/${myPlug.domain}/${myPlug.page}${this.linkParam}`
+ }
+
+ return html`
+
+ ${this.tabs.map((tab, index) => {
+ let title = ''
+ let icon = ''
+ let count = 0
+
+ if (tab.myPlugObj && tab.myPlugObj.title === "Overview Page") {
+ title = html`${translate('tabmenu.tm28')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Minting Details") {
+ title = html`${translate('tabmenu.tm1')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Become a Minter") {
+ title = html`${translate('tabmenu.tm2')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Sponsorship List") {
+ title = html`${translate('tabmenu.tm3')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Wallets") {
+ title = html`${translate('tabmenu.tm4')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Trade Portal") {
+ title = html`${translate('tabmenu.tm5')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Auto Buy") {
+ title = html`${translate('tabmenu.tm6')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Reward Share") {
+ title = html`${translate('tabmenu.tm7')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Q-Chat") {
+ title = html`${translate('tabmenu.tm8')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Name Registration") {
+ title = html`${translate('tabmenu.tm9')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Names Market") {
+ title = html`${translate('tabmenu.tm10')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Websites") {
+ title = html`${translate('tabmenu.tm11')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Q-Apps") {
+ title = html`${translate('tabmenu.tm12')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Group Management") {
+ title = html`${translate('tabmenu.tm13')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Data Management") {
+ title = html`${translate('tabmenu.tm14')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Puzzles") {
+ title = html`${translate('tabmenu.tm15')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.title === "Node Management") {
+ title = html`${translate('tabmenu.tm16')}`
+ } else if (tab.myPlugObj && tab.myPlugObj.url === "myapp") {
+ title = tab.myPlugObj && tab.myPlugObj.title
+ } else if (tab.myPlugObj && tab.myPlugObj.url === "devmode") {
+ title = html`${translate('tabmenu.tm38')}`
+ } else {
+ title = html`${translate('tabmenu.tm17')}`
+ }
+
+ if (tab.myPlugObj && tab.myPlugObj.mwcicon) {
+ icon = tab.myPlugObj.mwcicon
+ } else {
+ icon = 'tab'
+ }
+
+ if (tab.myPlugObj && (tab.myPlugObj.url === 'websites' || tab.myPlugObj.url === 'qapps') && this.tabInfo[tab.id]) {
+ title = this.tabInfo[tab.id].name
+ }
+
+ if (tab.myPlugObj && (tab.myPlugObj.url === 'websites' || tab.myPlugObj.url === 'qapps') && this.tabInfo[tab.id]) {
+ count = this.tabInfo[tab.id].count
+ }
+
+ if (tab.myPlugObj && tab.myPlugObj.url === 'q-chat') {
+ for (const chat of this.chatHeads) {
+
+ const lastReadMessage = this.chatLastSeen.find((ch) => {
+ let id
+ if (chat.groupId === 0) {
+ id = chat.groupId
+ } else if (chat.groupId) {
+ id = chat.groupId
+ } else {
+ id = chat.address
+ }
+ return ch.key.includes(id)
+ })
+ if (lastReadMessage && lastReadMessage.timestamp < chat.timestamp) {
+ count = count + 1
+ }
+ }
+ }
+
+ return html`
+
this.currentTab = index}"
+ >
+
+ ${icon}
+
+
+ ${count ? html`
+ ${title}
+ ${count}
+ {this.removeTab(index, tab.id)}}>close
+ ` : html`
+ ${title}
+ {this.removeTab(index, tab.id)}}>close
+ `}
+
+
+ `
+ })}
+
+
+
+
+ ${repeat(this.tabs, (tab) => tab.id, (tab, index) => html`
+
+
+ this.changePage(val)}
+ >
+
+
+ `)}
+
+
+
${translate('tabmenu.tm39')}
+
+
+
+
+
+
+
+
+
+ ${translate("general.close")}
+
+
+ ${translate('tabmenu.tm40')}
+
+
+ `
+ }
+
+ firstUpdated() {
+ this.changeLanguage()
+
+ this.tabs.forEach((tab, index) => {
+ const frame = this.shadowRoot.getElementById(`showPluginFrame${index}`)
+ this.createEpmlInstance(frame, index)
+ })
+
+ window.addEventListener('storage', () => {
+ const checkLanguage = localStorage.getItem('qortalLanguage')
+ const checkTheme = localStorage.getItem('qortalTheme')
+
+ use(checkLanguage)
+
+ if (checkTheme === 'dark') {
+ this.theme = 'dark'
+ } else {
+ this.theme = 'light'
+ }
+ document.querySelector('html').setAttribute('theme', this.theme)
+ })
+ }
+
+ changeLanguage() {
+ const checkLanguage = localStorage.getItem('qortalLanguage')
+
+ if (checkLanguage === null || checkLanguage.length === 0) {
+ localStorage.setItem('qortalLanguage', 'us')
+ use('us')
+ } else {
+ use(checkLanguage)
+ }
+ }
+
+ async getUpdateComplete() {
+ await super.getUpdateComplete()
+ return true
+ }
+
+ openDevDialog() {
+ this.shadowRoot.getElementById('domainInput').value = ''
+ this.shadowRoot.getElementById('portInput').value = ''
+ this.shadowRoot.querySelector("#addDevDialog").show()
+ }
+
+ async getProxyPort() {
+ this.proxyPort = 0
+ let framework = ''
+
+ const domain = this.shadowRoot.getElementById('domainInput').value
+ const port = this.shadowRoot.getElementById('portInput').value
+
+ if (domain.length >= 3 && port.length >= 2) {
+ framework = domain + ':' + port
+ } else {
+ let errorString = get("tabmenu.tm41")
+ parentEpml.request('showSnackBar', `${errorString}`)
+ return
+ }
+
+ let framePort = await parentEpml.request('apiCall', {
+ url: `/developer/proxy/start`,
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'text/plain'
+ },
+ body: `${framework}`
+ })
+
+ this.createUrl(framePort)
+ }
+
+ createUrl(framePort) {
+ this.proxyPort = framePort
+ const myFrameNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
+ const myFrameNodeUrl = myFrameNode.protocol + '://' + myFrameNode.domain + ':' + this.proxyPort
+
+ this.changePage({
+ "url": "devmode",
+ "domain": "core",
+ "page": `qdn/browser/index.html?link=${myFrameNodeUrl}&dev=FRAMEWORK`,
+ "title": "Dev Server",
+ "icon": "vaadin:desktop",
+ "mwcicon": "api",
+ "menus": [],
+ "parent": false
+ })
+
+ this.shadowRoot.querySelector("#addDevDialog").close()
+ }
+
+ async addTab(tab) {
+ if (this.tabs == []) {
+ // ...Nothing to do
+ } else {
+ this.tabs.forEach((rac, index) => {
+ let racId = ''
+ let tabRacId = ''
+ let frameRacId = ''
+ let plugRacId = ''
+ let iconRacId = ''
+
+ racId = rac.id
+ tabRacId = 'tab-' + racId
+ frameRacId = 'frame-' + racId
+ plugRacId = 'plug-' + racId
+ iconRacId = 'icon-' + racId
+
+ const plugObjRac = rac.url
+
+ var tabActiveRac = this.shadowRoot.getElementById(tabRacId)
+ var frameActiveRac = this.shadowRoot.getElementById(frameRacId)
+ var plugActiveRac = this.shadowRoot.getElementById(plugRacId)
+ var iconActiveRac = this.shadowRoot.getElementById(iconRacId)
+
+ if (plugObjRac === undefined || "") {
+ tabActiveRac.classList.remove("active")
+ iconActiveRac.classList.remove("iconActive")
+ iconActiveRac.classList.add("iconInactive")
+ plugActiveRac.classList.remove("showIframe")
+ plugActiveRac.classList.add("hideIframe")
+ } else {
+ tabActiveRac.classList.remove("active")
+ iconActiveRac.classList.remove("iconActive")
+ iconActiveRac.classList.add("iconInactive")
+ frameActiveRac.classList.remove("showIframe")
+ frameActiveRac.classList.add("hideIframe")
+ }
+ })
+ }
+
+ this.tabs = [...this.tabs, tab]
+ await this.getUpdateComplete()
+
+ // add the new tab to the tabs array
+ const newIndex = this.tabs.length - 1
+
+ // render the tab and wait for it to be added to the DOM
+ const frame = this.shadowRoot.getElementById(`showPluginFrame${newIndex}`)
+ this.createEpmlInstance(frame, newIndex)
+ }
+
+ removeTab(index, tabA) {
+ const tabB = this.tabs.length - 1
+ const tabC = this.tabs[tabB].id
+
+ if (tabC === tabA) {
+ let theId = ''
+ let tabId = ''
+ let frameId = ''
+ let plugId = ''
+ let iconId = ''
+
+ this.tabs = this.tabs.filter((tab, tIndex) => tIndex !== index)
+
+ const tabD = this.tabs.length - 1
+ const plugObj = this.tabs[tabD].url
+
+ theId = this.tabs[tabD].id
+ tabId = 'tab-' + theId
+ frameId = 'frame-' + theId
+ plugId = 'plug-' + theId
+ iconId = 'icon-' + theId
+
+ var tabActive = this.shadowRoot.getElementById(tabId)
+ var frameActive = this.shadowRoot.getElementById(frameId)
+ var plugActive = this.shadowRoot.getElementById(plugId)
+ var iconActive = this.shadowRoot.getElementById(iconId)
+
+ if (plugObj === undefined || "") {
+ tabActive.classList.add("active")
+ iconActive.classList.remove("iconInactive")
+ iconActive.classList.add("iconActive")
+ plugActive.classList.remove("hideIframe")
+ plugActive.classList.add("showIframe")
+ } else {
+ tabActive.classList.add("active")
+ iconActive.classList.remove("iconInactive")
+ iconActive.classList.add("iconActive")
+ frameActive.classList.remove("hideIframe")
+ frameActive.classList.add("showIframe")
+ }
+ this.requestUpdate()
+ } else {
+ // Remove tab from array
+ this.tabs = this.tabs.filter((tab, tIndex) => tIndex !== index)
+
+ if (this.tabs.length !== 0) {
+ this.currentTab = 0
+ }
+ this.requestUpdate()
+ }
+ }
+
+ createEpmlInstance(frame, index) {
+ const showingPluginEpml = new Epml({
+ type: 'WINDOW',
+ source: frame.contentWindow
+ })
+
+ addPluginRoutes(showingPluginEpml);
+ showingPluginEpml.imReady()
+
+ // store Epml instance in tab for later use
+ this.tabs[index].epmlInstance = showingPluginEpml
+
+ // Register each instance with a unique identifier
+ Epml.registerProxyInstance(`visible-plugin-${index}`, showingPluginEpml)
+ }
+
+ updated(changedProps) {
+ if (changedProps.has('url') || changedProps.has('registeredUrls')) {
+ const plugArr = []
+
+ this.registeredUrls.forEach(myPlugArr => {
+ myPlugArr.menus.length === 0 ? plugArr.push(myPlugArr) : myPlugArr.menus.forEach(i => plugArr.push(myPlugArr, i))
+ })
+
+ const myPlugObj = plugArr.find(pagePlug => {
+ return pagePlug.url === this.url
+ })
+
+ if (this.tabs.length === 0) {
+ this.addTab({
+ url: this.url,
+ myPlugObj,
+ id: this.uid()
+ })
+ } else {
+ const copiedTabs = [...this.tabs]
+ copiedTabs[this.currentTab] = {
+ ...copiedTabs[this.currentTab],
+ url: this.url,
+ myPlugObj
+ }
+ this.tabs = copiedTabs
+ }
+ this.requestUpdate()
+ }
+
+ if (changedProps.has('computerUrl')) {
+ if (this.computedUrl !== 'about:blank') {
+ this.loading = true
+ }
+ }
+ }
+
+ changePage(page) {
+ const copiedTabs = [...this.tabs]
+ copiedTabs[this.currentTab] = {
+ ...copiedTabs[this.currentTab],
+ myPlugObj: page,
+ url: page.url
+ }
+ this.tabs = copiedTabs
+ }
+
+ async stateChanged(state) {
+ const split = state.app.url.split('/')
+ const newRegisteredUrls = state.app.registeredUrls
+
+ let newUrl, newLinkParam
+
+ if (newRegisteredUrls !== this.registeredUrls) {
+ this.registeredUrls = newRegisteredUrls
+ }
+
+ if (split[0] === '' && split[1] === 'app' && split[2] === undefined) {
+ newUrl = 'wallet'
+ newLinkParam = ''
+ } else if (split.length === 5 && split[1] === 'app') {
+ newUrl = split[2]
+ newLinkParam = split[3] === undefined ? '' : '?' + split[3] + '/' + split[4]
+ } else if (split[1] === 'app') {
+ newUrl = split[2]
+ newLinkParam = ''
+ } else {
+ newUrl = '404'
+ newLinkParam = ''
+ }
+
+ if (newUrl !== this.url) {
+ this.url = newUrl
+ }
+
+ if (newLinkParam !== this.linkParam) {
+ this.linkParam = newLinkParam
+ }
+ if (this.tabInfo !== state.app.tabInfo) {
+ this.tabInfo = state.app.tabInfo
+ }
+ if (this.chatLastSeen !== state.app.chatLastSeen) {
+ this.chatLastSeen = state.app.chatLastSeen
+ }
+ if (state.app.chatHeads !== this.unModifiedChatHeads) {
+ let chatHeads = []
+ if (state.app.chatHeads && state.app.chatHeads.groups) {
+ chatHeads = [...chatHeads, ...state.app.chatHeads.groups]
+ }
+ if (state.app.chatHeads && state.app.chatHeads.direct) {
+ chatHeads = [...chatHeads, ...state.app.chatHeads.direct]
+ }
+ this.chatHeads = chatHeads
+ this.unModifiedChatHeads = state.app.chatHeads
+ }
+
+ if (state.app.newTab) {
+ const newTab = state.app.newTab
+ if (!this.tabs.find((tab) => tab.id === newTab.id)) {
+ this.addTab(newTab)
+ this.currentTab = this.tabs.length - 1
+ store.dispatch(setNewTab(null))
+ //clear newTab
+ } else {
+ const findIndex = this.tabs.findIndex((tab) => tab.id === newTab.id)
+ if (findIndex !== -1) {
+ const copiedTabs = [...this.tabs]
+ copiedTabs[findIndex] = newTab
+ this.tabs = copiedTabs
+ this.currentTab = findIndex
+ }
+
+ store.dispatch(setNewTab(null))
+ //clear newTab
+ }
+ }
+ }
+}
+
+window.customElements.define('show-plugin', ShowPlugin)
+
+class NavBar extends connect(store)(LitElement) {
+ static get properties() {
+ return {
+ menuList: { type: Array },
+ newMenuList: { type: Array },
+ myMenuList: { type: Array },
+ myMenuPlugins: { type: Array },
+ myApps: { type: Array },
+ addressInfo: { type: Object },
+ changePage: { attribute: false },
+ pluginName: { type: String },
+ pluginType: { type: String },
+ pluginPage: { type: String },
+ mwcIcon: { type: String },
+ pluginNameToDelete: { type: String },
+ pluginNumberToDelete: { type: String },
+ textFieldDisabled: { type: Boolean },
+ initialName: { type: String },
+ newId: { type: String },
+ removeTitle: { type: String },
+ myFollowedNames: { type: Array },
+ myFollowedNamesList: { type: Array },
+ searchNameContentString: { type: String },
+ searchNameResources: { type: Array }
+ }
+ }
+
+ static styles = css`
+ * {
+ --mdc-theme-primary: rgb(3, 169, 244);
+ --mdc-theme-surface: var(--white);
+ --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-dialog-content-ink-color: var(--black);
+ --mdc-dialog-shape-radius: 25px;
+ --mdc-dialog-min-width: 300px;
+ --mdc-dialog-max-width: 700px;
+ }
+
+ .parent {
+ display: flex;
+ flex-direction: column;
+ flex-flow: column;
+ align-items: center;
+ padding: 20px;
+ height: 100vh;
+ overflow-y: auto;
+ }
+
+ .navbar {
+ display: flex;
+ justify-content: space-between;
+ align-items: center;
+ background-color: color: var(--white);
+ padding: 10px 20px;
+ max-width: 750px;
+ width: 80%;
+ }
+
+ .navbar input {
+ font-size: 16px;
+ color: #000;
+ padding: 5px;
+ flex-grow: 1;
+ margin-right: 10px;
+ border: 1px solid var(--black);
+ }
+
+ .navbar button {
+ padding: 5px 10px;
+ font-size: 18px;
+ background-color: var(--app-background-1);
+ background-image: linear-gradient(315deg, var(--app-background-1) 0%, var(--app-background-2) 74%);
+ color: var(--app-icon);
+ border: 1px solid transparent;
+ border-radius: 3px;
+ cursor: pointer;
+ }
+
+ .navbar button:hover {
+ background-color: #45a049;
+ }
+
+ .app-list {
+ display: flex;
+ justify-content: space-between;
+ padding: 10px 0;
+ gap: 10px;
+ flex-wrap: wrap;
+ }
+
+ .app-list .app-icon {
+ text-align: center;
+ font-size: 15px;
+ font-weight: bold;
+ color: var(--black);
+ width: 175px;
+ height: 110px;
+ background: transparent;
+ padding: 5px;
+ display: flex;
+ flex-direction: column;
+ align-items: center;
+ justify-content: center;
+ gap: 10px;
+ }
+
+ .text {
+ overflow: hidden;
+ text-overflow: ellipsis;
+ white-space: nowrap;
+ display: block;
+ width: 100%;
+ min-width: 1px;
+ }
+
+ .app-list .app-icon span {
+ display: block;
+ }
+
+ .app-icon-box {
+ display: flex;
+ align-items: center;
+ padding-left: 14px;
+ width: 80px;
+ min-width: 80px;
+ height: 80px;
+ min-height: 80px;
+ background-color: var(--app-background-1);
+ background-image: linear-gradient(315deg, var(--app-background-1) 0%, var(--app-background-2) 74%);
+ border-top-left-radius: 10px;
+ border-top-right-radius: 20px;
+ border-bottom-left-radius: 20px;
+ border-bottom-right-radius: 10px;
+ }
+
+ .menuIcon {
+ color: var(--app-icon);
+ --mdc-icon-size: 64px;
+ cursor: pointer;
+ }
+
+ .menuIconPos {
+ position: relative;
+ right: 26px;
+ }
+
+ .removeIcon {
+ color: var(--black);
+ --mdc-icon-size: 28px;
+ cursor: pointer;
+ }
+
+ .removeIcon:hover {
+ color: #C6011F;
+ font-weight: bold;
+ }
+
+ .removeIconPos {
+ position: relative;
+ top: -36px;
+ left: 62px;
+ }
+
+ .red {
+ --mdc-theme-primary: #F44336;
+ }
+
+ select {
+ padding: 10px 10px 10px 10px;
+ width: 100%;
+ font-size: 16px;
+ font-weight: 500;
+ background: var(--white);
+ color: var(--black);
+ -webkit-appearance: none;
+ -moz-appearance: none;
+ appearance: none;
+ background-image: url('/img/arrow.png');
+ background-repeat: no-repeat;
+ background-position: right 10px center;
+ background-size: 20px;
+ }
+
+ .resetIcon {
+ position: fixed;
+ right: 20px;
+ top: 116px;
+ color: #666;
+ --mdc-icon-size: 32px;
+ cursor: pointer;
+ }
+
+ .resetIcon:hover {
+ color: #03a9f4;
+ font-weight: bold;
+ }
+
+ .searchIcon {
+ position: fixed;
+ left: 20px;
+ top: 116px;
+ color: #666;
+ --mdc-icon-size: 32px;
+ cursor: pointer;
+ }
+
+ .searchIcon:hover {
+ color: #03a9f4;
+ font-weight: bold;
+ }
+
+ .importIcon {
+ position: fixed;
+ left: 20px;
+ bottom: 16px;
+ color: #666;
+ --mdc-icon-size: 32px;
+ cursor: pointer;
+ }
+
+ .importIcon:hover {
+ color: #03a9f4;
+ font-weight: bold;
+ }
+
+ .exportIcon {
+ position: fixed;
+ right: 20px;
+ bottom: 16px;
+ color: #666;
+ --mdc-icon-size: 32px;
+ cursor: pointer;
+ }
+
+ .exportIcon:hover {
+ color: #03a9f4;
+ font-weight: bold;
+ }
+
+ paper-dialog.searchSettings {
+ width: 100%;
+ max-width: 550px;
+ height: auto;
+ max-height: 600px;
+ background-color: var(--white);
+ color: var(--black);
+ line-height: 1.6;
+ overflow: hidden;
+ border: 1px solid var(--black);
+ border-radius: 10px;
+ padding: 15px;
+ }
+
+ paper-dialog button {
+ padding: 5px 10px;
+ font-size: 18px;
+ background-color: #03a9f4;
+ color: white;
+ border: 1px solid transparent;
+ border-radius: 5px;
+ cursor: pointer;
+ }
+
+ paper-dialog button:hover {
+ opacity: 0.8;
+ cursor: pointer;
+ }
+
+ .search {
+ display: inline;
+ width: 50%;
+ align-items: center;
+ }
+
+ .divCard {
+ height: auto;
+ max-height: 500px;
+ border: 1px solid var(--border);
+ padding: 1em;
+ margin-bottom: 1em;
+ }
+
+ img {
+ border-radius: 25%;
+ max-width: 32px;
+ height: 100%;
+ max-height: 32px;
+ }
+
+ vaadin-text-field[focused]::part(input-field) {
+ border-color: #03a9f4;
+ }
+ `
+
+ constructor() {
+ super()
+ this.menuList = []
+ this.newMenuList = []
+ this.myMenuList = []
+ this.myMenuPlugins = []
+ this.addressInfo = {}
+ this.pluginName = ''
+ this.pluginType = ''
+ this.pluginPage = ''
+ this.myApps = ''
+ this.mwcIcon = ''
+ this.pluginNameToDelete = ''
+ this.pluginNumberToDelete = ''
+ this.textFieldDisabled = false
+ this.initialName = ''
+ this.newId = ''
+ this.removeTitle = ''
+ this.myFollowedNames = []
+ this.myFollowedNamesList = []
+ this.searchContentString = ''
+ this.searchNameResources = []
+ }
+
+ render() {
+ return html`
+
+
this.resetMenu()}" title="${translate("tabmenu.tm29")}">reset_tv
+
this.openNameSearch()}" title="${translate("tabmenu.tm30")}">person_search
+
this.openImportDialog()}" title="${translate("tabmenu.tm33")}">upload
+
this.exportTabMenu()}" title="${translate("tabmenu.tm34")}">download
+
+
+
+
+
+ ${repeat(this.myMenuList, (plugin) => plugin.url, (plugin, index) => html`
+
+
+ ${this.renderRemoveIcon(plugin.url, plugin.mwcicon, plugin.title, plugin.pluginNumber, plugin)}
+
+ ${this.renderTitle(plugin.url, plugin.title)}
+
+ `)}
+
this.openAddNewPlugin()}">
+
+
+
+
${translate("tabmenu.tm19")}
+
+
+
+
+
+
${translate("tabmenu.tm26")}
+
+
+
+ ${translate("tabmenu.tm24")}
+
+
+
+
+
+
+
+ ${translate("tabmenu.tm19")}
+
+
+ ${translate("general.close")}
+
+
+
+
+
${translate("tabmenu.tm27")}
+
+
+ ${translate("tabmenu.tm23")}
+ ${this.removeTitle}
+
+ ${translate("general.yes")}
+
+
+ ${translate("general.no")}
+
+
+
+
+
+
+
+
this.searchNameResult()}" title="${translate("websitespage.schange35")}">
+
this.closeNameSearch()}" title="${translate("general.close")}">
+
+
+
+
+ {
+ render(html`${this.renderNameAvatar(data.item)}`, root)
+ }}
+ >
+
+ {
+ render(html`${data.item.name}`, root)
+ }}
+ >
+
+ {
+ render(html`${this.renderMyFollowUnfollowButton(data.item)}`, root)
+ }}
+ >
+
+
+ ${this.isEmptyArray(this.searchNameResources) ? html`
+ ${translate("login.entername")}
+ `: ''}
+
+
+
+
+
+
+
+
${translate("tabmenu.tm31")}
+
+
+
+
+ {
+ render(html`${this.renderNameAvatar(data.item)}`, root)
+ }}
+ >
+
+ {
+ render(html`${data.item.name}`, root)
+ }}
+ >
+
+ {
+ render(html`${this.renderMyFollowUnfollowButton(data.item)}`, root)
+ }}
+ >
+
+
+ ${this.isEmptyArray(this.myFollowedNamesList) ? html`
+ ${translate("tabmenu.tm32")}
+ `: ''}
+
+
+
+
+
+
+
+ `
+ }
+
+ async firstUpdated() {
+ addPluginRoutes(parentEpml)
+ parentEpml.imReady()
+
+ const addressInfo = this.addressInfo
+ const isMinter = addressInfo?.error !== 124 && +addressInfo?.level > 0
+ const isSponsor = +addressInfo?.level >= 5
+ const appDelay = ms => new Promise(res => setTimeout(res, ms))
+
+ await appDelay(50)
+
+ await this.checkMyMenuPlugins()
+
+ if (!isMinter) {
+ this.newMenuList = this.myMenuPlugins.filter((minter) => {
+ return minter.url !== 'minting'
+ })
+ } else {
+ this.newMenuList = this.myMenuPlugins.filter((minter) => {
+ return minter.url !== 'become-minter'
+ })
+ }
+
+ if (!isSponsor) {
+ this.myMenuList = this.newMenuList.filter((sponsor) => {
+ return sponsor.url !== 'sponsorship-list'
+ })
+ } else {
+ this.myMenuList = this.newMenuList
+ }
+
+ await this.getMyFollowedNames()
+ await this.getMyFollowedNamesList()
+ }
+
+ openImportDialog() {
+ this.shadowRoot.getElementById('importTabMenutDialog').show()
+ }
+
+ importTabMenu(file) {
+ this.myMenuPlugins = []
+ let myFile = ''
+ localStorage.removeItem("myMenuPlugs")
+ myFile = file
+ const newTabMenu = JSON.parse((myFile) || "[]")
+ localStorage.setItem("myMenuPlugs", JSON.stringify(newTabMenu))
+ this.shadowRoot.getElementById('importTabMenutDialog').close()
+ this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+ this.firstUpdated()
+
+ let success5string = get("tabmenu.tm36")
+ parentEpml.request('showSnackBar', `${success5string}`)
+ }
+
+ exportTabMenu() {
+ let tabMenu = ""
+ const qortalTabMenu = JSON.stringify(localStorage.getItem("myMenuPlugs"))
+ const qortalTabMenuSave = JSON.parse((qortalTabMenu) || "[]")
+ const blob = new Blob([qortalTabMenuSave ], { type: 'text/plain;charset=utf-8' })
+ tabMenu = "qortal.tabmenu"
+ this.saveFileToDisk(blob, tabMenu)
+ }
+
+ 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("tabmenu.tm37")
+ parentEpml.request('showSnackBar', `${snack4string} ${fileName}`)
+ } catch (error) {
+ if (error.name === 'AbortError') {
+ return
+ }
+ FileSaver.saveAs(blob, fileName)
+ let snack4string = get("tabmenu.tm37")
+ parentEpml.request('showSnackBar', `${snack4string} ${fileName}`)
+ }
+ }
+
+ openNameSearch() {
+ this.searchNameResources = []
+ this.shadowRoot.getElementById('searchNameContent').value = ''
+ this.shadowRoot.getElementById('myFollowedNamesDialog').close()
+ this.shadowRoot.getElementById('searchNameDialog').open()
+ }
+
+ closeNameSearch() {
+ this.shadowRoot.getElementById('searchNameDialog').close()
+ }
+
+ openMyFollowedNames() {
+ this.shadowRoot.getElementById('searchNameDialog').close()
+ this.shadowRoot.getElementById('myFollowedNamesDialog').open()
+ this.getMyFollowedNamesList()
+ }
+
+ closeMyFollowedNames() {
+ this.shadowRoot.getElementById('myFollowedNamesDialog').close()
+ }
+
+ async getMyFollowedNames() {
+ let myFollowedNames = await parentEpml.request('apiCall', {
+ url: `/lists/followedNames?apiKey=${this.getApiKey()}`
+ })
+
+ this.myFollowedNames = myFollowedNames
+ }
+
+ searchNameKeyListener(e) {
+ if (e.key === 'Enter') {
+ this.searchNameResult()
+ }
+ }
+
+ async getMyFollowedNamesList() {
+ const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
+ const myNodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
+ const followedNamesUrl = `${myNodeUrl}/lists/followedNames?apiKey=${this.getApiKey()}`
+
+ var myFollowedNamesNew = []
+
+ this.myFollowedNamesList = []
+
+ await fetch(followedNamesUrl).then(response => {
+ return response.json()
+ }).then(data => {
+ return data.map(item => {
+ const addListName = {
+ name: item
+ }
+ myFollowedNamesNew.push(addListName)
+ })
+ })
+ this.myFollowedNamesList = myFollowedNamesNew
+ if(this.shadowRoot.getElementById('myFollowedNamesDialog').opened) {
+ this.shadowRoot.getElementById('myFollowedNamesDialog').notifyResize()
+ }
+ }
+
+ async searchNameResult() {
+ let searchMyName = this.shadowRoot.getElementById('searchNameContent').value
+ if (searchMyName.length === 0) {
+ let err1string = get("appspage.schange34")
+ parentEpml.request('showSnackBar', `${err1string}`)
+ } else {
+ let searchNameResources = await parentEpml.request('apiCall', {
+ url: `/names/search?query=${searchMyName}&prefix=true&limit=0&reverse=true`
+ })
+ if (this.isEmptyArray(searchNameResources)) {
+ let err2string = get("appspage.schange17")
+ parentEpml.request('showSnackBar', `${err2string}`)
+ } else {
+ this.searchNameResources = searchNameResources
+ if(this.shadowRoot.getElementById('searchNameDialog').opened) {
+ this.shadowRoot.getElementById('searchNameDialog').notifyResize()
+ }
+ }
+ }
+ }
+
+ renderNameAvatar(nameObj) {
+ let myName = nameObj.name
+ const myNameNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
+ const myNodeUrl = myNameNode.protocol + '://' + myNameNode.domain + ':' + myNameNode.port
+ const nameUrl = `${myNodeUrl}/arbitrary/THUMBNAIL/${myName}/qortal_avatar?async=true`
+ return html`
`
+ }
+
+ renderMyFollowUnfollowButton(nameObj) {
+ let name = nameObj.name
+
+ if (this.myFollowedNames == null || !Array.isArray(this.myFollowedNames)) {
+ return html``
+ }
+
+ if (this.myFollowedNames.indexOf(name) === -1) {
+ return html` this.myFollowName(nameObj)}>add_to_queue ${translate("appspage.schange29")}`
+ } else {
+ return html` this.myUnfollowName(nameObj)}>remove_from_queue ${translate("appspage.schange30")}`
+ }
+ }
+
+ async myFollowName(nameObj) {
+ let name = nameObj.name
+ let items = [
+ name
+ ]
+ let namesJsonString = JSON.stringify({ "items": items })
+
+ let ret = await parentEpml.request('apiCall', {
+ url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
+ method: 'POST',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: `${namesJsonString}`
+ })
+
+ if (ret === true) {
+ this.myFollowedNames = this.myFollowedNames.filter(item => item != name)
+ this.myFollowedNames.push(name)
+ } else {
+ let err3string = get("appspage.schange22")
+ parentEpml.request('showSnackBar', `${err3string}`)
+ }
+ this.getMyFollowedNamesList()
+ return ret
+ }
+
+ async myUnfollowName(nameObj) {
+ let name = nameObj.name
+ let items = [
+ name
+ ]
+ let namesJsonString = JSON.stringify({ "items": items })
+
+ let ret = await parentEpml.request('apiCall', {
+ url: `/lists/followedNames?apiKey=${this.getApiKey()}`,
+ method: 'DELETE',
+ headers: {
+ 'Content-Type': 'application/json'
+ },
+ body: `${namesJsonString}`
+ })
+
+ if (ret === true) {
+ this.myFollowedNames = this.myFollowedNames.filter(item => item != name)
+ } else {
+ let err4string = get("appspage.schange23")
+ parentEpml.request('showSnackBar', `${err4string}`)
+ }
+ this.getMyFollowedNamesList()
+ return ret
+ }
+
+ async checkMyMenuPlugins() {
+ const appDelay = ms => new Promise(res => setTimeout(res, ms))
+
+ if (localStorage.getItem("myMenuPlugs") === null) {
+ await appDelay(1000)
+ const myObj = JSON.stringify(this.menuList)
+ localStorage.setItem("myMenuPlugs", myObj)
+ this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+ } else {
+ this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+ }
+ }
+
+ resetMenu() {
+ localStorage.removeItem("myMenuPlugs")
+ this.firstUpdated()
+ }
+
+ val() {
+ const theValue = this.shadowRoot.getElementById("pluginTypeInput").value
+
+ if (theValue === "reject") {
+ this.textFieldDisabled = false
+ this.initialName = ''
+ this.mwcIcon = ''
+ } else if (theValue === "0") {
+ this.textFieldDisabled = false
+ this.initialName = ''
+ this.mwcIcon = ''
+ } else if (theValue === "1") {
+ this.textFieldDisabled = false
+ this.initialName = ''
+ this.mwcIcon = ''
+ } else if (theValue === 'overview-page') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Overview Page'
+ this.mwcIcon = 'home'
+ } else if (theValue === 'minting') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Minting Details'
+ this.mwcIcon = 'info_outline'
+ } else if (theValue === 'become-minter') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Become a Minter'
+ this.mwcIcon = 'thumb_up'
+ } else if (theValue === 'sponsorship-list') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Sponsorship List'
+ this.mwcIcon = 'format_list_numbered'
+ } else if (theValue === 'wallet') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Wallets'
+ this.mwcIcon = 'account_balance_wallet'
+ } else if (theValue === 'trade-portal') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Trade Portal'
+ this.mwcIcon = 'format_list_bulleted'
+ } else if (theValue === 'trade-bot-portal') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Auto Buy'
+ this.mwcIcon = 'shop'
+ } else if (theValue === 'reward-share') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Reward Share'
+ this.mwcIcon = 'ios_share'
+ } else if (theValue === 'q-chat') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Q-Chat'
+ this.mwcIcon = 'forum'
+ } else if (theValue === 'name-registration') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Name Registration'
+ this.mwcIcon = 'manage_accounts'
+ } else if (theValue === 'names-market') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Names Market'
+ this.mwcIcon = 'store'
+ } else if (theValue === 'websites') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Websites'
+ this.mwcIcon = 'desktop_mac'
+ } else if (theValue === 'qapps') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Q-Apps'
+ this.mwcIcon = 'apps'
+ } else if (theValue === 'group-management') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Group Management'
+ this.mwcIcon = 'group'
+ } else if (theValue === 'data-management') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Data Management'
+ this.mwcIcon = 'storage'
+ } else if (theValue === 'puzzles') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Puzzles'
+ this.mwcIcon = 'extension'
+ } else if (theValue === 'node-management') {
+ this.mwcIcon = ''
+ this.initialName = ''
+ this.textFieldDisabled = true
+ this.initialName = 'Node Management'
+ this.mwcIcon = 'cloud'
+ }
+ }
+
+ filterSelectMenu() {
+ const addressInfoSelect = this.addressInfo
+ const isMinterSelect = addressInfoSelect?.error !== 124 && +addressInfoSelect?.level > 0
+ const isSponsorSelect = +addressInfoSelect?.level >= 5
+
+ if (!isMinterSelect) {
+ return html`
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `
+ } else if (isMinterSelect && isSponsorSelect) {
+ return html`
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `
+ } else {
+ return html`
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `
+ }
+ }
+
+ openAddNewPlugin() {
+ this.shadowRoot.getElementById("pluginTypeInput").value = 'reject'
+ this.shadowRoot.getElementById("pluginNameInput").value = ''
+ this.initialName = ''
+ this.textFieldDisabled = false
+ this.shadowRoot.querySelector('#addNewPlugin').show()
+ }
+
+ async addToMyMenuPlugins() {
+ this.newId = ''
+ const newUid = new ShortUniqueId({ length: 10 })
+ this.newId = 'plugin-' + newUid()
+
+ this.pluginType = this.shadowRoot.getElementById("pluginTypeInput").value
+
+ if (this.pluginType === "reject") {
+ let myplugerr = get("tabmenu.tm25")
+ parentEpml.request('showSnackBar', `${myplugerr}`)
+ return false
+ } else if (this.pluginType === "0") {
+ this.mwcIcon = ''
+ this.pluginName = this.shadowRoot.getElementById('pluginNameInput').value
+
+ if (this.pluginName === "Q-Blog") {
+ this.mwcIcon = 'rss_feed'
+ } else if (this.pluginName === "Q-Mail") {
+ this.mwcIcon = 'mail'
+ } else {
+ this.mwcIcon = 'apps'
+ }
+
+ var oldMenuPlugs = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+
+ const newMenuPlugsItem = {
+ "url": "myapp",
+ "domain": "core",
+ "page": `qdn/browser/index.html?name=${this.pluginName}&service=APP`,
+ "title": this.pluginName,
+ "icon": "vaadin:external-browser",
+ "mwcicon": this.mwcIcon,
+ "pluginNumber": this.newId,
+ "menus": [],
+ "parent": false
+ }
+
+ const validatePluginName = async () => {
+ if (this.pluginType === "0" && this.pluginName.length == 0) {
+ let myplugstring1 = get("walletpage.wchange50")
+ parentEpml.request('showSnackBar', `${myplugstring1}`)
+ return false
+ }
+
+ let myPluginName = false
+ this.myPluginNameRes = []
+
+ await parentEpml.request('apiCall', {
+ url: `/arbitrary/resources/search?service=APP&query=${this.pluginName}&exactmatchnames=true&limit=1`
+ }).then(res => {
+ this.myPluginNameRes = res
+ })
+
+ if (this.myPluginNameRes === undefined || this.myPluginNameRes.length == 0) {
+ myPluginName = false
+ } else {
+ myPluginName = true
+ }
+ return myPluginName
+ }
+
+ let myNameRes = await validatePluginName()
+
+ if (myNameRes !== false) {
+ oldMenuPlugs.push(newMenuPlugsItem)
+
+ localStorage.setItem("myMenuPlugs", JSON.stringify(oldMenuPlugs))
+
+ let myplugstring2 = get("walletpage.wchange52")
+ parentEpml.request('showSnackBar', `${myplugstring2}`)
+
+ this.closeAddNewPlugin()
+
+ this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+ this.firstUpdated()
+ } else {
+ let myplugstring3 = get("websitespage.schange17")
+ parentEpml.request('showSnackBar', `${myplugstring3}`)
+ return false
+ }
+ } else if (this.pluginType === "1") {
+ this.mwcIcon = ''
+ this.pluginName = this.shadowRoot.getElementById('pluginNameInput').value
+
+ this.mwcIcon = 'web'
+
+ var oldMenuPlugs = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+
+ const newMenuPlugsItem = {
+ "url": "myapp",
+ "domain": "core",
+ "page": `qdn/browser/index.html?name=${this.pluginName}&service=WEBSITE`,
+ "title": this.pluginName,
+ "icon": "vaadin:external-browser",
+ "mwcicon": this.mwcIcon,
+ "pluginNumber": this.newId,
+ "menus": [],
+ "parent": false
+ }
+
+ const validatePluginName = async () => {
+ if (this.pluginType === "1" && this.pluginName.length == 0) {
+ let myplugstring1 = get("walletpage.wchange50")
+ parentEpml.request('showSnackBar', `${myplugstring1}`)
+ return false
+ }
+
+ let myPluginName = false
+ this.myPluginNameRes = []
+
+ await parentEpml.request('apiCall', {
+ url: `/arbitrary/resources/search?service=WEBSITE&query=${this.pluginName}&exactmatchnames=true&limit=1`
+ }).then(res => {
+ this.myPluginNameRes = res
+ })
+
+ if (this.myPluginNameRes === undefined || this.myPluginNameRes.length == 0 ) {
+ myPluginName = false
+ } else {
+ myPluginName = true
+ }
+ return myPluginName
+ }
+
+ let myNameRes = await validatePluginName()
+
+ if (myNameRes !== false) {
+ oldMenuPlugs.push(newMenuPlugsItem)
+
+ localStorage.setItem("myMenuPlugs", JSON.stringify(oldMenuPlugs))
+
+ let myplugstring2 = get("walletpage.wchange52")
+ parentEpml.request('showSnackBar', `${myplugstring2}`)
+
+ this.closeAddNewPlugin()
+
+ this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+ this.firstUpdated()
+ } else {
+ let myplugstring3 = get("websitespage.schange17")
+ parentEpml.request('showSnackBar', `${myplugstring3}`)
+ return false
+ }
+ } else {
+ this.pluginPage = ''
+ if (this.pluginType === 'overview-page') {
+ this.pluginPage = 'overview-page/index.html'
+ } else if (this.pluginType === 'minting') {
+ this.pluginPage = 'minting/index.html'
+ } else if (this.pluginType === 'become-minter') {
+ this.pluginPage = 'become-minter/index.html'
+ } else if (this.pluginType === 'sponsorship-list') {
+ this.pluginPage = 'sponsorship-list/index.html'
+ } else if (this.pluginType === 'wallet') {
+ this.pluginPage = 'wallet/index.html'
+ } else if (this.pluginType === 'trade-portal') {
+ this.pluginPage = 'trade-portal/index.html'
+ } else if (this.pluginType === 'trade-bot-portal') {
+ this.pluginPage = 'trade-bot/index.html'
+ } else if (this.pluginType === 'reward-share') {
+ this.pluginPage = 'reward-share/index.html'
+ } else if (this.pluginType === 'q-chat') {
+ this.pluginPage = 'messaging/q-chat/index.html'
+ } else if (this.pluginType === 'name-registration') {
+ this.pluginPage = 'name-registration/index.html'
+ } else if (this.pluginType === 'names-market') {
+ this.pluginPage = 'names-market/index.html'
+ } else if (this.pluginType === 'websites') {
+ this.pluginPage = 'qdn/index.html'
+ } else if (this.pluginType === 'qapps') {
+ this.pluginPage = 'q-app/index.html'
+ } else if (this.pluginType === 'group-management') {
+ this.pluginPage = 'group-management/index.html'
+ } else if (this.pluginType === 'data-management') {
+ this.pluginPage = 'qdn/data-management/index.html'
+ } else if (this.pluginType === 'puzzles') {
+ this.pluginPage = 'puzzles/index.html'
+ } else if (this.pluginType === 'node-management') {
+ this.pluginPage = 'node-management/index.html'
+ }
+
+ var oldMenuPlugs = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+
+ const newMenuPlugsItem = {
+ "url": this.pluginType,
+ "domain": "core",
+ "page": this.pluginPage,
+ "title": this.initialName,
+ "icon": "vaadin:external-browser",
+ "mwcicon": this.mwcIcon,
+ "pluginNumber": this.newId,
+ "menus": [],
+ "parent": false
+ }
+
+ oldMenuPlugs.push(newMenuPlugsItem)
+
+ localStorage.setItem("myMenuPlugs", JSON.stringify(oldMenuPlugs))
+
+ let myplugstring2 = get("walletpage.wchange52")
+ parentEpml.request('showSnackBar', `${myplugstring2}`)
+
+ this.closeAddNewPlugin()
+
+ this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+ this.firstUpdated()
+ }
+ }
+
+ closeAddNewPlugin() {
+ this.shadowRoot.querySelector('#addNewPlugin').close()
+ this.shadowRoot.getElementById("pluginTypeInput").value = 'reject'
+ this.shadowRoot.getElementById("pluginNameInput").value = ''
+ this.initialName = ''
+ this.textFieldDisabled = false
+ }
+
+ renderTitle(theUrl, theName) {
+ if (theUrl === 'overview-page') {
+ return html`${translate('tabmenu.tm28')}`
+ } else if (theUrl === 'minting') {
+ return html`${translate('tabmenu.tm1')}`
+ } else if (theUrl === 'become-minter') {
+ return html`${translate('tabmenu.tm2')}`
+ } else if (theUrl === 'sponsorship-list') {
+ return html`${translate('tabmenu.tm3')}`
+ } else if (theUrl === 'wallet') {
+ return html`${translate('tabmenu.tm4')}`
+ } else if (theUrl === 'trade-portal') {
+ return html`${translate('tabmenu.tm5')}`
+ } else if (theUrl === 'trade-bot-portal') {
+ return html`${translate('tabmenu.tm6')}`
+ } else if (theUrl === 'reward-share') {
+ return html`${translate('tabmenu.tm7')}`
+ } else if (theUrl === 'q-chat') {
+ return html`${translate('tabmenu.tm8')}`
+ } else if (theUrl === 'name-registration') {
+ return html`${translate('tabmenu.tm9')}`
+ } else if (theUrl === 'names-market') {
+ return html`${translate('tabmenu.tm10')}`
+ } else if (theUrl === 'websites') {
+ return html`${translate('tabmenu.tm11')}`
+ } else if (theUrl === 'qapps') {
+ return html`${translate('tabmenu.tm12')}`
+ } else if (theUrl === 'group-management') {
+ return html`${translate('tabmenu.tm13')}`
+ } else if (theUrl === 'data-management') {
+ return html`${translate('tabmenu.tm14')}`
+ } else if (theUrl === 'puzzles') {
+ return html`${translate('tabmenu.tm15')}`
+ } else if (theUrl === 'node-management') {
+ return html`${translate('tabmenu.tm16')}`
+ } else {
+ return html`${theName}`
+ }
+ }
+
+ renderRemoveIcon(appurl, appicon, appname, appid, appplugin) {
+ return html`
+ this.openRemoveApp(appname, appid, appurl)}">
+ backspace
+
+
+ `
+ }
+
+ openRemoveApp(pluginNameTD, pluginNumberTD, pluginUrlTD) {
+ this.pluginNameToDelete = ''
+ this.pluginNameToDelete = pluginNameTD
+ this.pluginNumberToDelete = ''
+ this.pluginNumberToDelete = pluginNumberTD
+ this.removeTitle = ''
+ if (pluginUrlTD === 'overview-page') {
+ this.removeTitle = html`${translate('tabmenu.tm28')}`
+ } else if (pluginUrlTD === 'minting') {
+ this.removeTitle = html`${translate('tabmenu.tm1')}`
+ } else if (pluginUrlTD === 'become-minter') {
+ this.removeTitle = html`${translate('tabmenu.tm2')}`
+ } else if (pluginUrlTD === 'sponsorship-list') {
+ this.removeTitle = html`${translate('tabmenu.tm3')}`
+ } else if (pluginUrlTD === 'wallet') {
+ this.removeTitle = html`${translate('tabmenu.tm4')}`
+ } else if (pluginUrlTD === 'trade-portal') {
+ this.removeTitle = html`${translate('tabmenu.tm5')}`
+ } else if (pluginUrlTD === 'trade-bot-portal') {
+ this.removeTitle = html`${translate('tabmenu.tm6')}`
+ } else if (pluginUrlTD === 'reward-share') {
+ this.removeTitle = html`${translate('tabmenu.tm7')}`
+ } else if (pluginUrlTD === 'q-chat') {
+ this.removeTitle = html`${translate('tabmenu.tm8')}`
+ } else if (pluginUrlTD === 'name-registration') {
+ this.removeTitle = html`${translate('tabmenu.tm9')}`
+ } else if (pluginUrlTD === 'names-market') {
+ this.removeTitle = html`${translate('tabmenu.tm10')}`
+ } else if (pluginUrlTD === 'websites') {
+ this.removeTitle = html`${translate('tabmenu.tm11')}`
+ } else if (pluginUrlTD === 'qapps') {
+ this.removeTitle = html`${translate('tabmenu.tm12')}`
+ } else if (pluginUrlTD === 'group-management') {
+ this.removeTitle = html`${translate('tabmenu.tm13')}`
+ } else if (pluginUrlTD === 'data-management') {
+ this.removeTitle = html`${translate('tabmenu.tm14')}`
+ } else if (pluginUrlTD === 'puzzles') {
+ this.removeTitle = html`${translate('tabmenu.tm15')}`
+ } else if (pluginUrlTD === 'node-management') {
+ this.removeTitle = html`${translate('tabmenu.tm16')}`
+ } else {
+ this.removeTitle = html`${pluginNameTD}`
+ }
+ this.shadowRoot.querySelector('#removePlugin').show()
+ }
+
+ removeAppFromArray() {
+ const pluginToRemove = this.pluginNumberToDelete
+ this.newMenuFilter = []
+ this.newMenuFilter = this.myMenuList.filter((item) => item.pluginNumber !== pluginToRemove)
+ const myNewObj = JSON.stringify(this.newMenuFilter)
+ localStorage.removeItem("myMenuPlugs")
+ localStorage.setItem("myMenuPlugs", myNewObj)
+ this.myMenuPlugins = JSON.parse(localStorage.getItem("myMenuPlugs") || "[]")
+ this.firstUpdated()
+ this.closeRemoveApp()
+ }
+
+ closeRemoveApp() {
+ this.shadowRoot.querySelector('#removePlugin').close()
+ this.pluginNameToDelete = ''
+ this.pluginNumberToDelete = ''
+ }
+
+ async extractComponents(url) {
+ if (!url.startsWith("qortal://")) {
+ return null
+ }
+
+ url = url.replace(/^(qortal\:\/\/)/, "")
+ if (url.includes("/")) {
+ let parts = url.split("/")
+ const service = parts[0].toUpperCase()
+ parts.shift()
+ const name = parts[0]
+ parts.shift()
+ let identifier
+
+ if (parts.length > 0) {
+ identifier = parts[0] // Do not shift yet
+ // Check if a resource exists with this service, name and identifier combination
+ const myNode = store.getState().app.nodeConfig.knownNodes[store.getState().app.nodeConfig.node]
+ const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
+ const url = `${nodeUrl}/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${myNode.apiKey}}`
+
+ const res = await fetch(url);
+ 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
+ }
+
+ async getQuery(value) {
+ let newQuery = value
+ 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}`
+ }
+
+ if (service === "APP") {
+ this.changePage({
+ "url": "qapp",
+ "domain": "core",
+ "page": `qdn/browser/index.html${query}`,
+ "title": "Q-App",
+ "icon": "vaadin:external-browser",
+ "mwcicon": "open_in_browser",
+ "menus": [],
+ "parent": false
+ })
+ } else if (service === "WEBSITE") {
+ this.changePage({
+ "url": "websites",
+ "domain": "core",
+ "page": `qdn/browser/index.html${query}`,
+ "title": "Website",
+ "icon": "vaadin:desktop",
+ "mwcicon": "desktop_mac",
+ "menus": [],
+ "parent": false
+ })
+ }
+ }
+
+ async handlePasteLink(e) {
+ try {
+ const value = this.shadowRoot.getElementById('linkInput').value
+ this.getQuery(value)
+ } catch (error) {
+ }
+ }
+
+ async _handleKeyDown(e) {
+ if (e.key === 'Enter') {
+ try {
+ const value = this.shadowRoot.getElementById('linkInput').value
+ this.getQuery(value)
+ } catch (error) {
+ }
+ }
+ }
+
+ getApiKey() {
+ const apiNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
+ let apiKey = apiNode.apiKey
+ return apiKey
+ }
+
+ isEmptyArray(arr) {
+ if (!arr) { return true }
+ return arr.length === 0
+ }
+
+ stateChanged(state) {
+ this.menuList = state.app.registeredUrls
+ this.addressInfo = state.app.accountInfo.addressInfo
+ }
+}
+
+customElements.define('nav-bar', NavBar)
From 6430900b2b05a52d83658681f4d820f1f6272eca Mon Sep 17 00:00:00 2001
From: AlphaX-Projects <77661270+AlphaX-Projects@users.noreply.github.com>
Date: Fri, 14 Jul 2023 15:16:56 +0200
Subject: [PATCH 4/5] Add dev translations
---
core/language/us.json | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/core/language/us.json b/core/language/us.json
index 0a6b6dea..20bdcf12 100644
--- a/core/language/us.json
+++ b/core/language/us.json
@@ -79,7 +79,11 @@
"tm34": "Export Tab Menu",
"tm35": "Your existing tab menu will be deleted and set to uploaded tab menu.",
"tm36": "Tab Menu Successfully Restored",
- "tm37": "Tab Menu Successfully Saved As"
+ "tm37": "Tab Menu Successfully Saved As",
+ "tm38": "DEV MODE",
+ "tm39": "Add Custom Framework",
+ "tm40": "Add And Open",
+ "tm41": "Error: Invalid data please try again !"
},
"login": {
"login": "Log In",
From fb2648b542c8c14861b59a0f96e99e134185ec92 Mon Sep 17 00:00:00 2001
From: Phillip
Date: Fri, 21 Jul 2023 22:22:21 +0300
Subject: [PATCH 5/5] change this.url on refresh for dev mode
---
plugins/plugins/core/qdn/browser/browser.src.js | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/plugins/plugins/core/qdn/browser/browser.src.js b/plugins/plugins/core/qdn/browser/browser.src.js
index 95f18177..9ae89c25 100644
--- a/plugins/plugins/core/qdn/browser/browser.src.js
+++ b/plugins/plugins/core/qdn/browser/browser.src.js
@@ -160,13 +160,13 @@ class WebBrowser extends LitElement {
if (this.dev === 'FRAMEWORK') {
displayUrl = 'qortal://app/development'
} else {
- displayUrl = 'qortal://' + this.service + '/' + this.name
- if ( this.identifier && this.identifier != 'null' && this.identifier != 'default' ) {
- displayUrl = displayUrl.concat('/' + this.identifier)
- }
- if (this.path != null && this.path != '/') {
- displayUrl = displayUrl.concat(this.path)
- }
+ displayUrl = 'qortal://' + this.service + '/' + this.name
+ if (this.identifier && this.identifier != 'null' && this.identifier != 'default') {
+ displayUrl = displayUrl.concat('/' + this.identifier)
+ }
+ if (this.path != null && this.path != '/') {
+ displayUrl = displayUrl.concat(this.path)
+ }
}
this.displayUrl = displayUrl
@@ -2756,7 +2756,7 @@ class WebBrowser extends LitElement {
const myNode = window.parent.reduxStore.getState().app.nodeConfig.knownNodes[window.parent.reduxStore.getState().app.nodeConfig.node]
const nodeUrl = myNode.protocol + '://' + myNode.domain + ':' + myNode.port
if (this.dev === 'FRAMEWORK') {
- this.url = `${this.link}`
+ this.url = `${this.link}?time=${new Date().getMilliseconds()}`
} else {
this.url = `${nodeUrl}/render/${this.service}/${this.name}${this.path != null ? this.path : ''
}?theme=${this.theme}&identifier=${this.identifier != null ? this.identifier : ''