diff --git a/src-tauri/prisma/migrations/20230410024403_add_channel/migration.sql b/src-tauri/prisma/migrations/20230410024403_add_channel/migration.sql new file mode 100644 index 00000000..e39630ca --- /dev/null +++ b/src-tauri/prisma/migrations/20230410024403_add_channel/migration.sql @@ -0,0 +1,12 @@ +-- CreateTable +CREATE TABLE "Channel" ( + "id" INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT, + "eventId" TEXT NOT NULL, + "content" TEXT NOT NULL +); + +-- CreateIndex +CREATE UNIQUE INDEX "Channel_eventId_key" ON "Channel"("eventId"); + +-- CreateIndex +CREATE INDEX "Channel_eventId_idx" ON "Channel"("eventId"); diff --git a/src-tauri/prisma/schema.prisma b/src-tauri/prisma/schema.prisma index 780eca94..99456c2e 100644 --- a/src-tauri/prisma/schema.prisma +++ b/src-tauri/prisma/schema.prisma @@ -66,6 +66,14 @@ model Message { @@index([pubkey, createdAt]) } +model Channel { + id Int @id @default(autoincrement()) + eventId String @unique + content String + + @@index([eventId]) +} + model Relay { id Int @id @default(autoincrement()) url String diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs index fe5caa84..bc017558 100644 --- a/src-tauri/src/main.rs +++ b/src-tauri/src/main.rs @@ -81,6 +81,12 @@ struct GetLatestNoteData { date: i32, } +#[derive(Deserialize, Type)] +struct CreateChannelData { + event_id: String, + content: String, +} + #[tauri::command] #[specta::specta] async fn get_accounts(db: DbState<'_>) -> Result, ()> { @@ -215,6 +221,16 @@ async fn count_total_notes(db: DbState<'_>) -> Result { db.note().count(vec![]).exec().await.map_err(|_| ()) } +#[tauri::command] +#[specta::specta] +async fn create_channel(db: DbState<'_>, data: CreateChannelData) -> Result { + db.channel() + .create(data.event_id, data.content, vec![]) + .exec() + .await + .map_err(|_| ()) +} + #[tokio::main] async fn main() { let db = PrismaClient::_builder().build().await.unwrap(); @@ -230,7 +246,8 @@ async fn main() { create_note, get_notes, get_latest_notes, - get_note_by_id + get_note_by_id, + create_channel ], "../src/utils/bindings.ts", ) @@ -272,7 +289,8 @@ async fn main() { get_notes, get_latest_notes, get_note_by_id, - count_total_notes + count_total_notes, + create_channel ]) .manage(Arc::new(db)) .run(tauri::generate_context!()) diff --git a/src/components/channels/channelList.tsx b/src/components/channels/channelList.tsx index 481230ed..b6af8320 100644 --- a/src/components/channels/channelList.tsx +++ b/src/components/channels/channelList.tsx @@ -1,9 +1,23 @@ -import { ChannelModal } from '@components/channels/channelModal'; +import { CreateChannelModal } from '@components/channels/createChannelModal'; + +import { GlobeIcon } from '@radix-ui/react-icons'; +import Link from 'next/link'; export default function ChannelList() { return (
- + +
+ +
+
+
Browse channels
+
+ +
); } diff --git a/src/components/channels/channelModal.tsx b/src/components/channels/createChannelModal.tsx similarity index 95% rename from src/components/channels/channelModal.tsx rename to src/components/channels/createChannelModal.tsx index 1a600247..4ea33142 100644 --- a/src/components/channels/channelModal.tsx +++ b/src/components/channels/createChannelModal.tsx @@ -5,10 +5,10 @@ import { dateToUnix } from '@utils/getDate'; import * as Dialog from '@radix-ui/react-dialog'; import { Cross1Icon, PlusIcon } from '@radix-ui/react-icons'; import { getEventHash, signEvent } from 'nostr-tools'; -import { useContext, useState } from 'react'; +import { useCallback, useContext, useState } from 'react'; import { useForm } from 'react-hook-form'; -export const ChannelModal = () => { +export const CreateChannelModal = () => { const [pool, relays]: any = useContext(RelayContext); const [open, setOpen] = useState(false); @@ -19,6 +19,11 @@ export const ChannelModal = () => { formState: { isDirty, isValid }, } = useForm(); + const insertChannelToDB = useCallback(async (id, data) => { + const { createChannel } = await import('@utils/bindings'); + return await createChannel({ event_id: id, content: data }); + }, []); + const onSubmit = (data) => { const activeAccount = JSON.parse(localStorage.getItem('activeAccount')); @@ -34,6 +39,8 @@ export const ChannelModal = () => { // publish channel pool.publish(event, relays); + // save to database + insertChannelToDB(event.id, data); // close modal setOpen(false); // reset form diff --git a/src/pages/channels/index.tsx b/src/pages/channels/index.tsx new file mode 100644 index 00000000..f37272fc --- /dev/null +++ b/src/pages/channels/index.tsx @@ -0,0 +1,24 @@ +import BaseLayout from '@layouts/base'; +import WithSidebarLayout from '@layouts/withSidebar'; + +import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal } from 'react'; + +export default function Page() { + return <>; +} + +Page.getLayout = function getLayout( + page: + | string + | number + | boolean + | ReactElement> + | ReactFragment + | ReactPortal +) { + return ( + + {page} + + ); +}; diff --git a/src/utils/bindings.ts b/src/utils/bindings.ts index 32d9834b..2d20b1e2 100644 --- a/src/utils/bindings.ts +++ b/src/utils/bindings.ts @@ -44,6 +44,10 @@ export function getNoteById(data: GetNoteByIdData) { return invoke('get_note_by_id', { data }); } +export function createChannel(data: CreateChannelData) { + return invoke('create_channel', { data }); +} + export type CreateNoteData = { event_id: string; pubkey: string; @@ -55,6 +59,7 @@ export type CreateNoteData = { created_at: number; account_id: number; }; +export type CreateChannelData = { event_id: string; content: string }; export type CreatePlebData = { pleb_id: string; pubkey: string; kind: number; metadata: string; account_id: number }; export type GetNoteByIdData = { event_id: string }; export type Pleb = { id: number; plebId: string; pubkey: string; kind: number; metadata: string; accountId: number }; @@ -71,6 +76,7 @@ export type Note = { accountId: number; }; export type Account = { id: number; pubkey: string; privkey: string; active: boolean; metadata: string }; +export type Channel = { id: number; eventId: string; content: string }; export type GetPlebPubkeyData = { pubkey: string }; export type GetPlebData = { account_id: number }; export type CreateAccountData = { pubkey: string; privkey: string; metadata: string };