Design tabs and autohide sidebar

This commit is contained in:
AlphaX-Projects 2023-06-10 17:04:05 +02:00
parent 1b5e0baf8b
commit 74214827b6
2 changed files with 123 additions and 134 deletions

View File

@ -429,7 +429,7 @@ class AppView extends connect(store)(LitElement) {
render() { render() {
return html` return html`
<app-drawer-layout responsive-width='${getComputedStyle(document.body).getPropertyValue('--layout-breakpoint-laptop')}' fullbleed> <app-drawer-layout fullbleed force-narrow>
<app-drawer swipe-open slot="drawer" id="appdrawer"> <app-drawer swipe-open slot="drawer" id="appdrawer">
<app-header-layout> <app-header-layout>
<div id="sideBar"> <div id="sideBar">
@ -466,7 +466,8 @@ class AppView extends connect(store)(LitElement) {
<app-header-layout style="height: var(--window-height);"> <app-header-layout style="height: var(--window-height);">
<app-header id='appHeader' slot="header" fixed> <app-header id='appHeader' slot="header" fixed>
<app-toolbar> <app-toolbar>
<paper-icon-button class="menu-toggle-button" drawer-toggle icon="menu"></paper-icon-button> <paper-icon-button id="mb" class="menu-toggle-button" drawer-toggle icon="menu"></paper-icon-button>
<vaadin-tooltip text="${translate("general.update")}" for="mb" position="bottom"></vaadin-tooltip>
<div main-title> <div main-title>
<span class="qora-title"> <span class="qora-title">
<img src="${this.config.coin.logo}" style="height:32px; padding-left:12px;"> <img src="${this.config.coin.logo}" style="height:32px; padding-left:12px;">

View File

@ -15,7 +15,8 @@ class ShowPlugin extends connect(store)(LitElement) {
linkParam: { type: String }, linkParam: { type: String },
registeredUrls: { type: Array }, registeredUrls: { type: Array },
currentTab: { type: Number }, currentTab: { type: Number },
tabs: { type: Array } tabs: { type: Array },
theme: { type: String, reflect: true },
} }
} }
@ -45,12 +46,10 @@ class ShowPlugin extends connect(store)(LitElement) {
border: 3px solid var(--scrollbarBG); border: 3px solid var(--scrollbarBG);
} }
.hideIframe { .hideIframe {
visibility: hidden; visibility: hidden;
position: absolute; position: absolute;
zIndex: -10; zIndex: -10;
} }
.showIframe { .showIframe {
@ -60,61 +59,78 @@ class ShowPlugin extends connect(store)(LitElement) {
} }
.tabs { .tabs {
display: flex; display: flex;
justify-content: flex-start; justify-content: flex-start;
gap: 1em; height: 35px
padding: 0.5em; max-height: 35px
background: #F6F8FA; gap: 1em;
border-bottom: 1px solid #E1E4E8; padding-top: 0.5em;
box-shadow: 0 1px 2px rgba(0,0,0,0.075); padding-left: 0.5em;
} background: var(--sidetopbar);
.tab { border-bottom: 1px solid var(--black);
padding: 0.5em 1em; }
background: #fafbfc;
border: 1px solid #E1E4E8;
border-radius: 3px;
color: #586069;
cursor: pointer;
transition: background 0.3s;
position: relative;
width: 120px;
box-sizing: border-box;
overflow: hidden;
text-overflow: ellipsis;
}
.tab:hover {
background: #F3F4F6;
}
.tab.active {
background: #FFFFFF;
color: #24292E;
border: 1px solid #E1E4E8;
box-shadow: 0 2px 5px rgba(0,0,0,0.1);
}
.close {
color: #999;
font-weight: bold;
font-size: 20px;
line-height: 20px;
position: absolute;
top: 5px;
right: 5px;
}
.close:hover { .tab {
color: red; padding: 0.5em;
} background: var(--white);
.add-tab-button { border-top-right-radius: 10px;
background: none; border-top-left-radius: 10px;
border: none; border-top: 1px solid grey;
color: #586069; border-left: 1px solid grey;
font-size: 1.5em; border-right: 1px solid grey;
cursor: pointer; color: grey;
transition: color 0.3s; cursor: pointer;
} transition: background 0.3s;
.add-tab-button:hover { position: relative;
color: #24292E; min-width: 120px;
} max-width: 200px;
text-overflow: ellipsis;
}
.tab:hover {
background: #F3F4F6;
}
.tab.active {
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);
}
.close {
color: #999;
font-weight: bold;
font-size: 20px;
line-height: 20px;
position: absolute;
top: 7px;
right: 8px;
}
.close:hover {
color: red;
}
.add-tab-button {
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);
}
` `
} }
@ -124,120 +140,100 @@ class ShowPlugin extends connect(store)(LitElement) {
this.currentTab = 0 this.currentTab = 0
this.tabs = [] this.tabs = []
this.uid = new ShortUniqueId() this.uid = new ShortUniqueId()
this.theme = localStorage.getItem('qortalTheme') ? localStorage.getItem('qortalTheme') : 'light'
} }
async getUpdateComplete() { async getUpdateComplete() {
await super.getUpdateComplete(); await super.getUpdateComplete()
return true; return true
} }
async addTab(tab) { async addTab(tab) {
this.tabs = [...this.tabs, tab] this.tabs = [...this.tabs, tab]
await this.getUpdateComplete(); await this.getUpdateComplete();
// add the new tab to the tabs array // add the new tab to the tabs array
const newIndex = this.tabs.length - 1; const newIndex = this.tabs.length - 1
// render the tab and wait for it to be added to the DOM // render the tab and wait for it to be added to the DOM
const frame = this.shadowRoot.getElementById(`showPluginFrame${newIndex}`)
const frame = this.shadowRoot.getElementById(`showPluginFrame${newIndex}`); this.createEpmlInstance(frame, newIndex)
this.createEpmlInstance(frame, newIndex);
} }
render() { render() {
const plugSrc = (myPlug) => { const plugSrc = (myPlug) => {
return myPlug === undefined ? 'about:blank' : `${window.location.origin}/plugin/${myPlug.domain}/${myPlug.page}${this.linkParam}` return myPlug === undefined ? 'about:blank' : `${window.location.origin}/plugin/${myPlug.domain}/${myPlug.page}${this.linkParam}`
} }
return html` return html`
<div class="tabs">
<div class="tabs"> ${this.tabs.map((tab, index) => html`
${this.tabs.map((tab, index) => html` <div
<div class="tab ${this.currentTab === index ? 'active' : ''}"
class="tab ${this.currentTab === index ? 'active' : ''}" @click=${() => this.currentTab = index}
@click=${() => this.currentTab = index} >
> ${tab.url}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;
${tab.url} <div class="close" @click=${() => { this.removeTab(index) }}>x</div>
<div class="close" @click=${() => { this.removeTab(index) }}>x</div> </div>
</div> `)}&nbsp;&nbsp;&nbsp;
`)} <button
<button class="add-tab-button"
class="add-tab-button" title="Add Tab"
title="Add Tab" @click=${() => this.addTab({
@click=${() => this.addTab( url: "",
{ id: this.uid()
url: "", })}
id: this.uid() >
} +
)} </button>
> </div>
</button>
</div>
${repeat(this.tabs, (tab) => tab.id, (tab, index) => html` ${repeat(this.tabs, (tab) => tab.id, (tab, index) => html`
<div class=${this.currentTab === index ? "showIframe" : "hideIframe"}> <div class=${this.currentTab === index ? "showIframe" : "hideIframe"}>
<iframe src="${plugSrc(tab.myPlugObj)}" id="showPluginFrame${index}" style="width:100%; <iframe src="${plugSrc(tab.myPlugObj)}" id="showPluginFrame${index}" style="width:100%;
height:calc(var(--window-height) - 64px); height:calc(var(--window-height) - 64px);
border:0; border:0;
padding:0; padding:0;
margin:0"></iframe> margin:0"
</div> >
`)} </iframe>
</div>
`)}
` `
} }
removeTab(index) { removeTab(index) {
// Remove tab from array // Remove tab from array
this.tabs = this.tabs.filter((tab, tIndex) => tIndex !== index) this.tabs = this.tabs.filter((tab, tIndex) => tIndex !== index)
} }
createEpmlInstance(frame, index) { createEpmlInstance(frame, index) {
const showingPluginEpml = new Epml({ const showingPluginEpml = new Epml({
type: 'WINDOW', type: 'WINDOW',
source: frame.contentWindow source: frame.contentWindow
}); })
addPluginRoutes(showingPluginEpml); addPluginRoutes(showingPluginEpml);
showingPluginEpml.imReady(); showingPluginEpml.imReady();
// store Epml instance in tab for later use // store Epml instance in tab for later use
this.tabs[index].epmlInstance = showingPluginEpml; this.tabs[index].epmlInstance = showingPluginEpml
// Register each instance with a unique identifier // Register each instance with a unique identifier
Epml.registerProxyInstance(`visible-plugin-${index}`, showingPluginEpml); Epml.registerProxyInstance(`visible-plugin-${index}`, showingPluginEpml)
} }
firstUpdated() { firstUpdated() {
this.tabs.forEach((tab, index) => { this.tabs.forEach((tab, index) => {
const frame = this.shadowRoot.getElementById(`showPluginFrame${index}`); const frame = this.shadowRoot.getElementById(`showPluginFrame${index}`)
this.createEpmlInstance(frame, index); this.createEpmlInstance(frame, index)
}); })
} }
updated(changedProps) { updated(changedProps) {
if (changedProps.has('url') || changedProps.has('registeredUrls')) { if (changedProps.has('url') || changedProps.has('registeredUrls')) {
const plugArr = [] const plugArr = []
this.registeredUrls.forEach(myPlugArr => { this.registeredUrls.forEach(myPlugArr => {
myPlugArr.menus.length === 0 ? plugArr.push(myPlugArr) : myPlugArr.menus.forEach(i => plugArr.push(myPlugArr, i)) myPlugArr.menus.length === 0 ? plugArr.push(myPlugArr) : myPlugArr.menus.forEach(i => plugArr.push(myPlugArr, i))
}) })
@ -247,14 +243,12 @@ class ShowPlugin extends connect(store)(LitElement) {
}) })
if (this.tabs.length === 0) { if (this.tabs.length === 0) {
this.addTab({ this.addTab({
url: this.url, url: this.url,
myPlugObj, myPlugObj,
id: this.uid() id: this.uid()
}) })
} else { } else {
const copiedTabs = [...this.tabs] const copiedTabs = [...this.tabs]
copiedTabs[this.currentTab] = { copiedTabs[this.currentTab] = {
...copiedTabs[this.currentTab], ...copiedTabs[this.currentTab],
@ -262,11 +256,7 @@ class ShowPlugin extends connect(store)(LitElement) {
myPlugObj myPlugObj
} }
this.tabs = copiedTabs this.tabs = copiedTabs
} }
this.requestUpdate() this.requestUpdate()
} }
@ -311,6 +301,4 @@ class ShowPlugin extends connect(store)(LitElement) {
} }
} }
window.customElements.define('show-plugin', ShowPlugin) window.customElements.define('show-plugin', ShowPlugin)