mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-19 11:43:30 +00:00
migrated to nextjs 13 app dir
This commit is contained in:
parent
da38ced72c
commit
d59cc041d5
@ -9,7 +9,7 @@
|
|||||||
"bracketSpacing": true,
|
"bracketSpacing": true,
|
||||||
"bracketSameLine": false,
|
"bracketSameLine": false,
|
||||||
"importOrder": [
|
"importOrder": [
|
||||||
"^@layouts/(.*)$",
|
"^@app/(.*)$",
|
||||||
"^@pages/(.*)$",
|
"^@pages/(.*)$",
|
||||||
"^@components/(.*)$",
|
"^@components/(.*)$",
|
||||||
"^@stores/(.*)$",
|
"^@stores/(.*)$",
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
const nextConfig = {
|
const nextConfig = {
|
||||||
|
output: 'export',
|
||||||
reactStrictMode: false,
|
reactStrictMode: false,
|
||||||
swcMinify: true,
|
swcMinify: true,
|
||||||
images: {
|
images: {
|
||||||
@ -11,6 +12,10 @@ const nextConfig = {
|
|||||||
typescript: {
|
typescript: {
|
||||||
ignoreBuildErrors: true,
|
ignoreBuildErrors: true,
|
||||||
},
|
},
|
||||||
|
experimental: {
|
||||||
|
appDir: true,
|
||||||
|
scrollRestoration: true,
|
||||||
|
},
|
||||||
webpack: (config) => {
|
webpack: (config) => {
|
||||||
config.experiments = { ...config.experiments, topLevelAwait: true };
|
config.experiments = { ...config.experiments, topLevelAwait: true };
|
||||||
return config;
|
return config;
|
||||||
|
19
package.json
19
package.json
@ -23,23 +23,23 @@
|
|||||||
"@radix-ui/react-tabs": "^1.0.3",
|
"@radix-ui/react-tabs": "^1.0.3",
|
||||||
"@radix-ui/react-tooltip": "^1.0.5",
|
"@radix-ui/react-tooltip": "^1.0.5",
|
||||||
"@rehooks/local-storage": "^2.4.4",
|
"@rehooks/local-storage": "^2.4.4",
|
||||||
"@supabase/supabase-js": "^2.15.0",
|
"@supabase/supabase-js": "^2.20.0",
|
||||||
"@tauri-apps/api": "^1.2.0",
|
"@tauri-apps/api": "^1.2.0",
|
||||||
"dayjs": "^1.11.7",
|
"dayjs": "^1.11.7",
|
||||||
"destr": "^1.2.2",
|
"destr": "^1.2.2",
|
||||||
"emoji-mart": "^5.5.2",
|
"emoji-mart": "^5.5.2",
|
||||||
"framer-motion": "^9.1.7",
|
"framer-motion": "^9.1.7",
|
||||||
"iconoir-react": "^6.6.0",
|
"iconoir-react": "^6.6.0",
|
||||||
"jotai": "^2.0.3",
|
"jotai": "^2.0.4",
|
||||||
"next": "^13.3.0",
|
"next": "^13.3.0",
|
||||||
"nostr-relaypool": "^0.5.18",
|
"nostr-relaypool": "^0.5.18",
|
||||||
"nostr-tools": "^1.8.2",
|
"nostr-tools": "^1.9.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-hook-form": "^7.43.9",
|
"react-hook-form": "^7.43.9",
|
||||||
"react-player": "^2.12.0",
|
"react-player": "^2.12.0",
|
||||||
"react-string-replace": "^1.1.0",
|
"react-string-replace": "^1.1.0",
|
||||||
"react-virtuoso": "^4.2.0",
|
"react-virtuoso": "^4.2.1",
|
||||||
"unique-names-generator": "^4.7.1",
|
"unique-names-generator": "^4.7.1",
|
||||||
"ws": "^8.13.0"
|
"ws": "^8.13.0"
|
||||||
},
|
},
|
||||||
@ -48,19 +48,20 @@
|
|||||||
"@tauri-apps/cli": "^1.2.3",
|
"@tauri-apps/cli": "^1.2.3",
|
||||||
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
|
"@trivago/prettier-plugin-sort-imports": "^4.1.1",
|
||||||
"@types/node": "^18.15.11",
|
"@types/node": "^18.15.11",
|
||||||
"@types/react": "^18.0.33",
|
"@types/react": "^18.0.35",
|
||||||
"@types/react-dom": "^18.0.11",
|
"@types/react-dom": "^18.0.11",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.57.1",
|
"@typescript-eslint/eslint-plugin": "^5.58.0",
|
||||||
"@typescript-eslint/parser": "^5.57.1",
|
"@typescript-eslint/parser": "^5.58.0",
|
||||||
"autoprefixer": "^10.4.14",
|
"autoprefixer": "^10.4.14",
|
||||||
"csstype": "^3.1.2",
|
"csstype": "^3.1.2",
|
||||||
"eslint": "^8.37.0",
|
"encoding": "^0.1.13",
|
||||||
|
"eslint": "^8.38.0",
|
||||||
"eslint-config-next": "^13.3.0",
|
"eslint-config-next": "^13.3.0",
|
||||||
"eslint-config-prettier": "^8.8.0",
|
"eslint-config-prettier": "^8.8.0",
|
||||||
"eslint-plugin-react": "^7.32.2",
|
"eslint-plugin-react": "^7.32.2",
|
||||||
"eslint-plugin-react-hooks": "^4.6.0",
|
"eslint-plugin-react-hooks": "^4.6.0",
|
||||||
"husky": "^8.0.3",
|
"husky": "^8.0.3",
|
||||||
"lint-staged": "^13.2.0",
|
"lint-staged": "^13.2.1",
|
||||||
"postcss": "^8.4.21",
|
"postcss": "^8.4.21",
|
||||||
"prettier": "^2.8.7",
|
"prettier": "^2.8.7",
|
||||||
"prettier-plugin-tailwindcss": "^0.2.7",
|
"prettier-plugin-tailwindcss": "^0.2.7",
|
||||||
|
495
pnpm-lock.yaml
495
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -3,7 +3,7 @@
|
|||||||
"beforeDevCommand": "pnpm dev",
|
"beforeDevCommand": "pnpm dev",
|
||||||
"beforeBuildCommand": "pnpm build",
|
"beforeBuildCommand": "pnpm build",
|
||||||
"devPath": "http://localhost:1420",
|
"devPath": "http://localhost:1420",
|
||||||
"distDir": "../dist",
|
"distDir": "../out",
|
||||||
"withGlobalTauri": true
|
"withGlobalTauri": true
|
||||||
},
|
},
|
||||||
"package": {
|
"package": {
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
import BaseLayout from '@layouts/base';
|
'use client';
|
||||||
import WithSidebarLayout from '@layouts/withSidebar';
|
|
||||||
|
|
||||||
import { ChannelMessages } from '@components/channels/messages/index';
|
import { ChannelMessages } from '@components/channels/messages/index';
|
||||||
import FormChannelMessage from '@components/form/channelMessage';
|
import FormChannelMessage from '@components/form/channelMessage';
|
||||||
@ -9,24 +8,11 @@ import { channelReplyAtom } from '@stores/channel';
|
|||||||
|
|
||||||
import useLocalStorage from '@rehooks/local-storage';
|
import useLocalStorage from '@rehooks/local-storage';
|
||||||
import { useResetAtom } from 'jotai/utils';
|
import { useResetAtom } from 'jotai/utils';
|
||||||
import { useRouter } from 'next/router';
|
import { useContext, useEffect, useRef, useState } from 'react';
|
||||||
import {
|
|
||||||
JSXElementConstructor,
|
|
||||||
ReactElement,
|
|
||||||
ReactFragment,
|
|
||||||
ReactPortal,
|
|
||||||
useContext,
|
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page({ params }: { params: { id: string } }) {
|
||||||
const [pool, relays]: any = useContext(RelayContext);
|
const [pool, relays]: any = useContext(RelayContext);
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const id: string | string[] = router.query.id || null;
|
|
||||||
|
|
||||||
const [messages, setMessages] = useState([]);
|
const [messages, setMessages] = useState([]);
|
||||||
const [activeAccount]: any = useLocalStorage('activeAccount', {});
|
const [activeAccount]: any = useLocalStorage('activeAccount', {});
|
||||||
const resetChannelReply = useResetAtom(channelReplyAtom);
|
const resetChannelReply = useResetAtom(channelReplyAtom);
|
||||||
@ -46,7 +32,7 @@ export default function Page() {
|
|||||||
since: 0,
|
since: 0,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
'#e': [id],
|
'#e': [params.id],
|
||||||
kinds: [42],
|
kinds: [42],
|
||||||
since: 0,
|
since: 0,
|
||||||
},
|
},
|
||||||
@ -70,32 +56,16 @@ export default function Page() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unsubscribe;
|
unsubscribe();
|
||||||
};
|
};
|
||||||
}, [id, pool, relays, activeAccount.pubkey, resetChannelReply]);
|
}, [pool, relays, activeAccount.pubkey, params.id, resetChannelReply]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full w-full flex-col justify-between">
|
<div className="flex h-full w-full flex-col justify-between">
|
||||||
<ChannelMessages data={messages.sort((a, b) => a.created_at - b.created_at)} />
|
<ChannelMessages data={messages.sort((a, b) => a.created_at - b.created_at)} />
|
||||||
<div className="shrink-0 p-3">
|
<div className="shrink-0 p-3">
|
||||||
<FormChannelMessage eventId={id} />
|
<FormChannelMessage eventId={params.id} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
|
||||||
page:
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<BaseLayout>
|
|
||||||
<WithSidebarLayout>{page}</WithSidebarLayout>
|
|
||||||
</BaseLayout>
|
|
||||||
);
|
|
||||||
};
|
|
39
src/app/channels/layout.tsx
Normal file
39
src/app/channels/layout.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import AppHeader from '@components/appHeader';
|
||||||
|
import MultiAccounts from '@components/multiAccounts';
|
||||||
|
import Navigation from '@components/navigation';
|
||||||
|
|
||||||
|
export default function ChannelsLayout({ children }: { children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<div className="h-screen w-screen bg-zinc-50 text-zinc-900 dark:bg-black dark:text-white">
|
||||||
|
<div className="flex h-screen w-full flex-col">
|
||||||
|
<div
|
||||||
|
data-tauri-drag-region
|
||||||
|
className="relative h-11 shrink-0 border-b border-zinc-100 bg-white dark:border-zinc-900 dark:bg-black"
|
||||||
|
>
|
||||||
|
<AppHeader />
|
||||||
|
</div>
|
||||||
|
<div className="relative flex min-h-0 w-full flex-1">
|
||||||
|
<div className="relative w-[68px] shrink-0 border-r border-zinc-900">
|
||||||
|
<MultiAccounts />
|
||||||
|
</div>
|
||||||
|
<div className="grid w-full grid-cols-4 xl:grid-cols-5">
|
||||||
|
<div className="scrollbar-hide col-span-1 overflow-y-auto overflow-x-hidden border-r border-zinc-900">
|
||||||
|
<Navigation />
|
||||||
|
</div>
|
||||||
|
<div className="col-span-3 m-3 overflow-hidden rounded-lg border border-zinc-800 bg-zinc-900 shadow-input shadow-black/20 xl:col-span-2 xl:mr-1.5">
|
||||||
|
<div className="h-full w-full rounded-lg">{children}</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-span-3 m-3 hidden overflow-hidden rounded-lg border border-zinc-800 bg-zinc-900 shadow-input shadow-black/20 xl:col-span-2 xl:ml-1.5 xl:flex">
|
||||||
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
|
<p className="select-text p-8 text-center text-zinc-400">
|
||||||
|
This feature hasn't implemented yet, so resize Lume to the initial size for a better experience.
|
||||||
|
I'm sorry for this inconvenience, and I swear I will add it soon 😁
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -1,9 +1,8 @@
|
|||||||
import BaseLayout from '@layouts/base';
|
'use client';
|
||||||
import WithSidebarLayout from '@layouts/withSidebar';
|
|
||||||
|
|
||||||
import { BrowseChannelItem } from '@components/channels/browseChannelItem';
|
import { BrowseChannelItem } from '@components/channels/browseChannelItem';
|
||||||
|
|
||||||
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const [list, setList] = useState([]);
|
const [list, setList] = useState([]);
|
||||||
@ -27,19 +26,3 @@ export default function Page() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
|
||||||
page:
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<BaseLayout>
|
|
||||||
<WithSidebarLayout>{page}</WithSidebarLayout>
|
|
||||||
</BaseLayout>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,28 +1,15 @@
|
|||||||
import BaseLayout from '@layouts/base';
|
'use client';
|
||||||
import WithSidebarLayout from '@layouts/withSidebar';
|
|
||||||
|
|
||||||
import { MessageList } from '@components/chats/messageList';
|
import { MessageList } from '@components/chats/messageList';
|
||||||
import FormChat from '@components/form/chat';
|
import FormChat from '@components/form/chat';
|
||||||
import { RelayContext } from '@components/relaysProvider';
|
import { RelayContext } from '@components/relaysProvider';
|
||||||
|
|
||||||
import useLocalStorage from '@rehooks/local-storage';
|
import useLocalStorage from '@rehooks/local-storage';
|
||||||
import { useRouter } from 'next/router';
|
import { useContext, useEffect, useState } from 'react';
|
||||||
import {
|
|
||||||
JSXElementConstructor,
|
|
||||||
ReactElement,
|
|
||||||
ReactFragment,
|
|
||||||
ReactPortal,
|
|
||||||
useContext,
|
|
||||||
useEffect,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page({ params }: { params: { pubkey: string } }) {
|
||||||
const [pool, relays]: any = useContext(RelayContext);
|
const [pool, relays]: any = useContext(RelayContext);
|
||||||
|
|
||||||
const router = useRouter();
|
|
||||||
const pubkey: any = router.query.pubkey || null;
|
|
||||||
|
|
||||||
const [activeAccount]: any = useLocalStorage('activeAccount', {});
|
const [activeAccount]: any = useLocalStorage('activeAccount', {});
|
||||||
const [messages, setMessages] = useState([]);
|
const [messages, setMessages] = useState([]);
|
||||||
|
|
||||||
@ -31,13 +18,13 @@ export default function Page() {
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
kinds: [4],
|
kinds: [4],
|
||||||
authors: [pubkey],
|
authors: [params.pubkey],
|
||||||
'#p': [activeAccount.pubkey],
|
'#p': [activeAccount.pubkey],
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
kinds: [4],
|
kinds: [4],
|
||||||
authors: [activeAccount.pubkey],
|
authors: [activeAccount.pubkey],
|
||||||
'#p': [pubkey],
|
'#p': [params.pubkey],
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
relays,
|
relays,
|
||||||
@ -47,32 +34,16 @@ export default function Page() {
|
|||||||
);
|
);
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
unsubscribe;
|
unsubscribe();
|
||||||
};
|
};
|
||||||
}, [pool, relays, pubkey, activeAccount.pubkey]);
|
}, [pool, relays, params.pubkey, activeAccount.pubkey]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="flex h-full w-full flex-col justify-between">
|
<div className="flex h-full w-full flex-col justify-between">
|
||||||
<MessageList data={messages.sort((a, b) => a.created_at - b.created_at)} />
|
<MessageList data={messages.sort((a, b) => a.created_at - b.created_at)} />
|
||||||
<div className="shrink-0 p-3">
|
<div className="shrink-0 p-3">
|
||||||
<FormChat receiverPubkey={pubkey} />
|
<FormChat receiverPubkey={params.pubkey} />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
|
||||||
page:
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<BaseLayout>
|
|
||||||
<WithSidebarLayout>{page}</WithSidebarLayout>
|
|
||||||
</BaseLayout>
|
|
||||||
);
|
|
||||||
};
|
|
39
src/app/chats/layout.tsx
Normal file
39
src/app/chats/layout.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import AppHeader from '@components/appHeader';
|
||||||
|
import MultiAccounts from '@components/multiAccounts';
|
||||||
|
import Navigation from '@components/navigation';
|
||||||
|
|
||||||
|
export default function ChatsLayout({ children }: { children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<div className="h-screen w-screen bg-zinc-50 text-zinc-900 dark:bg-black dark:text-white">
|
||||||
|
<div className="flex h-screen w-full flex-col">
|
||||||
|
<div
|
||||||
|
data-tauri-drag-region
|
||||||
|
className="relative h-11 shrink-0 border-b border-zinc-100 bg-white dark:border-zinc-900 dark:bg-black"
|
||||||
|
>
|
||||||
|
<AppHeader />
|
||||||
|
</div>
|
||||||
|
<div className="relative flex min-h-0 w-full flex-1">
|
||||||
|
<div className="relative w-[68px] shrink-0 border-r border-zinc-900">
|
||||||
|
<MultiAccounts />
|
||||||
|
</div>
|
||||||
|
<div className="grid w-full grid-cols-4 xl:grid-cols-5">
|
||||||
|
<div className="scrollbar-hide col-span-1 overflow-y-auto overflow-x-hidden border-r border-zinc-900">
|
||||||
|
<Navigation />
|
||||||
|
</div>
|
||||||
|
<div className="col-span-3 m-3 overflow-hidden rounded-lg border border-zinc-800 bg-zinc-900 shadow-input shadow-black/20 xl:col-span-2 xl:mr-1.5">
|
||||||
|
<div className="h-full w-full rounded-lg">{children}</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-span-3 m-3 hidden overflow-hidden rounded-lg border border-zinc-800 bg-zinc-900 shadow-input shadow-black/20 xl:col-span-2 xl:ml-1.5 xl:flex">
|
||||||
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
|
<p className="select-text p-8 text-center text-zinc-400">
|
||||||
|
This feature hasn't implemented yet, so resize Lume to the initial size for a better experience.
|
||||||
|
I'm sorry for this inconvenience, and I swear I will add it soon 😁
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
3
src/app/explore/page.tsx
Normal file
3
src/app/explore/page.tsx
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
export default function Page() {
|
||||||
|
return <></>;
|
||||||
|
}
|
13
src/app/layout.tsx
Normal file
13
src/app/layout.tsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
import '@assets/global.css';
|
||||||
|
|
||||||
|
import { Providers } from './providers';
|
||||||
|
|
||||||
|
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<html lang="en" className="dark">
|
||||||
|
<body className="cursor-default select-none overflow-hidden font-sans antialiased">
|
||||||
|
<Providers>{children}</Providers>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
);
|
||||||
|
}
|
5
src/app/newsfeed/[id]/page.tsx
Normal file
5
src/app/newsfeed/[id]/page.tsx
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
export default function Page({ params }: { params: { id: string } }) {
|
||||||
|
return <div className="scrollbar-hide flex h-full flex-col gap-2 overflow-y-auto py-3">{params.id}</div>;
|
||||||
|
}
|
7
src/app/newsfeed/circle/page.tsx
Normal file
7
src/app/newsfeed/circle/page.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
export default function Page() {
|
||||||
|
return (
|
||||||
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
|
<p className="text-sm text-zinc-400">Sorry, this feature under development, it will come in the next version</p>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -1,5 +1,4 @@
|
|||||||
import BaseLayout from '@layouts/base';
|
'use client';
|
||||||
import WithSidebarLayout from '@layouts/withSidebar';
|
|
||||||
|
|
||||||
import FormBase from '@components/form/base';
|
import FormBase from '@components/form/base';
|
||||||
import { NoteBase } from '@components/note/base';
|
import { NoteBase } from '@components/note/base';
|
||||||
@ -12,16 +11,7 @@ import { filterDuplicateParentID } from '@utils/transform';
|
|||||||
|
|
||||||
import { ArrowUp } from 'iconoir-react';
|
import { ArrowUp } from 'iconoir-react';
|
||||||
import { useAtom } from 'jotai';
|
import { useAtom } from 'jotai';
|
||||||
import {
|
import { useCallback, useEffect, useRef, useState } from 'react';
|
||||||
JSXElementConstructor,
|
|
||||||
ReactElement,
|
|
||||||
ReactFragment,
|
|
||||||
ReactPortal,
|
|
||||||
useCallback,
|
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
import { Virtuoso } from 'react-virtuoso';
|
import { Virtuoso } from 'react-virtuoso';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
@ -121,19 +111,3 @@ const COMPONENTS = {
|
|||||||
EmptyPlaceholder: () => <Placeholder />,
|
EmptyPlaceholder: () => <Placeholder />,
|
||||||
ScrollSeekPlaceholder: () => <Placeholder />,
|
ScrollSeekPlaceholder: () => <Placeholder />,
|
||||||
};
|
};
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
|
||||||
page:
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<BaseLayout>
|
|
||||||
<WithSidebarLayout>{page}</WithSidebarLayout>
|
|
||||||
</BaseLayout>
|
|
||||||
);
|
|
||||||
};
|
|
39
src/app/newsfeed/layout.tsx
Normal file
39
src/app/newsfeed/layout.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import AppHeader from '@components/appHeader';
|
||||||
|
import MultiAccounts from '@components/multiAccounts';
|
||||||
|
import Navigation from '@components/navigation';
|
||||||
|
|
||||||
|
export default function Layout({ children }: { children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<div className="h-screen w-screen bg-zinc-50 text-zinc-900 dark:bg-black dark:text-white">
|
||||||
|
<div className="flex h-screen w-full flex-col">
|
||||||
|
<div
|
||||||
|
data-tauri-drag-region
|
||||||
|
className="relative h-11 shrink-0 border-b border-zinc-100 bg-white dark:border-zinc-900 dark:bg-black"
|
||||||
|
>
|
||||||
|
<AppHeader />
|
||||||
|
</div>
|
||||||
|
<div className="relative flex min-h-0 w-full flex-1">
|
||||||
|
<div className="relative w-[68px] shrink-0 border-r border-zinc-900">
|
||||||
|
<MultiAccounts />
|
||||||
|
</div>
|
||||||
|
<div className="grid w-full grid-cols-4 xl:grid-cols-5">
|
||||||
|
<div className="scrollbar-hide col-span-1 overflow-y-auto overflow-x-hidden border-r border-zinc-900">
|
||||||
|
<Navigation />
|
||||||
|
</div>
|
||||||
|
<div className="col-span-3 m-3 overflow-hidden rounded-lg border border-zinc-800 bg-zinc-900 shadow-input shadow-black/20 xl:col-span-2 xl:mr-1.5">
|
||||||
|
<div className="h-full w-full rounded-lg">{children}</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-span-3 m-3 hidden overflow-hidden rounded-lg border border-zinc-800 bg-zinc-900 shadow-input shadow-black/20 xl:col-span-2 xl:ml-1.5 xl:flex">
|
||||||
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
|
<p className="select-text p-8 text-center text-zinc-400">
|
||||||
|
This feature hasn't implemented yet, so resize Lume to the initial size for a better experience.
|
||||||
|
I'm sorry for this inconvenience, and I swear I will add it soon 😁
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import BaseLayout from '@layouts/base';
|
'use client';
|
||||||
|
|
||||||
import { RelayContext } from '@components/relaysProvider';
|
import { RelayContext } from '@components/relaysProvider';
|
||||||
import { UserBase } from '@components/user/base';
|
import { UserBase } from '@components/user/base';
|
||||||
@ -8,19 +8,9 @@ import { followsTag } from '@utils/transform';
|
|||||||
|
|
||||||
import { createClient } from '@supabase/supabase-js';
|
import { createClient } from '@supabase/supabase-js';
|
||||||
import { CheckCircle } from 'iconoir-react';
|
import { CheckCircle } from 'iconoir-react';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/navigation';
|
||||||
import { getEventHash, signEvent } from 'nostr-tools';
|
import { getEventHash, signEvent } from 'nostr-tools';
|
||||||
import {
|
import { Key, useCallback, useContext, useEffect, useState } from 'react';
|
||||||
JSXElementConstructor,
|
|
||||||
Key,
|
|
||||||
ReactElement,
|
|
||||||
ReactFragment,
|
|
||||||
ReactPortal,
|
|
||||||
useCallback,
|
|
||||||
useContext,
|
|
||||||
useEffect,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
|
|
||||||
const supabase = createClient(
|
const supabase = createClient(
|
||||||
'https://niwaazauwnrwiwmnocnn.supabase.co',
|
'https://niwaazauwnrwiwmnocnn.supabase.co',
|
||||||
@ -62,11 +52,9 @@ const initialList = [
|
|||||||
{ pubkey: 'ff04a0e6cd80c141b0b55825fed127d4532a6eecdb7e743a38a3c28bf9f44609' },
|
{ pubkey: 'ff04a0e6cd80c141b0b55825fed127d4532a6eecdb7e743a38a3c28bf9f44609' },
|
||||||
];
|
];
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page({ params }: { params: { id: string; pubkey: string; privkey: string } }) {
|
||||||
const [pool, relays]: any = useContext(RelayContext);
|
|
||||||
|
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const { id, pubkey, privkey }: any = router.query || '';
|
const [pool, relays]: any = useContext(RelayContext);
|
||||||
|
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const [list, setList]: any = useState(initialList);
|
const [list, setList]: any = useState(initialList);
|
||||||
@ -86,11 +74,11 @@ export default function Page() {
|
|||||||
for (const follow of follows) {
|
for (const follow of follows) {
|
||||||
const metadata: any = await fetchMetadata(follow);
|
const metadata: any = await fetchMetadata(follow);
|
||||||
createPleb({
|
createPleb({
|
||||||
pleb_id: follow + '-lume' + id,
|
pleb_id: follow + '-lume' + params.id,
|
||||||
pubkey: follow,
|
pubkey: follow,
|
||||||
kind: 0,
|
kind: 0,
|
||||||
metadata: metadata.content,
|
metadata: metadata.content,
|
||||||
account_id: parseInt(id),
|
account_id: parseInt(params.id),
|
||||||
}).catch(console.error);
|
}).catch(console.error);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,15 +87,15 @@ export default function Page() {
|
|||||||
content: '',
|
content: '',
|
||||||
created_at: Math.floor(Date.now() / 1000),
|
created_at: Math.floor(Date.now() / 1000),
|
||||||
kind: 3,
|
kind: 3,
|
||||||
pubkey: pubkey,
|
pubkey: params.pubkey,
|
||||||
tags: followsTag(follows),
|
tags: followsTag(follows),
|
||||||
};
|
};
|
||||||
event.id = getEventHash(event);
|
event.id = getEventHash(event);
|
||||||
event.sig = signEvent(event, privkey);
|
event.sig = signEvent(event, params.privkey);
|
||||||
|
|
||||||
pool.publish(event, relays);
|
pool.publish(event, relays);
|
||||||
router.replace('/');
|
router.replace('/');
|
||||||
}, [follows, id, pool, pubkey, privkey, relays, router]);
|
}, [params.pubkey, params.privkey, params.id, follows, pool, relays, router]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const fetchData = async () => {
|
const fetchData = async () => {
|
||||||
@ -182,15 +170,3 @@ export default function Page() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
|
||||||
page:
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
|
||||||
return <BaseLayout>{page}</BaseLayout>;
|
|
||||||
};
|
|
@ -1,21 +1,12 @@
|
|||||||
import BaseLayout from '@layouts/base';
|
'use client';
|
||||||
|
|
||||||
import { RelayContext } from '@components/relaysProvider';
|
import { RelayContext } from '@components/relaysProvider';
|
||||||
|
|
||||||
import { ArrowLeft, EyeClose, EyeEmpty } from 'iconoir-react';
|
import { ArrowLeft, EyeClose, EyeEmpty } from 'iconoir-react';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/navigation';
|
||||||
import { generatePrivateKey, getEventHash, getPublicKey, nip19, signEvent } from 'nostr-tools';
|
import { generatePrivateKey, getEventHash, getPublicKey, nip19, signEvent } from 'nostr-tools';
|
||||||
import {
|
import { useCallback, useContext, useMemo, useState } from 'react';
|
||||||
JSXElementConstructor,
|
|
||||||
ReactElement,
|
|
||||||
ReactFragment,
|
|
||||||
ReactPortal,
|
|
||||||
useCallback,
|
|
||||||
useContext,
|
|
||||||
useMemo,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
import { Config, names, uniqueNamesGenerator } from 'unique-names-generator';
|
import { Config, names, uniqueNamesGenerator } from 'unique-names-generator';
|
||||||
|
|
||||||
const config: Config = {
|
const config: Config = {
|
||||||
@ -80,10 +71,7 @@ export default function Page() {
|
|||||||
createAccount({ pubkey: pubKey, privkey: privKey, metadata: metadata })
|
createAccount({ pubkey: pubKey, privkey: privKey, metadata: metadata })
|
||||||
.then((res) => {
|
.then((res) => {
|
||||||
pool.publish(event, relays);
|
pool.publish(event, relays);
|
||||||
router.push({
|
router.push(`/onboarding/create/${res.id}/${res.pubkey}/${res.privkey}`);
|
||||||
pathname: '/onboarding/create/step-2',
|
|
||||||
query: { id: res.id, pubkey: res.pubkey, privkey: res.privkey },
|
|
||||||
});
|
|
||||||
})
|
})
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
}, [pool, pubKey, privKey, metadata, relays, router]);
|
}, [pool, pubKey, privKey, metadata, relays, router]);
|
||||||
@ -193,15 +181,3 @@ export default function Page() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
|
||||||
page:
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
|
||||||
return <BaseLayout>{page}</BaseLayout>;
|
|
||||||
};
|
|
13
src/app/onboarding/layout.tsx
Normal file
13
src/app/onboarding/layout.tsx
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
export default function OnboardingLayout({ children }: { children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<div className="h-screen w-screen bg-zinc-50 text-zinc-900 dark:bg-black dark:text-white">
|
||||||
|
<div className="flex h-screen w-full flex-col">
|
||||||
|
<div
|
||||||
|
data-tauri-drag-region
|
||||||
|
className="relative h-11 shrink-0 border-b border-zinc-100 bg-white dark:border-zinc-900 dark:bg-black"
|
||||||
|
></div>
|
||||||
|
<div className="relative flex min-h-0 w-full flex-1">{children}</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -1,4 +1,4 @@
|
|||||||
import BaseLayout from '@layouts/base';
|
'use client';
|
||||||
|
|
||||||
import { RelayContext } from '@components/relaysProvider';
|
import { RelayContext } from '@components/relaysProvider';
|
||||||
|
|
||||||
@ -8,26 +8,15 @@ import { fetchMetadata } from '@utils/metadata';
|
|||||||
import { truncate } from '@utils/truncate';
|
import { truncate } from '@utils/truncate';
|
||||||
|
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/navigation';
|
||||||
import { getPublicKey } from 'nostr-tools';
|
import { getPublicKey } from 'nostr-tools';
|
||||||
import {
|
import { useCallback, useContext, useEffect, useMemo, useState } from 'react';
|
||||||
JSXElementConstructor,
|
|
||||||
ReactElement,
|
|
||||||
ReactFragment,
|
|
||||||
ReactPortal,
|
|
||||||
useCallback,
|
|
||||||
useContext,
|
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page({ params }: { params: { privkey: string } }) {
|
||||||
|
const router = useRouter();
|
||||||
const [pool, relays]: any = useContext(RelayContext);
|
const [pool, relays]: any = useContext(RelayContext);
|
||||||
|
|
||||||
const router = useRouter();
|
const pubkey = useMemo(() => (params.privkey ? getPublicKey(params.privkey) : null), [params.privkey]);
|
||||||
const privkey: any = router.query.privkey || null;
|
|
||||||
const pubkey = privkey ? getPublicKey(privkey) : null;
|
|
||||||
|
|
||||||
const [profile, setProfile] = useState({ id: null, metadata: null });
|
const [profile, setProfile] = useState({ id: null, metadata: null });
|
||||||
const [done, setDone] = useState(false);
|
const [done, setDone] = useState(false);
|
||||||
@ -75,7 +64,7 @@ export default function Page() {
|
|||||||
relays,
|
relays,
|
||||||
(event: any) => {
|
(event: any) => {
|
||||||
if (event.kind === 0) {
|
if (event.kind === 0) {
|
||||||
insertAccountToStorage(pubkey, privkey, event.content);
|
insertAccountToStorage(pubkey, params.privkey, event.content);
|
||||||
} else {
|
} else {
|
||||||
if (event.tags.length > 0) {
|
if (event.tags.length > 0) {
|
||||||
insertFollowsToStorage(event.tags);
|
insertFollowsToStorage(event.tags);
|
||||||
@ -91,7 +80,7 @@ export default function Page() {
|
|||||||
return () => {
|
return () => {
|
||||||
unsubscribe;
|
unsubscribe;
|
||||||
};
|
};
|
||||||
}, [insertAccountToStorage, insertFollowsToStorage, pool, relays, privkey, pubkey]);
|
}, [insertAccountToStorage, insertFollowsToStorage, pool, relays, pubkey, params.privkey]);
|
||||||
|
|
||||||
// submit then redirect to home
|
// submit then redirect to home
|
||||||
const submit = () => {
|
const submit = () => {
|
||||||
@ -168,15 +157,3 @@ export default function Page() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
|
||||||
page:
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
|
||||||
return <BaseLayout>{page}</BaseLayout>;
|
|
||||||
};
|
|
@ -1,9 +1,8 @@
|
|||||||
import BaseLayout from '@layouts/base';
|
'use client';
|
||||||
|
|
||||||
import { ArrowLeft, CableTag } from 'iconoir-react';
|
import { ArrowLeft, CableTag } from 'iconoir-react';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/navigation';
|
||||||
import { nip19 } from 'nostr-tools';
|
import { nip19 } from 'nostr-tools';
|
||||||
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal } from 'react';
|
|
||||||
import { Resolver, useForm } from 'react-hook-form';
|
import { Resolver, useForm } from 'react-hook-form';
|
||||||
|
|
||||||
type FormValues = {
|
type FormValues = {
|
||||||
@ -45,10 +44,7 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
router.push({
|
router.push(`/onboarding/login/${privkey}`);
|
||||||
pathname: '/onboarding/login/step-2',
|
|
||||||
query: { privkey: privkey },
|
|
||||||
});
|
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setError('key', {
|
setError('key', {
|
||||||
type: 'custom',
|
type: 'custom',
|
||||||
@ -134,15 +130,3 @@ export default function Page() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
|
||||||
page:
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
|
||||||
return <BaseLayout>{page}</BaseLayout>;
|
|
||||||
};
|
|
@ -1,9 +1,6 @@
|
|||||||
import BaseLayout from '@layouts/base';
|
|
||||||
|
|
||||||
import { ArrowRight } from 'iconoir-react';
|
import { ArrowRight } from 'iconoir-react';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal } from 'react';
|
|
||||||
|
|
||||||
const PLEBS = [
|
const PLEBS = [
|
||||||
'https://133332.xyz/p.jpg',
|
'https://133332.xyz/p.jpg',
|
||||||
@ -128,15 +125,3 @@ export default function Page() {
|
|||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
|
||||||
page:
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
|
||||||
return <BaseLayout>{page}</BaseLayout>;
|
|
||||||
};
|
|
@ -1,4 +1,4 @@
|
|||||||
import BaseLayout from '@layouts/base';
|
'use client';
|
||||||
|
|
||||||
import { RelayContext } from '@components/relaysProvider';
|
import { RelayContext } from '@components/relaysProvider';
|
||||||
|
|
||||||
@ -8,17 +8,8 @@ import { getParentID, pubkeyArray } from '@utils/transform';
|
|||||||
import LumeSymbol from '@assets/icons/Lume';
|
import LumeSymbol from '@assets/icons/Lume';
|
||||||
|
|
||||||
import useLocalStorage, { writeStorage } from '@rehooks/local-storage';
|
import useLocalStorage, { writeStorage } from '@rehooks/local-storage';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/navigation';
|
||||||
import {
|
import { useCallback, useContext, useEffect, useRef } from 'react';
|
||||||
JSXElementConstructor,
|
|
||||||
ReactElement,
|
|
||||||
ReactFragment,
|
|
||||||
ReactPortal,
|
|
||||||
useCallback,
|
|
||||||
useContext,
|
|
||||||
useEffect,
|
|
||||||
useRef,
|
|
||||||
} from 'react';
|
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const [pool, relays]: any = useContext(RelayContext);
|
const [pool, relays]: any = useContext(RelayContext);
|
||||||
@ -174,50 +165,40 @@ export default function Page() {
|
|||||||
}, [fetchActiveAccount, fetchPlebsByAccount, totalNotes, fetchData, router]);
|
}, [fetchActiveAccount, fetchPlebsByAccount, totalNotes, fetchData, router]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className="relative h-full overflow-hidden">
|
<div className="h-screen w-screen bg-zinc-50 text-zinc-900 dark:bg-black dark:text-white">
|
||||||
{/* dragging area */}
|
<div className="relative h-full overflow-hidden">
|
||||||
<div data-tauri-drag-region className="absolute left-0 top-0 z-20 h-16 w-full bg-transparent" />
|
{/* dragging area */}
|
||||||
{/* end dragging area */}
|
<div data-tauri-drag-region className="absolute left-0 top-0 z-20 h-16 w-full bg-transparent" />
|
||||||
<div className="relative flex h-full flex-col items-center justify-center">
|
{/* end dragging area */}
|
||||||
<div className="flex flex-col items-center gap-2">
|
<div className="relative flex h-full flex-col items-center justify-center">
|
||||||
<LumeSymbol className="h-16 w-16 text-black dark:text-white" />
|
<div className="flex flex-col items-center gap-2">
|
||||||
<div className="text-center">
|
<LumeSymbol className="h-16 w-16 text-black dark:text-white" />
|
||||||
<h3 className="text-lg font-semibold leading-tight text-zinc-900 dark:text-zinc-100">
|
<div className="text-center">
|
||||||
Here's an interesting fact:
|
<h3 className="text-lg font-semibold leading-tight text-zinc-900 dark:text-zinc-100">
|
||||||
</h3>
|
Here's an interesting fact:
|
||||||
<p className="font-medium text-zinc-300 dark:text-zinc-600">
|
</h3>
|
||||||
Bitcoin and Nostr can be used by anyone, and no one can stop you!
|
<p className="font-medium text-zinc-300 dark:text-zinc-600">
|
||||||
</p>
|
Bitcoin and Nostr can be used by anyone, and no one can stop you!
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="absolute bottom-16 left-1/2 -translate-x-1/2 transform">
|
||||||
|
<svg
|
||||||
|
className="h-5 w-5 animate-spin text-black dark:text-white"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
>
|
||||||
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||||
|
<path
|
||||||
|
className="opacity-75"
|
||||||
|
fill="currentColor"
|
||||||
|
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
||||||
|
></path>
|
||||||
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
|
||||||
<div className="absolute bottom-16 left-1/2 -translate-x-1/2 transform">
|
|
||||||
<svg
|
|
||||||
className="h-5 w-5 animate-spin text-black dark:text-white"
|
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
|
||||||
fill="none"
|
|
||||||
viewBox="0 0 24 24"
|
|
||||||
>
|
|
||||||
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
|
||||||
<path
|
|
||||||
className="opacity-75"
|
|
||||||
fill="currentColor"
|
|
||||||
d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"
|
|
||||||
></path>
|
|
||||||
</svg>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
|
||||||
page:
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
|
||||||
return <BaseLayout>{page}</BaseLayout>;
|
|
||||||
};
|
|
7
src/app/providers.tsx
Normal file
7
src/app/providers.tsx
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import RelayProvider from '@components/relaysProvider';
|
||||||
|
|
||||||
|
export function Providers({ children }: { children: React.ReactNode }) {
|
||||||
|
return <RelayProvider>{children}</RelayProvider>;
|
||||||
|
}
|
@ -1,5 +1,4 @@
|
|||||||
import BaseLayout from '@layouts/base';
|
'use client';
|
||||||
import WithSidebarLayout from '@layouts/withSidebar';
|
|
||||||
|
|
||||||
import ProfileFollowers from '@components/profile/followers';
|
import ProfileFollowers from '@components/profile/followers';
|
||||||
import ProfileFollows from '@components/profile/follows';
|
import ProfileFollows from '@components/profile/follows';
|
||||||
@ -7,16 +6,11 @@ import ProfileMetadata from '@components/profile/metadata';
|
|||||||
import ProfileNotes from '@components/profile/notes';
|
import ProfileNotes from '@components/profile/notes';
|
||||||
|
|
||||||
import * as Tabs from '@radix-ui/react-tabs';
|
import * as Tabs from '@radix-ui/react-tabs';
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal } from 'react';
|
|
||||||
|
|
||||||
export default function Page() {
|
|
||||||
const router = useRouter();
|
|
||||||
const id: any = router.query.id || '';
|
|
||||||
|
|
||||||
|
export default function Page({ params }: { params: { id: string } }) {
|
||||||
return (
|
return (
|
||||||
<div className="scrollbar-hide h-full w-full overflow-y-auto">
|
<div className="scrollbar-hide h-full w-full overflow-y-auto">
|
||||||
<ProfileMetadata id={id} />
|
<ProfileMetadata id={params.id} />
|
||||||
<Tabs.Root className="flex w-full flex-col" defaultValue="notes">
|
<Tabs.Root className="flex w-full flex-col" defaultValue="notes">
|
||||||
<Tabs.List className="flex border-b border-zinc-800">
|
<Tabs.List className="flex border-b border-zinc-800">
|
||||||
<Tabs.Trigger
|
<Tabs.Trigger
|
||||||
@ -39,31 +33,15 @@ export default function Page() {
|
|||||||
</Tabs.Trigger>
|
</Tabs.Trigger>
|
||||||
</Tabs.List>
|
</Tabs.List>
|
||||||
<Tabs.Content value="notes">
|
<Tabs.Content value="notes">
|
||||||
<ProfileNotes id={id} />
|
<ProfileNotes id={params.id} />
|
||||||
</Tabs.Content>
|
</Tabs.Content>
|
||||||
<Tabs.Content value="followers">
|
<Tabs.Content value="followers">
|
||||||
<ProfileFollowers id={id} />
|
<ProfileFollowers id={params.id} />
|
||||||
</Tabs.Content>
|
</Tabs.Content>
|
||||||
<Tabs.Content value="following">
|
<Tabs.Content value="following">
|
||||||
<ProfileFollows id={id} />
|
<ProfileFollows id={params.id} />
|
||||||
</Tabs.Content>
|
</Tabs.Content>
|
||||||
</Tabs.Root>
|
</Tabs.Root>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
|
||||||
page:
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<BaseLayout>
|
|
||||||
<WithSidebarLayout>{page}</WithSidebarLayout>
|
|
||||||
</BaseLayout>
|
|
||||||
);
|
|
||||||
};
|
|
39
src/app/users/layout.tsx
Normal file
39
src/app/users/layout.tsx
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import AppHeader from '@components/appHeader';
|
||||||
|
import MultiAccounts from '@components/multiAccounts';
|
||||||
|
import Navigation from '@components/navigation';
|
||||||
|
|
||||||
|
export default function UsersLayout({ children }: { children: React.ReactNode }) {
|
||||||
|
return (
|
||||||
|
<div className="h-screen w-screen bg-zinc-50 text-zinc-900 dark:bg-black dark:text-white">
|
||||||
|
<div className="flex h-screen w-full flex-col">
|
||||||
|
<div
|
||||||
|
data-tauri-drag-region
|
||||||
|
className="relative h-11 shrink-0 border-b border-zinc-100 bg-white dark:border-zinc-900 dark:bg-black"
|
||||||
|
>
|
||||||
|
<AppHeader />
|
||||||
|
</div>
|
||||||
|
<div className="relative flex min-h-0 w-full flex-1">
|
||||||
|
<div className="relative w-[68px] shrink-0 border-r border-zinc-900">
|
||||||
|
<MultiAccounts />
|
||||||
|
</div>
|
||||||
|
<div className="grid w-full grid-cols-4 xl:grid-cols-5">
|
||||||
|
<div className="scrollbar-hide col-span-1 overflow-y-auto overflow-x-hidden border-r border-zinc-900">
|
||||||
|
<Navigation />
|
||||||
|
</div>
|
||||||
|
<div className="col-span-3 m-3 overflow-hidden rounded-lg border border-zinc-800 bg-zinc-900 shadow-input shadow-black/20 xl:col-span-2 xl:mr-1.5">
|
||||||
|
<div className="h-full w-full rounded-lg">{children}</div>
|
||||||
|
</div>
|
||||||
|
<div className="col-span-3 m-3 hidden overflow-hidden rounded-lg border border-zinc-800 bg-zinc-900 shadow-input shadow-black/20 xl:col-span-2 xl:ml-1.5 xl:flex">
|
||||||
|
<div className="flex h-full w-full items-center justify-center">
|
||||||
|
<p className="select-text p-8 text-center text-zinc-400">
|
||||||
|
This feature hasn't implemented yet, so resize Lume to the initial size for a better experience.
|
||||||
|
I'm sorry for this inconvenience, and I swear I will add it soon 😁
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
@ -1,39 +0,0 @@
|
|||||||
import Link, { LinkProps } from 'next/link';
|
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import { PropsWithChildren, memo, useEffect, useState } from 'react';
|
|
||||||
|
|
||||||
type ActiveLinkProps = LinkProps & {
|
|
||||||
className?: string;
|
|
||||||
activeClassName: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
const ActiveLink = ({ children, activeClassName, className, ...props }: PropsWithChildren<ActiveLinkProps>) => {
|
|
||||||
const { asPath, isReady } = useRouter();
|
|
||||||
const [computedClassName, setComputedClassName] = useState(className);
|
|
||||||
|
|
||||||
useEffect(() => {
|
|
||||||
// Check if the router fields are updated client-side
|
|
||||||
if (isReady) {
|
|
||||||
// Dynamic route will be matched via props.as
|
|
||||||
// Static route will be matched via props.href
|
|
||||||
const linkPathname = new URL((props.as || props.href) as string, location.href).pathname;
|
|
||||||
|
|
||||||
// Using URL().pathname to get rid of query and hash
|
|
||||||
const activePathname = new URL(asPath, location.href).pathname;
|
|
||||||
|
|
||||||
const newClassName = linkPathname === activePathname ? `${className} ${activeClassName}`.trim() : className;
|
|
||||||
|
|
||||||
if (newClassName !== computedClassName) {
|
|
||||||
setComputedClassName(newClassName);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}, [asPath, isReady, props.as, props.href, activeClassName, className, computedClassName]);
|
|
||||||
|
|
||||||
return (
|
|
||||||
<Link className={computedClassName} {...props}>
|
|
||||||
{children}
|
|
||||||
</Link>
|
|
||||||
);
|
|
||||||
};
|
|
||||||
|
|
||||||
export default memo(ActiveLink);
|
|
@ -1,6 +1,8 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import { platform } from '@tauri-apps/api/os';
|
import { platform } from '@tauri-apps/api/os';
|
||||||
import { ArrowLeft, ArrowRight, Refresh } from 'iconoir-react';
|
import { ArrowLeft, ArrowRight, Refresh } from 'iconoir-react';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/navigation';
|
||||||
import { useLayoutEffect, useState } from 'react';
|
import { useLayoutEffect, useState } from 'react';
|
||||||
|
|
||||||
export default function AppActions() {
|
export default function AppActions() {
|
||||||
@ -12,11 +14,11 @@ export default function AppActions() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const goForward = () => {
|
const goForward = () => {
|
||||||
window.history.forward();
|
router.forward();
|
||||||
};
|
};
|
||||||
|
|
||||||
const reload = () => {
|
const reload = () => {
|
||||||
router.reload();
|
router.refresh();
|
||||||
};
|
};
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
|
@ -2,7 +2,7 @@ import { ImageWithFallback } from '@components/imageWithFallback';
|
|||||||
|
|
||||||
import { DEFAULT_AVATAR } from '@stores/constants';
|
import { DEFAULT_AVATAR } from '@stores/constants';
|
||||||
|
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/navigation';
|
||||||
import { useCallback } from 'react';
|
import { useCallback } from 'react';
|
||||||
|
|
||||||
export const BrowseChannelItem = ({ data }: { data: any }) => {
|
export const BrowseChannelItem = ({ data }: { data: any }) => {
|
||||||
@ -11,10 +11,7 @@ export const BrowseChannelItem = ({ data }: { data: any }) => {
|
|||||||
|
|
||||||
const openChannel = useCallback(
|
const openChannel = useCallback(
|
||||||
(id: string) => {
|
(id: string) => {
|
||||||
router.push({
|
router.push(`/channels/${id}`);
|
||||||
pathname: '/channels/[id]',
|
|
||||||
query: { id: id },
|
|
||||||
});
|
|
||||||
},
|
},
|
||||||
[router]
|
[router]
|
||||||
);
|
);
|
||||||
|
@ -2,17 +2,14 @@ import { ImageWithFallback } from '@components/imageWithFallback';
|
|||||||
|
|
||||||
import { DEFAULT_AVATAR } from '@stores/constants';
|
import { DEFAULT_AVATAR } from '@stores/constants';
|
||||||
|
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
export const ChannelListItem = ({ data }: { data: any }) => {
|
export const ChannelListItem = ({ data }: { data: any }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const channel = JSON.parse(data.content);
|
const channel = JSON.parse(data.content);
|
||||||
|
|
||||||
const openChannel = (id: string) => {
|
const openChannel = (id: string) => {
|
||||||
router.push({
|
router.push(`/channels/${id}`);
|
||||||
pathname: '/channels/[id]',
|
|
||||||
query: { id: id },
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -5,7 +5,7 @@ import { ImageWithFallback } from '@components/imageWithFallback';
|
|||||||
import { DEFAULT_AVATAR } from '@stores/constants';
|
import { DEFAULT_AVATAR } from '@stores/constants';
|
||||||
|
|
||||||
import useLocalStorage from '@rehooks/local-storage';
|
import useLocalStorage from '@rehooks/local-storage';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/navigation';
|
||||||
import { useEffect, useState } from 'react';
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
export default function ChatList() {
|
export default function ChatList() {
|
||||||
@ -16,10 +16,7 @@ export default function ChatList() {
|
|||||||
const profile = activeAccount.metadata ? JSON.parse(activeAccount.metadata) : null;
|
const profile = activeAccount.metadata ? JSON.parse(activeAccount.metadata) : null;
|
||||||
|
|
||||||
const openSelfChat = () => {
|
const openSelfChat = () => {
|
||||||
router.push({
|
router.push(`/chats/${activeAccount.pubkey}`);
|
||||||
pathname: '/chats/[pubkey]',
|
|
||||||
query: { pubkey: activeAccount.pubkey },
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
@ -5,17 +5,14 @@ import { DEFAULT_AVATAR } from '@stores/constants';
|
|||||||
import { useMetadata } from '@utils/metadata';
|
import { useMetadata } from '@utils/metadata';
|
||||||
import { truncate } from '@utils/truncate';
|
import { truncate } from '@utils/truncate';
|
||||||
|
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
export const ChatListItem = ({ pubkey }: { pubkey: string }) => {
|
export const ChatListItem = ({ pubkey }: { pubkey: string }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const profile = useMetadata(pubkey);
|
const profile = useMetadata(pubkey);
|
||||||
|
|
||||||
const openChat = () => {
|
const openChat = () => {
|
||||||
router.push({
|
router.push(`/chats/${pubkey}`);
|
||||||
pathname: '/chats/[pubkey]',
|
|
||||||
query: { pubkey: pubkey },
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -4,17 +4,14 @@ import { DEFAULT_AVATAR } from '@stores/constants';
|
|||||||
|
|
||||||
import { truncate } from '@utils/truncate';
|
import { truncate } from '@utils/truncate';
|
||||||
|
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/navigation';
|
||||||
|
|
||||||
export const ChatModalUser = ({ data }: { data: any }) => {
|
export const ChatModalUser = ({ data }: { data: any }) => {
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const profile = JSON.parse(data.metadata);
|
const profile = JSON.parse(data.metadata);
|
||||||
|
|
||||||
const openNewChat = () => {
|
const openNewChat = () => {
|
||||||
router.push({
|
router.push(`/chats/${data.pubkey}`);
|
||||||
pathname: '/chats/[pubkey]',
|
|
||||||
query: { pubkey: data.pubkey },
|
|
||||||
});
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import { NetworkStatusIndicator } from '@components/networkStatusIndicator';
|
import { NetworkStatusIndicator } from '@components/networkStatusIndicator';
|
||||||
import { RelayContext } from '@components/relaysProvider';
|
import { RelayContext } from '@components/relaysProvider';
|
||||||
|
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import { DEFAULT_AVATAR } from '@stores/constants';
|
import { DEFAULT_AVATAR } from '@stores/constants';
|
||||||
|
|
||||||
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
|
import * as DropdownMenu from '@radix-ui/react-dropdown-menu';
|
||||||
import { writeText } from '@tauri-apps/api/clipboard';
|
import { writeText } from '@tauri-apps/api/clipboard';
|
||||||
import { LogOut, ProfileCircle, Settings } from 'iconoir-react';
|
import { LogOut, ProfileCircle, Settings } from 'iconoir-react';
|
||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/navigation';
|
||||||
import { nip19 } from 'nostr-tools';
|
import { nip19 } from 'nostr-tools';
|
||||||
|
|
||||||
export const ActiveAccount = ({ user }: { user: any }) => {
|
export const ActiveAccount = ({ user }: { user: any }) => {
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import { ActiveAccount } from '@components/multiAccounts/activeAccount';
|
import { ActiveAccount } from '@components/multiAccounts/activeAccount';
|
||||||
import { InactiveAccount } from '@components/multiAccounts/inactiveAccount';
|
import { InactiveAccount } from '@components/multiAccounts/inactiveAccount';
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import ChannelList from '@components/channels/channelList';
|
import ChannelList from '@components/channels/channelList';
|
||||||
|
|
||||||
import * as Collapsible from '@radix-ui/react-collapsible';
|
import * as Collapsible from '@radix-ui/react-collapsible';
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import ChatList from '@components/chats/chatList';
|
import ChatList from '@components/chats/chatList';
|
||||||
|
|
||||||
import * as Collapsible from '@radix-ui/react-collapsible';
|
import * as Collapsible from '@radix-ui/react-collapsible';
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
import ActiveLink from '@components/activeLink';
|
'use client';
|
||||||
|
|
||||||
import * as Collapsible from '@radix-ui/react-collapsible';
|
import * as Collapsible from '@radix-ui/react-collapsible';
|
||||||
import { NavArrowUp } from 'iconoir-react';
|
import { NavArrowUp } from 'iconoir-react';
|
||||||
|
import Link from 'next/link';
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
|
|
||||||
export default function Newsfeed() {
|
export default function Newsfeed() {
|
||||||
@ -21,20 +22,20 @@ export default function Newsfeed() {
|
|||||||
<h3 className="text-[11px] font-bold uppercase tracking-widest text-zinc-600">Newsfeed</h3>
|
<h3 className="text-[11px] font-bold uppercase tracking-widest text-zinc-600">Newsfeed</h3>
|
||||||
</Collapsible.Trigger>
|
</Collapsible.Trigger>
|
||||||
<Collapsible.Content className="flex flex-col text-zinc-400">
|
<Collapsible.Content className="flex flex-col text-zinc-400">
|
||||||
<ActiveLink
|
<Link
|
||||||
href={`/newsfeed/following`}
|
href={`/newsfeed/following`}
|
||||||
activeClassName="dark:bg-zinc-900 dark:text-zinc-100 hover:dark:bg-zinc-800"
|
//activeClassName="dark:bg-zinc-900 dark:text-zinc-100 hover:dark:bg-zinc-800"
|
||||||
className="flex h-8 items-center gap-2.5 rounded-md px-2.5 text-sm font-medium hover:text-zinc-200"
|
className="flex h-8 items-center gap-2.5 rounded-md px-2.5 text-sm font-medium hover:text-zinc-200"
|
||||||
>
|
>
|
||||||
<span>Following</span>
|
<span>Following</span>
|
||||||
</ActiveLink>
|
</Link>
|
||||||
<ActiveLink
|
<Link
|
||||||
href={`/newsfeed/circle`}
|
href={`/newsfeed/circle`}
|
||||||
activeClassName="dark:bg-zinc-900 dark:text-zinc-100 hover:dark:bg-zinc-800"
|
//activeClassName="dark:bg-zinc-900 dark:text-zinc-100 hover:dark:bg-zinc-800"
|
||||||
className="flex h-8 items-center gap-2.5 rounded-md px-2.5 text-sm font-medium hover:text-zinc-200"
|
className="flex h-8 items-center gap-2.5 rounded-md px-2.5 text-sm font-medium hover:text-zinc-200"
|
||||||
>
|
>
|
||||||
<span>Circle</span>
|
<span>Circle</span>
|
||||||
</ActiveLink>
|
</Link>
|
||||||
</Collapsible.Content>
|
</Collapsible.Content>
|
||||||
</div>
|
</div>
|
||||||
</Collapsible.Root>
|
</Collapsible.Root>
|
||||||
|
@ -7,7 +7,7 @@ import { UserExtend } from '@components/user/extend';
|
|||||||
import { UserMention } from '@components/user/mention';
|
import { UserMention } from '@components/user/mention';
|
||||||
|
|
||||||
import destr from 'destr';
|
import destr from 'destr';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/navigation';
|
||||||
import { memo, useMemo } from 'react';
|
import { memo, useMemo } from 'react';
|
||||||
import reactStringReplace from 'react-string-replace';
|
import reactStringReplace from 'react-string-replace';
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ import { dateToUnix } from '@utils/getDate';
|
|||||||
import * as Dialog from '@radix-ui/react-dialog';
|
import * as Dialog from '@radix-ui/react-dialog';
|
||||||
import useLocalStorage from '@rehooks/local-storage';
|
import useLocalStorage from '@rehooks/local-storage';
|
||||||
import { MultiBubble, OpenNewWindow } from 'iconoir-react';
|
import { MultiBubble, OpenNewWindow } from 'iconoir-react';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/navigation';
|
||||||
import { getEventHash, signEvent } from 'nostr-tools';
|
import { getEventHash, signEvent } from 'nostr-tools';
|
||||||
import { memo, useContext, useState } from 'react';
|
import { memo, useContext, useState } from 'react';
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import { RelayContext } from '@components/relaysProvider';
|
import { RelayContext } from '@components/relaysProvider';
|
||||||
import { UserFollow } from '@components/user/follow';
|
import { UserFollow } from '@components/user/follow';
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import { RelayContext } from '@components/relaysProvider';
|
import { RelayContext } from '@components/relaysProvider';
|
||||||
import { UserFollow } from '@components/user/follow';
|
import { UserFollow } from '@components/user/follow';
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import { ImageWithFallback } from '@components/imageWithFallback';
|
import { ImageWithFallback } from '@components/imageWithFallback';
|
||||||
import { RelayContext } from '@components/relaysProvider';
|
import { RelayContext } from '@components/relaysProvider';
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import { NoteBase } from '@components/note/base';
|
import { NoteBase } from '@components/note/base';
|
||||||
import { RelayContext } from '@components/relaysProvider';
|
import { RelayContext } from '@components/relaysProvider';
|
||||||
|
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
import { RelayPool } from 'nostr-relaypool';
|
import { RelayPool } from 'nostr-relaypool';
|
||||||
import { createContext, useMemo } from 'react';
|
import { createContext, useMemo } from 'react';
|
||||||
|
|
||||||
|
@ -1,3 +0,0 @@
|
|||||||
export default function BaseLayout({ children }: { children: React.ReactNode }) {
|
|
||||||
return <div className="h-screen w-screen bg-zinc-50 text-zinc-900 dark:bg-black dark:text-white">{children}</div>;
|
|
||||||
}
|
|
@ -1,37 +0,0 @@
|
|||||||
import AppHeader from '@components/appHeader';
|
|
||||||
import MultiAccounts from '@components/multiAccounts';
|
|
||||||
import Navigation from '@components/navigation';
|
|
||||||
|
|
||||||
export default function WithSidebarLayout({ children }: { children: React.ReactNode }) {
|
|
||||||
return (
|
|
||||||
<div className="flex h-screen w-full flex-col">
|
|
||||||
<div
|
|
||||||
data-tauri-drag-region
|
|
||||||
className="relative h-11 shrink-0 border-b border-zinc-100 bg-white dark:border-zinc-900 dark:bg-black"
|
|
||||||
>
|
|
||||||
<AppHeader />
|
|
||||||
</div>
|
|
||||||
<div className="relative flex min-h-0 w-full flex-1">
|
|
||||||
<div className="relative w-[68px] shrink-0 border-r border-zinc-900">
|
|
||||||
<MultiAccounts />
|
|
||||||
</div>
|
|
||||||
<div className="grid w-full grid-cols-4 xl:grid-cols-5">
|
|
||||||
<div className="scrollbar-hide col-span-1 overflow-y-auto overflow-x-hidden border-r border-zinc-900">
|
|
||||||
<Navigation />
|
|
||||||
</div>
|
|
||||||
<div className="col-span-3 m-3 overflow-hidden rounded-lg border border-zinc-800 bg-zinc-900 shadow-input shadow-black/20 xl:col-span-2 xl:mr-1.5">
|
|
||||||
<div className="h-full w-full rounded-lg">{children}</div>
|
|
||||||
</div>
|
|
||||||
<div className="col-span-3 m-3 hidden overflow-hidden rounded-lg border border-zinc-800 bg-zinc-900 shadow-input shadow-black/20 xl:col-span-2 xl:ml-1.5 xl:flex">
|
|
||||||
<div className="flex h-full w-full items-center justify-center">
|
|
||||||
<p className="select-text p-8 text-center text-zinc-400">
|
|
||||||
This feature hasn't implemented yet, so resize Lume to the initial size for a better experience.
|
|
||||||
I'm sorry for this inconvenience, and I swear I will add it soon 😁
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,25 +0,0 @@
|
|||||||
import RelayProvider from '@components/relaysProvider';
|
|
||||||
|
|
||||||
import type { NextPage } from 'next';
|
|
||||||
import type { AppProps } from 'next/app';
|
|
||||||
import { useRouter } from 'next/router';
|
|
||||||
import { ReactElement, ReactNode } from 'react';
|
|
||||||
|
|
||||||
import '../App.css';
|
|
||||||
|
|
||||||
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
||||||
export type NextPageWithLayout<P = {}, IP = P> = NextPage<P, IP> & {
|
|
||||||
getLayout?: (page: ReactElement) => ReactNode;
|
|
||||||
};
|
|
||||||
|
|
||||||
type AppPropsWithLayout = AppProps & {
|
|
||||||
Component: NextPageWithLayout;
|
|
||||||
};
|
|
||||||
|
|
||||||
export default function MyApp({ Component, pageProps }: AppPropsWithLayout) {
|
|
||||||
const router = useRouter();
|
|
||||||
// Use the layout defined at the page level, if available
|
|
||||||
const getLayout = Component.getLayout ?? ((page) => page);
|
|
||||||
|
|
||||||
return <RelayProvider>{getLayout(<Component key={router.asPath} {...pageProps} />)}</RelayProvider>;
|
|
||||||
}
|
|
@ -1,13 +0,0 @@
|
|||||||
import { Head, Html, Main, NextScript } from 'next/document';
|
|
||||||
|
|
||||||
export default function Document() {
|
|
||||||
return (
|
|
||||||
<Html>
|
|
||||||
<Head />
|
|
||||||
<body className="cursor-default select-none overflow-hidden font-sans antialiased">
|
|
||||||
<Main />
|
|
||||||
<NextScript />
|
|
||||||
</body>
|
|
||||||
</Html>
|
|
||||||
);
|
|
||||||
}
|
|
@ -1,24 +0,0 @@
|
|||||||
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<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<BaseLayout>
|
|
||||||
<WithSidebarLayout>{page}</WithSidebarLayout>
|
|
||||||
</BaseLayout>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,24 +0,0 @@
|
|||||||
import BaseLayout from '@layouts/base';
|
|
||||||
import WithSidebarLayout from '@layouts/withSidebar';
|
|
||||||
|
|
||||||
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal } from 'react';
|
|
||||||
|
|
||||||
export default function Page() {
|
|
||||||
return <div className="scrollbar-hide flex h-full flex-col gap-2 overflow-y-auto py-3"></div>;
|
|
||||||
}
|
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
|
||||||
page:
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<BaseLayout>
|
|
||||||
<WithSidebarLayout>{page}</WithSidebarLayout>
|
|
||||||
</BaseLayout>
|
|
||||||
);
|
|
||||||
};
|
|
@ -1,28 +0,0 @@
|
|||||||
import BaseLayout from '@layouts/base';
|
|
||||||
import WithSidebarLayout from '@layouts/withSidebar';
|
|
||||||
|
|
||||||
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal } from 'react';
|
|
||||||
|
|
||||||
export default function Page() {
|
|
||||||
return (
|
|
||||||
<div className="flex h-full w-full items-center justify-center">
|
|
||||||
<p className="text-sm text-zinc-400">Sorry, this feature under development, it will come in the next version</p>
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
|
||||||
page:
|
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
|
||||||
return (
|
|
||||||
<BaseLayout>
|
|
||||||
<WithSidebarLayout>{page}</WithSidebarLayout>
|
|
||||||
</BaseLayout>
|
|
||||||
);
|
|
||||||
};
|
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
content: ['./src/**/*.{js,ts,jsx,tsx}'],
|
content: ['./src/**/*.{js,ts,jsx,tsx}'],
|
||||||
|
darkMode: 'class',
|
||||||
theme: {
|
theme: {
|
||||||
extend: {
|
extend: {
|
||||||
boxShadow: {
|
boxShadow: {
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
"compilerOptions": {
|
"compilerOptions": {
|
||||||
"baseUrl": "./",
|
"baseUrl": "./",
|
||||||
"paths": {
|
"paths": {
|
||||||
"@pages/*": ["src/pages/*"],
|
"@app/*": ["src/app/*"],
|
||||||
"@layouts/*": ["src/layouts/*"],
|
|
||||||
"@components/*": ["src/components/*"],
|
"@components/*": ["src/components/*"],
|
||||||
"@stores/*": ["src/stores/*"],
|
"@stores/*": ["src/stores/*"],
|
||||||
"@utils/*": ["src/utils/*"],
|
"@utils/*": ["src/utils/*"],
|
||||||
@ -27,7 +26,8 @@
|
|||||||
{
|
{
|
||||||
"name": "next"
|
"name": "next"
|
||||||
}
|
}
|
||||||
]
|
],
|
||||||
|
"strictNullChecks": false
|
||||||
},
|
},
|
||||||
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
|
||||||
"exclude": ["node_modules"]
|
"exclude": ["node_modules"]
|
||||||
|
Loading…
Reference in New Issue
Block a user