From 805cf1a88a9f33f19f3c9aa6cd5a1a853885d350 Mon Sep 17 00:00:00 2001 From: Phillip Date: Sat, 10 Jun 2023 02:53:00 +0300 Subject: [PATCH] added tab functionality --- core/src/components/show-plugin.js | 226 ++++++++++++++++++++++++++--- 1 file changed, 202 insertions(+), 24 deletions(-) diff --git a/core/src/components/show-plugin.js b/core/src/components/show-plugin.js index 06529e97..62d6624d 100644 --- a/core/src/components/show-plugin.js +++ b/core/src/components/show-plugin.js @@ -3,6 +3,8 @@ 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'; class ShowPlugin extends connect(store)(LitElement) { static get properties() { @@ -11,7 +13,9 @@ class ShowPlugin extends connect(store)(LitElement) { pluginConfig: { type: Object }, url: { type: String }, linkParam: { type: String }, - registeredUrls: { type: Array } + registeredUrls: { type: Array }, + currentTab: { type: Number }, + tabs: { type: Array } } } @@ -41,57 +45,229 @@ class ShowPlugin extends connect(store)(LitElement) { border: 3px solid var(--scrollbarBG); } - iframe#showPluginFrame { - width:100%; - height:calc(var(--window-height) - 64px); - border:0; - padding:0; - margin:0; + + .hideIframe { + visibility: hidden; + position: absolute; + zIndex: -10; + } + + .showIframe { + zIndex: 1; + position: relative; + visibility: visible; + } + + .tabs { + display: flex; + justify-content: flex-start; + gap: 1em; + padding: 0.5em; + background: #F6F8FA; + border-bottom: 1px solid #E1E4E8; + box-shadow: 0 1px 2px rgba(0,0,0,0.075); + } + .tab { + 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 { + color: red; + } + .add-tab-button { + background: none; + border: none; + color: #586069; + font-size: 1.5em; + cursor: pointer; + transition: color 0.3s; + } + .add-tab-button:hover { + color: #24292E; + } ` } constructor() { super() this.registeredUrls = [] + this.currentTab = 0 + this.tabs = [] + this.uid = new ShortUniqueId() } + async getUpdateComplete() { + await super.getUpdateComplete(); + return true; + } + + async addTab(tab) { + + 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); + + } + + + + + + render() { - const plugArr = [] + const plugSrc = (myPlug) => { return myPlug === undefined ? 'about:blank' : `${window.location.origin}/plugin/${myPlug.domain}/${myPlug.page}${this.linkParam}` } - 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 - }) return html` - + +
+ ${this.tabs.map((tab, index) => html` +
this.currentTab = index} + > + ${tab.url} +
{ this.removeTab(index) }}>x
+
+ `)} + +
+ + ${repeat(this.tabs, (tab) => tab.id, (tab, index) => html` +
+ +
+ `)} + + + ` } - firstUpdated() { + removeTab(index) { + + // Remove tab from array + this.tabs = this.tabs.filter((tab, tIndex) => tIndex !== index) + + + } + + createEpmlInstance(frame, index) { const showingPluginEpml = new Epml({ type: 'WINDOW', - source: this.shadowRoot.getElementById('showPluginFrame').contentWindow - }) + source: frame.contentWindow + }); - addPluginRoutes(showingPluginEpml) - showingPluginEpml.imReady() - this.showingPluginEpml = showingPluginEpml - Epml.registerProxyInstance('visible-plugin', showingPluginEpml) + 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); + } + + firstUpdated() { + this.tabs.forEach((tab, index) => { + const frame = this.shadowRoot.getElementById(`showPluginFrame${index}`); + this.createEpmlInstance(frame, index); + }); } updated(changedProps) { - if (changedProps.has('url')) { - //... + + 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')) { @@ -136,3 +312,5 @@ class ShowPlugin extends connect(store)(LitElement) { } window.customElements.define('show-plugin', ShowPlugin) + +