- 📝 Add comprehensive README.md, CONTRIBUTING.md, and 🔒 SECURITY.md documentation - 🔧 Integrate code formatting tool and refactor existing codebase to meet style guidelines - ⬆️ Update project dependencies to latest stable versions - 🤖 Implement pre-commit hook for automated code formatting #documentation #tooling #maintenance
122 lines
3.1 KiB
TypeScript
122 lines
3.1 KiB
TypeScript
import { getSigner, ndk } from '@/ndk';
|
|
import type { NDKSubscription } from '@nostr-dev-kit/ndk';
|
|
import formatDateTime from '@utils/formatDateTime';
|
|
import { LitElement, css, html } from 'lit';
|
|
import { customElement, state } from 'lit/decorators.js';
|
|
|
|
import '@components/Breadcrumbs';
|
|
import '@components/PhoraForumCategory';
|
|
import '@components/PhoraForumTopic';
|
|
import '@components/PhoraButton';
|
|
|
|
interface ForumTopic {
|
|
id: string;
|
|
title: string;
|
|
author: string;
|
|
description: string;
|
|
created_at: string;
|
|
}
|
|
|
|
interface ForumCategory {
|
|
id: string;
|
|
name: string;
|
|
description: string;
|
|
topics: ForumTopic[];
|
|
}
|
|
|
|
@customElement('arx-phora-home')
|
|
export class PhoraForum extends LitElement {
|
|
@state()
|
|
private categories: ForumCategory[] = [];
|
|
|
|
private categoriesQuery: NDKSubscription | undefined;
|
|
|
|
static override styles = css`
|
|
:host {
|
|
display: block;
|
|
}
|
|
`;
|
|
|
|
override async connectedCallback() {
|
|
super.connectedCallback();
|
|
await this.loadCategories();
|
|
}
|
|
|
|
override disconnectedCallback() {
|
|
super.disconnectedCallback();
|
|
if (this.categoriesQuery) this.categoriesQuery.stop();
|
|
}
|
|
|
|
private async loadCategories() {
|
|
await getSigner();
|
|
this.categoriesQuery = ndk
|
|
.subscribe({
|
|
kinds: [11],
|
|
})
|
|
.on('event', (event) => {
|
|
const subject = event.tags.find((tag: string[]) => tag[0] === 'subject');
|
|
const parent = event.tags.find((tag: string[]) => tag[0] === 'e');
|
|
|
|
if (!subject) return;
|
|
|
|
if (parent) {
|
|
const categoryIndex = this.categories.findIndex((category) => category.id === parent[1]);
|
|
if (categoryIndex === -1) return;
|
|
|
|
const updatedCategories = [...this.categories];
|
|
updatedCategories[categoryIndex].topics.push({
|
|
id: event.id,
|
|
title: subject[1],
|
|
author: event.pubkey,
|
|
created_at: formatDateTime((event.created_at || 0) * 1000),
|
|
description: event.content,
|
|
});
|
|
|
|
this.categories = updatedCategories;
|
|
return;
|
|
}
|
|
|
|
this.categories = [
|
|
...this.categories,
|
|
{
|
|
id: event.id,
|
|
name: subject[1],
|
|
description: event.content.substring(0, 100),
|
|
topics: [],
|
|
},
|
|
];
|
|
});
|
|
}
|
|
|
|
override render() {
|
|
return html`
|
|
<arx-breadcrumbs
|
|
.items=${[{ text: 'Home', href: '/' }, { text: 'Phora' }]}
|
|
>
|
|
</arx-breadcrumbs>
|
|
|
|
<arx-phora-button href="/phora/new-category">
|
|
New Category
|
|
</arx-phora-button>
|
|
|
|
${this.categories.map(
|
|
(category) => html`
|
|
<arx-phora-forum-category id=${category.id} title=${category.name}>
|
|
${category.topics.map(
|
|
(topic) => html`
|
|
<arx-phora-forum-topic
|
|
id=${topic.id}
|
|
title=${topic.title}
|
|
description=${topic.description}
|
|
lastPostBy=${topic.author}
|
|
lastPostTime=${topic.created_at}
|
|
>
|
|
</arx-phora-forum-topic>
|
|
`,
|
|
)}
|
|
</arx-phora-forum-category>
|
|
`,
|
|
)}
|
|
`;
|
|
}
|
|
}
|