diff --git a/src/components/Setup/CCNList.ts b/src/components/Setup/CCNList.ts
new file mode 100644
index 0000000..de16349
--- /dev/null
+++ b/src/components/Setup/CCNList.ts
@@ -0,0 +1,56 @@
+import '@components/General/Button';
+import '@components/General/Select';
+import { LitElement, css, html } from 'lit';
+import { customElement, property, state } from 'lit/decorators.js';
+
+@customElement('arx-setup-ccn-list')
+export class CCNList extends LitElement {
+ @property({ type: Array }) ccns: { name: string; pubkey: string }[] = [];
+
+ static override styles = css`
+ :host {
+ display: block;
+ }
+ `;
+
+ @state() private selectedCCN: string | undefined;
+
+ private _valueMapper = (ccn: { name: string; pubkey: string }) => ccn.pubkey;
+ private _textMapper = (ccn: { name: string; pubkey: string }) => ccn.name;
+
+ private _handleCCNSelected(pubkey: string | undefined) {
+ this.selectedCCN = pubkey;
+ this.dispatchEvent(new CustomEvent('ccn-selected', { detail: { ccn: this.selectedCCN } }));
+ }
+
+ override render() {
+ if (this.ccns.length === 0)
+ return html`
+
No CCNs found in the relay. You will be asked to setup a CCN in the next step.
+ `;
+
+ if (this.ccns.length === 1)
+ return html`
+
+
CCN Found
+
We found one CCN in your relay, which likely means you've used Eve before or there was an update introducing new setup steps. You can use this CCN to proceed with the setup, or create a new one.
+
CCN Name: ${this.ccns[0].name}
+
this._handleCCNSelected(this.ccns[0].pubkey)}" label="Use This CCN">
+
this._handleCCNSelected(undefined)}" label="Create New CCN">
+
+ `;
+ return html`
+
+
CCNs
+
We found the following CCNs in your relay, which likely means you've used Eve before or there was an update introducing new setup steps. You can quickly choose one of these CCNs to proceed with the setup, or create a new one.
+
) => this._handleCCNSelected(e.detail.value)}"
+ >
+
this._handleCCNSelected(undefined)}" label="Create New CCN">
+
+ `;
+ }
+}
diff --git a/src/components/Sidebar.ts b/src/components/Sidebar.ts
index 253f7a1..e481bfd 100644
--- a/src/components/Sidebar.ts
+++ b/src/components/Sidebar.ts
@@ -20,31 +20,31 @@ export default class Sidebar extends LitElement {
apps = [
{
id: 1,
- href: 'beacon',
- name: 'Beacon',
+ href: 'calendar',
+ name: 'Calendar',
color: '#FF8C00',
- icon: 'fa-solid:sun',
+ icon: 'arx:calendar',
},
{
id: 2,
href: 'arbor',
name: 'Arbor',
color: '#FF4040',
- icon: 'fa-solid:tree',
+ icon: 'arx:arbor',
},
{
id: 3,
href: 'wallet',
name: 'Wallet',
color: '#1E90FF',
- icon: 'fa-solid:spa',
+ icon: 'arx:wallet',
},
{
id: 4,
href: 'settings',
name: 'Settings',
color: '#7B68EE',
- icon: 'fa-solid:tools',
+ icon: 'arx:settings',
},
];
diff --git a/src/electron/main.ts b/src/electron/main.ts
index 14a0d67..99d25fb 100644
--- a/src/electron/main.ts
+++ b/src/electron/main.ts
@@ -1,19 +1,10 @@
+import path from 'node:path';
import { is, optimizer } from '@electron-toolkit/utils';
import { BrowserWindow, app, ipcMain, shell } from 'electron';
-import fs from 'node:fs';
-import path from 'node:path';
import { RelayManager } from './relayManager';
const relay = new RelayManager();
-ipcMain.handle('relay:writeSeed', async (_, ...args: string[]) => {
- if (!args[0]) throw new Error('No seed provided');
- const seed = args[0] as string;
- const configPath = relay.getRelayConfigPath();
- fs.mkdirSync(configPath, { recursive: true });
- fs.writeFileSync(path.join(configPath, 'ccn.seed'), seed);
-});
-
ipcMain.handle('relay:start', (_, ...args: string[]) => {
if (!args[0]) throw new Error('No encryption key provided');
const encryptionKey = args[0];
diff --git a/src/electron/preload.ts b/src/electron/preload.ts
index 7382cfe..260d402 100644
--- a/src/electron/preload.ts
+++ b/src/electron/preload.ts
@@ -5,7 +5,6 @@ if (process.contextIsolated) {
try {
contextBridge.exposeInMainWorld('electron', electronAPI);
contextBridge.exposeInMainWorld('relay', {
- writeSeed: (seed: string) => ipcRenderer.invoke('relay:writeSeed', seed),
start: (encryptionKey: string) => ipcRenderer.invoke('relay:start', encryptionKey),
stop: () => ipcRenderer.invoke('relay:stop'),
getStatus: () => ipcRenderer.invoke('relay:status'),
diff --git a/src/electron/relayManager.ts b/src/electron/relayManager.ts
index 5be64b9..e2253b7 100644
--- a/src/electron/relayManager.ts
+++ b/src/electron/relayManager.ts
@@ -1,8 +1,8 @@
-import { is } from '@electron-toolkit/utils';
-import { app } from 'electron';
import { type ChildProcess, spawn } from 'node:child_process';
import { existsSync, rmdirSync } from 'node:fs';
import { join } from 'node:path';
+import { is } from '@electron-toolkit/utils';
+import { app } from 'electron';
type PackageEnvironment = 'flatpak' | 'appimage' | 'system' | 'mac' | 'dev';
@@ -144,20 +144,6 @@ export class RelayManager {
this.process = spawn('nc', ['localhost', '6942']);
this.devRunning = true;
- if (this.process.stdout) {
- this.process.stdout.on('data', (data: Buffer) => {
- const logLine = data.toString().trim();
- this.addLog(`[DEV] ${logLine}`);
- });
- }
-
- if (this.process.stderr) {
- this.process.stderr.on('data', (data: Buffer) => {
- const logLine = data.toString().trim();
- this.addLog(`[DEV] ERROR: ${logLine}`);
- });
- }
-
this.process.on('error', (err: Error) => {
this.addLog(`[DEV] Failed to start netcat: ${err.message}`);
this.process = null;
@@ -210,9 +196,7 @@ export class RelayManager {
this.process.on('exit', this.handleProcessExit.bind(this));
- if (this.process.pid) {
- this.restartAttempts = 0;
- }
+ if (this.process.pid) this.restartAttempts = 0;
} catch (error) {
console.error(`Error starting Relay: ${error instanceof Error ? error.message : 'Unknown error'}`);
this.restartProcess();
diff --git a/src/main.ts b/src/main.ts
index af68c9c..f81013a 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -1,3 +1,4 @@
+import '@/arx-icons';
import '@components/Breadcrumbs';
import '@components/ErrorView';
import '@components/Header';
@@ -8,6 +9,8 @@ import '@routes/router';
import type EveRouter from '@routes/router';
import './style.css';
+let availableCCNs: { name: string; pubkey: string }[] = [];
+
function checkRelayUp() {
return new Promise((resolve, reject) => {
const timeoutId = setTimeout(() => {
@@ -19,7 +22,66 @@ function checkRelayUp() {
ws.onopen = () => {
clearTimeout(timeoutId);
- ws.close();
+ ws.send(JSON.stringify(['CCN', 'LIST']));
+ };
+
+ ws.onmessage = async (message) => {
+ const data = JSON.parse(message.data);
+ console.log(data);
+ if (data[0] !== 'OK' || data[1] !== 'CCN LIST' || data[2] !== true) return;
+ availableCCNs = JSON.parse(data[3]);
+ if (availableCCNs.length === 0) throw new Error('No CCNs found');
+ if (availableCCNs.length === 1) {
+ ws.send(
+ JSON.stringify([
+ 'CCN',
+ 'ACTIVATE',
+ {
+ pubkey: availableCCNs[0].pubkey,
+ },
+ ]),
+ );
+ return resolve(true);
+ }
+ if (localStorage.getItem('selectedCCN')) {
+ const selected = JSON.parse(localStorage.getItem('selectedCCN')!) as { date: number; pubkey: string };
+ if (Date.now() - selected.date < 1000 * 60 * 60 * 24) {
+ ws.send(JSON.stringify(['CCN', 'ACTIVATE', { pubkey: selected.pubkey }]));
+ return resolve(true);
+ }
+ }
+ await new Promise((resolve) => {
+ let selectedCCN: string | null = availableCCNs[0].pubkey;
+ const selectBox = document.createElement('arx-select');
+ selectBox.options = availableCCNs.map((ccn) => ({ label: ccn.name, value: ccn.pubkey }));
+ selectBox.addEventListener('change', (e) => {
+ selectedCCN = e.target.value;
+ });
+ const okButton = document.createElement('arx-button');
+ okButton.label = 'OK';
+ okButton.addEventListener('click', () => {
+ if (selectedCCN) {
+ ws.send(
+ JSON.stringify([
+ 'CCN',
+ 'ACTIVATE',
+ {
+ pubkey: selectedCCN,
+ },
+ ]),
+ );
+ localStorage.setItem('selectedCCN', JSON.stringify({ date: Date.now(), pubkey: selectedCCN }));
+ resolve(true);
+ document.body.removeChild(dialog);
+ }
+ });
+ const dialog = document.createElement('arx-dialog');
+ dialog.title = 'Select CCN';
+ dialog.open = true;
+ dialog.appendChild(selectBox);
+ dialog.appendChild(okButton);
+ document.body.appendChild(dialog);
+ });
resolve(true);
};
diff --git a/src/relayManager.d.ts b/src/relayManager.d.ts
index d9937df..4cda5e4 100644
--- a/src/relayManager.d.ts
+++ b/src/relayManager.d.ts
@@ -5,7 +5,6 @@ interface RelayStatus {
}
interface RelayBridge {
- writeSeed: (seed: string) => Promise
;
start: (encryptionKey: string) => Promise;
stop: () => Promise;
getStatus: () => Promise;
diff --git a/src/routes/Arbor/Home.ts b/src/routes/Arbor/Home.ts
index 797f93f..6fc93ca 100644
--- a/src/routes/Arbor/Home.ts
+++ b/src/routes/Arbor/Home.ts
@@ -5,14 +5,14 @@ import { customElement, state } from 'lit/decorators.js';
import { map } from 'lit/directives/map.js';
import { when } from 'lit/directives/when.js';
-import '@components/Breadcrumbs';
-import '@components/Arbor/ForumTopic';
import '@components/Arbor/ForumCategory';
+import '@components/Arbor/ForumThread';
+import '@components/Breadcrumbs';
import '@components/General/Prompt';
import type { EvePrompt } from '@components/General/Prompt';
-interface ForumTopic {
+interface ForumThread {
id: string;
title: string;
author: string;
@@ -23,7 +23,7 @@ interface ForumTopic {
interface ForumCategory {
id: string;
name: string;
- topics: ForumTopic[];
+ threads: ForumThread[];
}
@customElement('arx-arbor-home')
@@ -33,7 +33,7 @@ export class ArborForum extends LitElement {
private isSaving = false;
- private topicsQuery: NDKSubscription | undefined;
+ private threadsQuery: NDKSubscription | undefined;
@state()
private forum: NDKEvent | null = null;
@@ -42,6 +42,10 @@ export class ArborForum extends LitElement {
:host {
display: block;
}
+
+ arx-button {
+ margin-bottom: calc(var(--spacing-sm) / 2);
+ }
`;
override async connectedCallback() {
@@ -92,11 +96,11 @@ export class ArborForum extends LitElement {
{
id: dtag,
name: newCategory,
- topics: [],
+ threads: [],
},
];
- this.loadTopics();
+ this.loadThreads();
} catch (error) {
console.error('Failed to create category:', error);
alert('Failed to create category');
@@ -128,17 +132,17 @@ export class ArborForum extends LitElement {
{
id: categoryId,
name: tag[2],
- topics: [],
+ threads: [],
},
];
}
}
- this.loadTopics();
+ this.loadThreads();
}
- private async loadTopics() {
- if (this.topicsQuery) this.topicsQuery.stop();
- this.topicsQuery = ndk
+ private async loadThreads() {
+ if (this.threadsQuery) this.threadsQuery.stop();
+ this.threadsQuery = ndk
.subscribe({
kinds: [892 as NDKKind],
'#d': this.categories.map((category) => `60891:${category.id}`),
@@ -148,9 +152,9 @@ export class ArborForum extends LitElement {
(category) => category.id === event.tags.find((tag) => tag[0] === 'd')?.[1].split(':')[1],
);
if (categoryId === -1) return;
- if (this.categories[categoryId].topics.find((topic) => topic.id === event.id)) return;
- this.categories[categoryId].topics = [
- ...this.categories[categoryId].topics,
+ if (this.categories[categoryId].threads.find((thread) => thread.id === event.id)) return;
+ this.categories[categoryId].threads = [
+ ...this.categories[categoryId].threads,
{
id: event.id,
title: event.tags.find((tag) => tag[0] === 'name')?.[1] || '',
@@ -187,18 +191,18 @@ export class ArborForum extends LitElement {
this.categories,
(category) => html`
- ${when(category.topics.length === 0, () => html` No topics...
`)}
+ ${when(category.threads.length === 0, () => html` No threads...
`)}
${map(
- category.topics,
- (topic) => html`
- html`
+
-
+
`,
)}
diff --git a/src/routes/Arbor/NewPost.ts b/src/routes/Arbor/NewPost.ts
index ab2a6c3..e4c450a 100644
--- a/src/routes/Arbor/NewPost.ts
+++ b/src/routes/Arbor/NewPost.ts
@@ -9,13 +9,13 @@ import '@components/General/Textarea';
@customElement('arx-arbor-post-creator')
export class ArborPostCreator extends LitElement {
@property({ type: String })
- topicId = '';
+ threadId = '';
@state()
private postContent = '';
@state()
- private topic: NDKEvent | null = null;
+ private thread: NDKEvent | null = null;
@state()
private isCreating = false;
@@ -34,7 +34,7 @@ export class ArborPostCreator extends LitElement {
gap: 1rem;
}
- .topic-id {
+ .thread-id {
color: #666;
font-family: monospace;
}
@@ -58,24 +58,24 @@ export class ArborPostCreator extends LitElement {
override connectedCallback() {
super.connectedCallback();
- this.loadTopic();
+ this.loadThread();
}
- private async loadTopic() {
+ private async loadThread() {
try {
await getSigner();
- this.topic = await ndk.fetchEvent(this.topicId);
- if (!this.topic) {
- throw new Error('Could not load topic');
+ this.thread = await ndk.fetchEvent(this.threadId);
+ if (!this.thread) {
+ throw new Error('Could not load thread');
}
} catch (error) {
- console.error('Failed to load topic:', error);
+ console.error('Failed to load thread:', error);
}
}
private async doCreatePost() {
if (this.isCreating) return;
- if (!this.topic) return;
+ if (!this.thread) return;
if (this.postContent.length < 10) {
this.error = 'Post content must be at least 10 characters long';
@@ -88,9 +88,9 @@ export class ArborPostCreator extends LitElement {
const event = new NDKEvent(ndk);
event.kind = 893;
event.tags = [
- ['A', this.topic.tags.find((tag) => tag[0] === 'd')?.[1] || ''],
- ['E', this.topicId],
- ['p', this.topic.pubkey],
+ ['A', this.thread.tags.find((tag) => tag[0] === 'd')?.[1] || ''],
+ ['E', this.threadId],
+ ['p', this.thread.pubkey],
];
event.content = this.postContent;
@@ -117,7 +117,7 @@ export class ArborPostCreator extends LitElement {
override render() {
return html`
-
Topic ID: ${this.topicId}
+
Thread ID: ${this.threadId}
@@ -123,7 +110,7 @@ export class ArborTopicCreator extends LitElement {
diff --git a/src/routes/Arbor/TopicView.ts b/src/routes/Arbor/ThreadView.ts
similarity index 90%
rename from src/routes/Arbor/TopicView.ts
rename to src/routes/Arbor/ThreadView.ts
index f522906..baef231 100644
--- a/src/routes/Arbor/TopicView.ts
+++ b/src/routes/Arbor/ThreadView.ts
@@ -3,8 +3,8 @@ import type { NDKKind, NDKSubscription } from '@nostr-dev-kit/ndk';
import { LitElement, css, html } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
-import '@components/Breadcrumbs';
import '@components/Arbor/ForumPost';
+import '@components/Breadcrumbs';
import '@components/General/Button';
import { map } from 'lit/directives/map.js';
@@ -17,10 +17,10 @@ interface ForumPost {
content: string;
}
-@customElement('arx-arbor-topic-view')
-export class ArborTopicView extends LitElement {
+@customElement('arx-arbor-thread-view')
+export class ArborThreadView extends LitElement {
@property({ type: String })
- topicId = '';
+ threadId = '';
@state()
override title = '';
@@ -36,7 +36,7 @@ export class ArborTopicView extends LitElement {
margin: 0 auto;
}
- .topic-container {
+ .thread-container {
background: var(--color-base-100);
border-radius: var(--radius-box);
border: var(--border) solid var(--color-base-300);
@@ -144,7 +144,7 @@ export class ArborTopicView extends LitElement {
override async connectedCallback() {
super.connectedCallback();
- await this.loadTopic();
+ await this.loadThread();
}
override disconnectedCallback() {
@@ -154,13 +154,13 @@ export class ArborTopicView extends LitElement {
}
}
- private async loadTopic() {
+ private async loadThread() {
try {
await getSigner();
- const event = await ndk.fetchEvent(this.topicId);
+ const event = await ndk.fetchEvent(this.threadId);
if (!event) {
- throw new Error('Could not load topic');
+ throw new Error('Could not load thread');
}
this.title = event.tags.find((tag) => tag[0] === 'name')?.[1] || '';
@@ -178,7 +178,7 @@ export class ArborTopicView extends LitElement {
this.subscription = ndk
.subscribe({
kinds: [893 as NDKKind],
- '#E': [this.topicId],
+ '#E': [this.threadId],
})
.on('event', (event) => {
this.posts = [
@@ -192,8 +192,8 @@ export class ArborTopicView extends LitElement {
];
});
} catch (error) {
- console.error('Failed to load topic:', error);
- alert('Could not load topic');
+ console.error('Failed to load thread:', error);
+ alert('Could not load thread');
}
}
@@ -203,9 +203,9 @@ export class ArborTopicView extends LitElement {
return html`
-
+
@@ -218,7 +218,7 @@ export class ArborTopicView extends LitElement {
(post) => html`
diff --git a/src/routes/Home.ts b/src/routes/Home.ts
index 929dddf..37b5ab4 100644
--- a/src/routes/Home.ts
+++ b/src/routes/Home.ts
@@ -26,56 +26,57 @@ export class Home extends LitElement {
href: 'letters',
name: 'Letters',
color: '#FF3E96',
- icon: 'fa-solid:leaf',
+ icon: 'arx:letters',
},
{
id: 1,
- href: 'messages',
- name: 'Murmur',
+ href: 'howl',
+ name: 'Howl',
color: '#00CD66',
- icon: 'fa-solid:seedling',
+ icon: 'arx:howl',
},
{
id: 2,
- href: 'beacon',
- name: 'Beacon',
+ href: 'calendar',
+ name: 'Calendar',
color: '#FF8C00',
- icon: 'fa-solid:sun',
+ icon: 'arx:calendar',
},
{
id: 3,
href: 'arbor',
name: 'Arbor',
color: '#FF4040',
- icon: 'fa-solid:tree',
+ icon: 'arx:arbor',
},
{
id: 5,
- href: 'grove',
- name: 'Grove',
+ href: 'market',
+ name: 'Market',
color: '#9370DB',
- icon: 'fa-solid:store-alt',
+ icon: 'arx:market',
},
{
id: 6,
href: 'wallet',
name: 'Wallet',
color: '#1E90FF',
- icon: 'fa-solid:spa',
+ icon: 'arx:wallet',
},
{
id: 7,
- href: 'oracle',
- name: 'Oracle',
- color: '#FFD700',
- icon: 'bxs:landscape',
+ href: 'pool',
+ name: 'Pool',
+ color: '#7aD700',
+ icon: 'arx:pool',
},
{
id: 8,
href: 'settings',
name: 'Settings',
color: '#7B68EE',
- icon: 'fa-solid:tools',
+ icon: 'arx:settings',
+ },
},
];
diff --git a/src/routes/router.ts b/src/routes/router.ts
index 51410f4..951866f 100644
--- a/src/routes/router.ts
+++ b/src/routes/router.ts
@@ -3,8 +3,8 @@ import '@components/Sidebar';
import '@routes/404Page';
import '@routes/Arbor/Home';
import '@routes/Arbor/NewPost';
-import '@routes/Arbor/NewTopic';
-import '@routes/Arbor/TopicView';
+import '@routes/Arbor/NewThread';
+import '@routes/Arbor/ThreadView';
import '@routes/Calendar';
import '@routes/Home';
import '@routes/Profile';
@@ -16,6 +16,7 @@ import type { NDKUserProfile } from '@nostr-dev-kit/ndk';
import { spread } from '@open-wc/lit-helpers';
import { LitElement, css } from 'lit';
import { customElement, property, state } from 'lit/decorators.js';
+import { classMap } from 'lit/directives/class-map.js';
import { keyed } from 'lit/directives/keyed.js';
import { type Ref, createRef, ref } from 'lit/directives/ref.js';
import { when } from 'lit/directives/when.js';
@@ -42,7 +43,7 @@ export default class EveRouter extends LitElement {
component: literal`arx-eve-home`,
},
{
- pattern: 'beacon',
+ pattern: 'calendar',
params: {},
component: literal`arx-calendar-route`,
},
@@ -57,20 +58,25 @@ export default class EveRouter extends LitElement {
component: literal`arx-arbor-home`,
},
{
- pattern: 'arbor/new-topic/:categoryId',
+ pattern: 'arbor/new-thread/:categoryId',
params: {},
- component: literal`arx-arbor-topic-creator`,
+ component: literal`arx-arbor-thread-creator`,
},
{
- pattern: 'arbor/topics/:topicId',
+ pattern: 'arbor/threads/:threadId',
params: {},
- component: literal`arx-arbor-topic-view`,
+ component: literal`arx-arbor-thread-view`,
},
{
- pattern: 'arbor/new-post/:topicId',
+ pattern: 'arbor/new-post/:threadId',
params: {},
component: literal`arx-arbor-post-creator`,
},
+ {
+ pattern: 'howl',
+ params: {},
+ component: literal`arx-howl-route`,
+ },
{
pattern: 'settings',
params: {},
@@ -112,6 +118,9 @@ export default class EveRouter extends LitElement {
@state()
private userNpub = '';
+ @state()
+ private sidebarVisible = true;
+
static override styles = css`
:host {
position: fixed;
@@ -121,8 +130,13 @@ export default class EveRouter extends LitElement {
height: 100%;
display: grid;
grid-template-rows: auto 1fr;
- grid-template-columns: 100px 1fr;
+ grid-template-columns: auto 1fr;
overflow: hidden;
+ transition: grid-template-columns 0.3s ease;
+ }
+
+ :host([sidebar-hidden]) {
+ grid-template-columns: 0 1fr;
}
::-webkit-scrollbar {
@@ -173,6 +187,21 @@ export default class EveRouter extends LitElement {
arx-sidebar {
grid-column: 1;
grid-row: 1 / span 2;
+ transition: width 0.3s ease, opacity 0.3s ease, padding 0.3s ease, transform 0.3s ease;
+ width: 100px;
+ opacity: 1;
+ overflow: hidden;
+ background: var(--color-base-100);
+ border-right: 1px solid var(--color-base-300);
+ }
+
+ arx-sidebar.hidden {
+ width: 0;
+ opacity: 0;
+ padding: 0;
+ pointer-events: none;
+ transform: translateX(-20px);
+ border-right: none;
}
.window-content {
@@ -187,6 +216,7 @@ export default class EveRouter extends LitElement {
transition: var(--transition);
backface-visibility: hidden;
filter: blur(0px);
+ grid-row: 1;
}
.window-content::after {
@@ -218,6 +248,44 @@ export default class EveRouter extends LitElement {
grid-column: 2;
grid-row: 1;
}
+
+ .sidebar-toggle {
+ position: fixed;
+ top: 50%;
+ left: 100px;
+ transform: translateY(-50%);
+ z-index: 1000;
+ background: color-mix(in srgb, var(--color-primary) 70%, transparent);
+ backdrop-filter: blur(5px);
+ color: var(--color-base);
+ border: none;
+ width: 20px;
+ height: 50px;
+ border-top-right-radius: var(--radius-btn);
+ border-bottom-right-radius: var(--radius-btn);
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ cursor: pointer;
+ display: flex;
+ align-items: center;
+ justify-content: center;
+ font-size: 14px;
+ transition: all var(--transition);
+ box-shadow: 2px 0 5px rgba(0,0,0,0.1);
+ }
+
+ :host([sidebar-hidden]) .sidebar-toggle {
+ left: 0;
+ border-top-left-radius: var(--radius-btn);
+ border-bottom-left-radius: var(--radius-btn);
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ }
+
+ .sidebar-toggle:hover {
+ /* background: var(--color-primary-focus); */
+ background: color-mix(in srgb, var(--color-primary) 90%, transparent);
+ }
`;
constructor() {
@@ -233,6 +301,7 @@ export default class EveRouter extends LitElement {
if (this.ccnSetup) {
this.loadUserProfile();
}
+ this.updateSidebarAttribute();
}
override disconnectedCallback(): void {
@@ -403,11 +472,36 @@ export default class EveRouter extends LitElement {
}
}
+ private toggleSidebar() {
+ this.sidebarVisible = !this.sidebarVisible;
+ this.updateSidebarAttribute();
+ }
+
+ private updateSidebarAttribute() {
+ if (this.sidebarVisible) {
+ this.removeAttribute('sidebar-hidden');
+ } else {
+ this.setAttribute('sidebar-hidden', '');
+ }
+ }
+
override render() {
if (!this.ccnSetup) return this.renderSetup();
return html`
+
-
-
+
+
${when(
this.isTransitioning,
() => html`
`,
diff --git a/tsconfig.json b/tsconfig.json
index b55f9c5..ef1724c 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -29,7 +29,8 @@
"@routes/*": ["./src/routes/*"],
"@styles/*": ["./src/styles/*"],
"@components/*": ["./src/components/*"],
- "@widgets/*": ["./src/components/Widgets/*"]
+ "@widgets/*": ["./src/components/Widgets/*"],
+ "@assets/*": ["./src/assets/*"],
}
},
"include": ["./src/**/*"]