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