diff --git a/core/src/components/show-plugin.js b/core/src/components/show-plugin.js index 92651ef6..055851e3 100644 --- a/core/src/components/show-plugin.js +++ b/core/src/components/show-plugin.js @@ -6,6 +6,10 @@ 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 '@vaadin/icon' +import '@vaadin/icons' + + class ShowPlugin extends connect(store)(LitElement) { static get properties() { @@ -197,13 +201,19 @@ class ShowPlugin extends connect(store)(LitElement) { ${repeat(this.tabs, (tab) => tab.id, (tab, index) => html`
- + + this.changePage(val)}> + +
`)} ` @@ -212,6 +222,9 @@ class ShowPlugin extends connect(store)(LitElement) { removeTab(index) { // Remove tab from array this.tabs = this.tabs.filter((tab, tIndex) => tIndex !== index) + if (this.tabs.length !== 0) { + this.currentTab = 0 + } } createEpmlInstance(frame, index) { @@ -267,6 +280,7 @@ class ShowPlugin extends connect(store)(LitElement) { this.requestUpdate() } + if (changedProps.has('computerUrl')) { if (this.computedUrl !== 'about:blank') { this.loading = true @@ -274,6 +288,19 @@ class ShowPlugin extends connect(store)(LitElement) { } } + changePage(page) { + + const copiedTabs = [...this.tabs] + copiedTabs[this.currentTab] = { + ...copiedTabs[this.currentTab], + myPlugObj: page, + url: page.url + } + this.tabs = copiedTabs + + + } + stateChanged(state) { const split = state.app.url.split('/') const newRegisteredUrls = state.app.registeredUrls @@ -330,4 +357,196 @@ class ShowPlugin extends connect(store)(LitElement) { } } -window.customElements.define('show-plugin', ShowPlugin) \ No newline at end of file +window.customElements.define('show-plugin', ShowPlugin) + +class NavBar extends LitElement { + static get properties() { + return { + registeredUrls: { type: Array }, + changePage: { attribute: false }, + } + } + constructor() { + super() + this.registeredUrls = [] + + } + static styles = css` + .parent { + display: flex; + flex-direction: column; + align-items: center; + padding: 20px; + } + .navbar { + display: flex; + justify-content: space-between; + align-items: center; + background-color: #f8f8f8; + padding: 10px 20px; + max-width: 750px; + width: 80%; + } + .navbar input { + font-size: 16px; + padding: 5px; + flex-grow: 1; + margin-right: 10px; + border: 1px solid #ddd; + } + .navbar button { + padding: 5px 10px; + background-color: #4CAF50; + color: white; + border: none; + cursor: pointer; + } + .navbar button:hover { + background-color: #45a049; + } + .app-list { + display: flex; + justify-content: space-around; + padding: 20px 0; + gap: 20px; + flex-wrap: wrap; + } + .app-list .app-icon { + text-align: center; + font-size: 24px; + width: 150px; + height: 150px; + background: white; + border-radius: 5px; + padding: 5px; + display: flex; + flex-direction: column; + align-items: center; + justify-content: center; + gap: 10px; + cursor: pointer; + } + .app-list .app-icon span { + display: block; + } + `; + + 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; + let responseObj = await parentEpml.request('apiCall', { + url: `${nodeUrl}/arbitrary/resource/status/${service}/${name}/${identifier}?apiKey=${myNode.apiKey}}` + }) + + if (responseObj.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}` + } + + this.changePage({ + + "url": "qapp", + "domain": "core", + "page": `qdn/browser/index.html${query}`, + "title": "Q-App", + "icon": "vaadin:desktop", + "menus": [], + "parent": false + + }) + } + + async handlePasteLink(e) { + const value = this.shadowRoot.getElementById('linkInput').value + this.getQuery(value) + } + + async _handleKeyDown(e) { + if (e.key === 'Enter') { + const value = this.shadowRoot.getElementById('linkInput').value + this.getQuery(value) + + } + } + + render() { + return html` +
+ +
+
+ + ${repeat(this.registeredUrls, (plugin) => plugin.url, (plugin, index) => html` +
{ + this.changePage(plugin) + }}> + + ${plugin.title} +
+ + `)} + + +
+
+
+ `; + } +} + +customElements.define('nav-bar', NavBar); \ No newline at end of file