✨ Enhance app with multi-CCN support and improved UX
Features: ✅ Add support for multiple CCNs 🔍 Implement sidebar hiding functionality 🎨 Revamp navigation system for better flow 🖌️ Replace icons with custom-designed assets and improved naming 🚀 Streamline initial setup process 📝 Refine terminology (e.g., "forum thread" → "topic") 🛠️ Enhance forum usability and interaction
This commit is contained in:
parent
bf3c950da0
commit
9893945f55
34 changed files with 792 additions and 308 deletions
|
@ -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`
|
||||
<arx-arbor-forum-category id=${category.id} title=${category.name}>
|
||||
${when(category.topics.length === 0, () => html` <div style="padding: 1rem 1.5rem">No topics...</div> `)}
|
||||
${when(category.threads.length === 0, () => html` <div style="padding: 1rem 1.5rem">No threads...</div> `)}
|
||||
${map(
|
||||
category.topics,
|
||||
(topic) => html`
|
||||
<arx-arbor-forum-topic
|
||||
id=${topic.id}
|
||||
title=${topic.title}
|
||||
description=${topic.description}
|
||||
lastPostBy=${topic.author}
|
||||
lastPostTime=${topic.created_at}
|
||||
category.threads,
|
||||
(thread) => html`
|
||||
<arx-arbor-forum-thread
|
||||
id=${thread.id}
|
||||
title=${thread.title}
|
||||
description=${thread.description}
|
||||
lastPostBy=${thread.author}
|
||||
lastPostTime=${thread.created_at}
|
||||
>
|
||||
</arx-arbor-forum-topic>
|
||||
</arx-arbor-forum-thread>
|
||||
`,
|
||||
)}
|
||||
</arx-arbor-forum-category>
|
||||
|
|
|
@ -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`
|
||||
<div class="container">
|
||||
<div class="topic-id">Topic ID: ${this.topicId}</div>
|
||||
<div class="thread-id">Thread ID: ${this.threadId}</div>
|
||||
|
||||
<arx-textarea
|
||||
placeholder="Post. You can use Markdown here."
|
||||
|
|
|
@ -8,16 +8,16 @@ import '@components/General/Button';
|
|||
import '@components/General/Input';
|
||||
import '@components/General/Textarea';
|
||||
|
||||
@customElement('arx-arbor-topic-creator')
|
||||
export class ArborTopicCreator extends LitElement {
|
||||
@customElement('arx-arbor-thread-creator')
|
||||
export class ArborThreadCreator extends LitElement {
|
||||
@property({ type: String })
|
||||
categoryId = '';
|
||||
|
||||
@state()
|
||||
private newTopic = '';
|
||||
private newThread = '';
|
||||
|
||||
@state()
|
||||
private topicContent = '';
|
||||
private threadContent = '';
|
||||
|
||||
@state()
|
||||
private isCreating = false;
|
||||
|
@ -39,16 +39,16 @@ export class ArborTopicCreator extends LitElement {
|
|||
}
|
||||
`;
|
||||
|
||||
private async doCreateTopic() {
|
||||
private async doCreateThread() {
|
||||
if (this.isCreating) return;
|
||||
|
||||
if (this.newTopic.length < 3) {
|
||||
alert('Topic title must be at least 3 characters long');
|
||||
if (this.newThread.length < 3) {
|
||||
alert('Thread title must be at least 3 characters long');
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.topicContent.length < 10) {
|
||||
alert('Topic content must be at least 10 characters long');
|
||||
if (this.threadContent.length < 10) {
|
||||
alert('Thread content must be at least 10 characters long');
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -59,40 +59,27 @@ export class ArborTopicCreator extends LitElement {
|
|||
const event = new NDKEvent(ndk);
|
||||
event.kind = 892;
|
||||
event.tags = [
|
||||
['name', this.newTopic],
|
||||
['name', this.newThread],
|
||||
['d', `60891:${this.categoryId}`],
|
||||
];
|
||||
event.content = this.topicContent;
|
||||
event.content = this.threadContent;
|
||||
await event.sign();
|
||||
await event.publish();
|
||||
|
||||
this.dispatchEvent(
|
||||
new CustomEvent('topic-created', {
|
||||
bubbles: true,
|
||||
composed: true,
|
||||
detail: {
|
||||
topicId: event.id,
|
||||
categoryId: this.categoryId,
|
||||
},
|
||||
}),
|
||||
);
|
||||
|
||||
this.newTopic = '';
|
||||
this.topicContent = '';
|
||||
location.hash = `/arbor/${event.id}`;
|
||||
} catch (error) {
|
||||
console.error('Failed to create topic:', error);
|
||||
alert('Failed to create topic');
|
||||
console.error('Failed to create thread:', error);
|
||||
alert('Failed to create thread');
|
||||
} finally {
|
||||
this.isCreating = false;
|
||||
}
|
||||
}
|
||||
|
||||
private handleTopicInput(e: ArxInputChangeEvent) {
|
||||
this.newTopic = e.detail.value;
|
||||
private handleThreadInput(e: ArxInputChangeEvent) {
|
||||
this.newThread = e.detail.value;
|
||||
}
|
||||
|
||||
private handleContentInput(e: ArxInputChangeEvent) {
|
||||
this.topicContent = e.detail.value;
|
||||
this.threadContent = e.detail.value;
|
||||
}
|
||||
|
||||
override render() {
|
||||
|
@ -101,15 +88,15 @@ export class ArborTopicCreator extends LitElement {
|
|||
|
||||
<arx-input
|
||||
type="text"
|
||||
placeholder="New Topic"
|
||||
.value=${this.newTopic}
|
||||
@change=${this.handleTopicInput}
|
||||
placeholder="New Thread"
|
||||
.value=${this.newThread}
|
||||
@change=${this.handleThreadInput}
|
||||
?disabled=${this.isCreating}
|
||||
></arx-input>
|
||||
|
||||
<arx-textarea
|
||||
placeholder="Topic. You can use Markdown here."
|
||||
.value=${this.topicContent}
|
||||
placeholder="Thread. You can use Markdown here."
|
||||
.value=${this.threadContent}
|
||||
@change=${this.handleContentInput}
|
||||
?disabled=${this.isCreating}
|
||||
></arx-textarea>
|
||||
|
@ -123,7 +110,7 @@ export class ArborTopicCreator extends LitElement {
|
|||
|
||||
<arx-button
|
||||
label=${this.isCreating ? 'Creating...' : 'Create'}
|
||||
@click=${this.doCreateTopic}
|
||||
@click=${this.doCreateThread}
|
||||
?disabled=${this.isCreating}
|
||||
>
|
||||
</arx-button>
|
|
@ -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`
|
||||
<arx-breadcrumbs .items=${breadcrumbItems}></arx-breadcrumbs>
|
||||
|
||||
<div class="topic-container">
|
||||
<div class="thread-container">
|
||||
<div class="header">
|
||||
<span>${this.title || 'Loading topic...'}</span>
|
||||
<span>${this.title || 'Loading thread...'}</span>
|
||||
</div>
|
||||
|
||||
<div class="posts-container">
|
||||
|
@ -218,7 +218,7 @@ export class ArborTopicView extends LitElement {
|
|||
(post) => html`
|
||||
<arx-forum-post
|
||||
id=${post.id}
|
||||
.topicId=${this.topicId}
|
||||
.threadId=${this.threadId}
|
||||
.npub=${post.npub}
|
||||
.date=${post.date}
|
||||
.content=${post.content}
|
||||
|
@ -229,7 +229,7 @@ export class ArborTopicView extends LitElement {
|
|||
</div>
|
||||
|
||||
<div class="actions">
|
||||
<arx-button label="New Post" href="/arbor/new-post/${this.topicId}">
|
||||
<arx-button label="New Post" href="/arbor/new-post/${this.threadId}">
|
||||
New Post
|
||||
</arx-button>
|
||||
</div>
|
|
@ -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',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
|
|
|
@ -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`
|
||||
<button class="sidebar-toggle" @click=${this.toggleSidebar} title=${when(
|
||||
this.sidebarVisible,
|
||||
() => 'Hide Sidebar',
|
||||
() => 'Show Sidebar',
|
||||
)}>
|
||||
${when(
|
||||
this.sidebarVisible,
|
||||
() => html`<iconify-icon icon="mdi:chevron-left"></iconify-icon>`,
|
||||
() => html`<iconify-icon icon="mdi:chevron-right"></iconify-icon>`,
|
||||
)}
|
||||
</button>
|
||||
<arx-sidebar
|
||||
class=${classMap({ hidden: !this.sidebarVisible })}
|
||||
.currentPath=${this.currentPath}
|
||||
.userNpub=${this.userNpub}
|
||||
.userProfile=${this.userProfile}
|
||||
|
@ -422,8 +516,8 @@ export default class EveRouter extends LitElement {
|
|||
@go-forward=${this.goForward}
|
||||
title="Eve"
|
||||
></arx-header>
|
||||
<div class="window ${this.currentRoute.pattern === 'home' ? 'hide-overflow' : ''}">
|
||||
<div ${ref(this.windowContentRef)} class="window-content ${this.isTransitioning ? 'transitioning' : ''}">
|
||||
<div class=${classMap({ window: true, 'hide-overflow': this.currentRoute.pattern === 'home' })}>
|
||||
<div ${ref(this.windowContentRef)} class=${classMap({ 'window-content': true, transitioning: this.isTransitioning })}>
|
||||
${when(
|
||||
this.isTransitioning,
|
||||
() => html`<arx-loading-view></arx-loading-view>`,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue