mirror of
https://github.com/luminous-devs/lume.git
synced 2024-09-18 11:13:30 +00:00
updated prettier config & run linted
This commit is contained in:
parent
416243706c
commit
63dbfba391
@ -5,7 +5,7 @@
|
|||||||
"next/core-web-vitals",
|
"next/core-web-vitals",
|
||||||
"plugin:react/recommended",
|
"plugin:react/recommended",
|
||||||
"plugin:react/jsx-runtime",
|
"plugin:react/jsx-runtime",
|
||||||
"plugin:react-hooks/recommended",
|
"plugin:react-hooks/recommended",
|
||||||
"plugin:@typescript-eslint/recommended",
|
"plugin:@typescript-eslint/recommended",
|
||||||
"prettier"
|
"prettier"
|
||||||
],
|
],
|
||||||
|
13
.prettierrc
13
.prettierrc
@ -3,12 +3,19 @@
|
|||||||
"trailingComma": "es5",
|
"trailingComma": "es5",
|
||||||
"singleQuote": true,
|
"singleQuote": true,
|
||||||
"tabWidth": 2,
|
"tabWidth": 2,
|
||||||
"printWidth": 150,
|
"printWidth": 120,
|
||||||
"useTabs": false,
|
"useTabs": false,
|
||||||
"endOfLine": "lf",
|
"endOfLine": "lf",
|
||||||
"bracketSpacing": true,
|
"bracketSpacing": true,
|
||||||
"bracketSameLine": true,
|
"bracketSameLine": false,
|
||||||
"importOrder": ["^@layouts/(.*)$", "^@pages/(.*)$", "^@components/(.*)$", "^@utils/(.*)$", "^@stores/(.*)$", "<THIRD_PARTY_MODULES>", "^[./]"],
|
"importOrder": [
|
||||||
|
"^@layouts/(.*)$",
|
||||||
|
"^@pages/(.*)$",
|
||||||
|
"^@components/(.*)$",
|
||||||
|
"^@utils/(.*)$",
|
||||||
|
"<THIRD_PARTY_MODULES>",
|
||||||
|
"^[./]"
|
||||||
|
],
|
||||||
"importOrderSeparation": true,
|
"importOrderSeparation": true,
|
||||||
"importOrderSortSpecifiers": true,
|
"importOrderSortSpecifiers": true,
|
||||||
"plugins": ["@trivago/prettier-plugin-sort-imports", "prettier-plugin-tailwindcss"],
|
"plugins": ["@trivago/prettier-plugin-sort-imports", "prettier-plugin-tailwindcss"],
|
||||||
|
12
package.json
12
package.json
@ -24,14 +24,14 @@
|
|||||||
"framer-motion": "^9.1.7",
|
"framer-motion": "^9.1.7",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"nanostores": "^0.7.4",
|
"nanostores": "^0.7.4",
|
||||||
"next": "^13.2.1",
|
"next": "^13.2.3",
|
||||||
"next-remove-imports": "^1.0.10",
|
"next-remove-imports": "^1.0.10",
|
||||||
"nostr-relaypool": "^0.5.3",
|
"nostr-relaypool": "^0.5.3",
|
||||||
"nostr-tools": "^1.7.1",
|
"nostr-tools": "^1.7.4",
|
||||||
"qrcode.react": "^3.1.0",
|
"qrcode.react": "^3.1.0",
|
||||||
"react": "^18.2.0",
|
"react": "^18.2.0",
|
||||||
"react-dom": "^18.2.0",
|
"react-dom": "^18.2.0",
|
||||||
"react-hook-form": "^7.43.2",
|
"react-hook-form": "^7.43.4",
|
||||||
"react-moment": "^1.1.3",
|
"react-moment": "^1.1.3",
|
||||||
"react-player": "^2.11.2",
|
"react-player": "^2.11.2",
|
||||||
"react-virtuoso": "^4.1.0",
|
"react-virtuoso": "^4.1.0",
|
||||||
@ -43,7 +43,7 @@
|
|||||||
"@tailwindcss/typography": "^0.5.9",
|
"@tailwindcss/typography": "^0.5.9",
|
||||||
"@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.14.2",
|
"@types/node": "^18.14.6",
|
||||||
"@types/react": "^18.0.28",
|
"@types/react": "^18.0.28",
|
||||||
"@types/react-dom": "^18.0.11",
|
"@types/react-dom": "^18.0.11",
|
||||||
"@typescript-eslint/eslint-plugin": "^5.54.0",
|
"@typescript-eslint/eslint-plugin": "^5.54.0",
|
||||||
@ -51,7 +51,7 @@
|
|||||||
"autoprefixer": "^10.4.13",
|
"autoprefixer": "^10.4.13",
|
||||||
"csstype": "^3.1.1",
|
"csstype": "^3.1.1",
|
||||||
"eslint": "^8.35.0",
|
"eslint": "^8.35.0",
|
||||||
"eslint-config-next": "^13.2.1",
|
"eslint-config-next": "^13.2.3",
|
||||||
"eslint-config-prettier": "^8.6.0",
|
"eslint-config-prettier": "^8.6.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",
|
||||||
@ -59,7 +59,7 @@
|
|||||||
"lint-staged": "^13.1.2",
|
"lint-staged": "^13.1.2",
|
||||||
"postcss": "^8.4.21",
|
"postcss": "^8.4.21",
|
||||||
"prettier": "^2.8.4",
|
"prettier": "^2.8.4",
|
||||||
"prettier-plugin-tailwindcss": "^0.2.3",
|
"prettier-plugin-tailwindcss": "^0.2.4",
|
||||||
"prop-types": "^15.8.1",
|
"prop-types": "^15.8.1",
|
||||||
"tailwindcss": "^3.2.7",
|
"tailwindcss": "^3.2.7",
|
||||||
"typescript": "^4.9.5"
|
"typescript": "^4.9.5"
|
||||||
|
2166
pnpm-lock.yaml
2166
pnpm-lock.yaml
File diff suppressed because it is too large
Load Diff
@ -145,8 +145,8 @@
|
|||||||
.w-md-editor-toolbar-child {
|
.w-md-editor-toolbar-child {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
border-radius: 3px;
|
border-radius: 3px;
|
||||||
box-shadow: 0 0 0 1px var(--color-border-default),
|
box-shadow: 0 0 0 1px var(--color-border-default), 0 0 0 var(--color-border-default),
|
||||||
0 0 0 var(--color-border-default), 0 1px 1px var(--color-border-default);
|
0 1px 1px var(--color-border-default);
|
||||||
background-color: var(--color-canvas-default);
|
background-color: var(--color-canvas-default);
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -14,7 +14,8 @@ export const Account = memo(function Account({ user, current }: { user: any; cur
|
|||||||
onClick={() => setCurrentUser()}
|
onClick={() => setCurrentUser()}
|
||||||
className={`relative h-11 w-11 shrink overflow-hidden rounded-full ${
|
className={`relative h-11 w-11 shrink overflow-hidden rounded-full ${
|
||||||
current === user.pubkey ? 'ring-1 ring-fuchsia-500 ring-offset-4 ring-offset-black' : ''
|
current === user.pubkey ? 'ring-1 ring-fuchsia-500 ring-offset-4 ring-offset-black' : ''
|
||||||
}`}>
|
}`}
|
||||||
|
>
|
||||||
{userData?.picture !== undefined ? (
|
{userData?.picture !== undefined ? (
|
||||||
<Image src={userData.picture} alt="user's avatar" fill={true} className="rounded-full object-cover" />
|
<Image src={userData.picture} alt="user's avatar" fill={true} className="rounded-full object-cover" />
|
||||||
) : (
|
) : (
|
||||||
|
@ -31,7 +31,8 @@ export default function AccountBar() {
|
|||||||
))}
|
))}
|
||||||
<Link
|
<Link
|
||||||
href="/onboarding"
|
href="/onboarding"
|
||||||
className="group relative flex h-11 w-11 shrink cursor-pointer items-center justify-center overflow-hidden rounded-full border-2 border-dashed border-zinc-600 hover:border-zinc-400">
|
className="group relative flex h-11 w-11 shrink cursor-pointer items-center justify-center overflow-hidden rounded-full border-2 border-dashed border-zinc-600 hover:border-zinc-400"
|
||||||
|
>
|
||||||
<PlusIcon className="h-4 w-4 text-zinc-400 group-hover:text-zinc-200" />
|
<PlusIcon className="h-4 w-4 text-zinc-400 group-hover:text-zinc-200" />
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
|
@ -7,12 +7,7 @@ type ActiveLinkProps = LinkProps & {
|
|||||||
activeClassName: string;
|
activeClassName: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
const ActiveLink = ({
|
const ActiveLink = ({ children, activeClassName, className, ...props }: PropsWithChildren<ActiveLinkProps>) => {
|
||||||
children,
|
|
||||||
activeClassName,
|
|
||||||
className,
|
|
||||||
...props
|
|
||||||
}: PropsWithChildren<ActiveLinkProps>) => {
|
|
||||||
const { asPath, isReady } = useRouter();
|
const { asPath, isReady } = useRouter();
|
||||||
const [computedClassName, setComputedClassName] = useState(className);
|
const [computedClassName, setComputedClassName] = useState(className);
|
||||||
|
|
||||||
@ -26,8 +21,7 @@ const ActiveLink = ({
|
|||||||
// Using URL().pathname to get rid of query and hash
|
// Using URL().pathname to get rid of query and hash
|
||||||
const activePathname = new URL(asPath, location.href).pathname;
|
const activePathname = new URL(asPath, location.href).pathname;
|
||||||
|
|
||||||
const newClassName =
|
const newClassName = linkPathname === activePathname ? `${className} ${activeClassName}`.trim() : className;
|
||||||
linkPathname === activePathname ? `${className} ${activeClassName}`.trim() : className;
|
|
||||||
|
|
||||||
if (newClassName !== computedClassName) {
|
if (newClassName !== computedClassName) {
|
||||||
setComputedClassName(newClassName);
|
setComputedClassName(newClassName);
|
||||||
|
@ -29,19 +29,19 @@ export default function Empty() {
|
|||||||
fill="none"
|
fill="none"
|
||||||
stroke="currentColor"
|
stroke="currentColor"
|
||||||
viewBox="0 0 48 48"
|
viewBox="0 0 48 48"
|
||||||
aria-hidden="true">
|
aria-hidden="true"
|
||||||
|
>
|
||||||
<path
|
<path
|
||||||
strokeLinecap="round"
|
strokeLinecap="round"
|
||||||
strokeLinejoin="round"
|
strokeLinejoin="round"
|
||||||
strokeWidth={2}
|
strokeWidth={2}
|
||||||
d="M34 40h10v-4a6 6 0 00-10.712-3.714M34 40H14m20 0v-4a9.971 9.971 0 00-.712-3.714M14 40H4v-4a6 6 0 0110.713-3.714M14 40v-4c0-1.313.253-2.566.713-3.714m0 0A10.003 10.003 0 0124 26c4.21 0 7.813 2.602 9.288 6.286M30 14a6 6 0 11-12 0 6 6 0 0112 0zm12 6a4 4 0 11-8 0 4 4 0 018 0zm-28 0a4 4 0 11-8 0 4 4 0 018 0z"></path>
|
d="M34 40h10v-4a6 6 0 00-10.712-3.714M34 40H14m20 0v-4a9.971 9.971 0 00-.712-3.714M14 40H4v-4a6 6 0 0110.713-3.714M14 40v-4c0-1.313.253-2.566.713-3.714m0 0A10.003 10.003 0 0124 26c4.21 0 7.813 2.602 9.288 6.286M30 14a6 6 0 11-12 0 6 6 0 0112 0zm12 6a4 4 0 11-8 0 4 4 0 018 0zm-28 0a4 4 0 11-8 0 4 4 0 018 0z"
|
||||||
|
></path>
|
||||||
</svg>
|
</svg>
|
||||||
<h2 className="mt-2 text-lg font-medium text-zinc-100">
|
<h2 className="mt-2 text-lg font-medium text-zinc-100">You haven't followed anyone yet</h2>
|
||||||
You haven't followed anyone yet
|
|
||||||
</h2>
|
|
||||||
<p className="mt-1 text-sm text-zinc-500">
|
<p className="mt-1 text-sm text-zinc-500">
|
||||||
You can send invite via email to your friend and lume will onboard them into nostr or
|
You can send invite via email to your friend and lume will onboard them into nostr or follow some people in
|
||||||
follow some people in suggested below
|
suggested below
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<form action="#" className="relative mt-6">
|
<form action="#" className="relative mt-6">
|
||||||
@ -68,12 +68,7 @@ export default function Empty() {
|
|||||||
<li key={index} className="flex items-center justify-between space-x-3 py-4">
|
<li key={index} className="flex items-center justify-between space-x-3 py-4">
|
||||||
<div className="flex min-w-0 flex-1 items-center space-x-3">
|
<div className="flex min-w-0 flex-1 items-center space-x-3">
|
||||||
<div className="relative h-10 w-10 flex-shrink-0">
|
<div className="relative h-10 w-10 flex-shrink-0">
|
||||||
<Image
|
<Image className="rounded-full object-cover" src={person.imageUrl} alt={person.name} fill={true} />
|
||||||
className="rounded-full object-cover"
|
|
||||||
src={person.imageUrl}
|
|
||||||
alt={person.name}
|
|
||||||
fill={true}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="min-w-0 flex-1">
|
<div className="min-w-0 flex-1">
|
||||||
<p className="truncate text-sm font-medium text-zinc-200">{person.name}</p>
|
<p className="truncate text-sm font-medium text-zinc-200">{person.name}</p>
|
||||||
@ -83,7 +78,8 @@ export default function Empty() {
|
|||||||
<div className="flex-shrink-0">
|
<div className="flex-shrink-0">
|
||||||
<button
|
<button
|
||||||
type="button"
|
type="button"
|
||||||
className="inline-flex items-center rounded-full border border-zinc-700 bg-zinc-800 px-3 py-1 text-xs font-medium text-zinc-400 shadow-sm hover:bg-zinc-800 focus:outline-none focus:ring-2 focus:ring-fuchsia-600 focus:ring-offset-2">
|
className="inline-flex items-center rounded-full border border-zinc-700 bg-zinc-800 px-3 py-1 text-xs font-medium text-zinc-400 shadow-sm hover:bg-zinc-800 focus:outline-none focus:ring-2 focus:ring-fuchsia-600 focus:ring-offset-2"
|
||||||
|
>
|
||||||
<PlusIcon className="-ml-1 h-5 w-5" />
|
<PlusIcon className="-ml-1 h-5 w-5" />
|
||||||
<span className="text-sm font-medium text-zinc-300">Follow</span>
|
<span className="text-sm font-medium text-zinc-300">Follow</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -30,7 +30,9 @@ export default function CreatePost() {
|
|||||||
buttonProps: { className: 'cta-btn', 'aria-label': 'Post a message' },
|
buttonProps: { className: 'cta-btn', 'aria-label': 'Post a message' },
|
||||||
icon: (
|
icon: (
|
||||||
<div className="relative inline-flex h-10 w-16 transform cursor-pointer overflow-hidden rounded bg-zinc-900 px-2.5 ring-zinc-500/50 ring-offset-zinc-900 will-change-transform focus:outline-none focus:ring-1 focus:ring-offset-2 active:translate-y-1">
|
<div className="relative inline-flex h-10 w-16 transform cursor-pointer overflow-hidden rounded bg-zinc-900 px-2.5 ring-zinc-500/50 ring-offset-zinc-900 will-change-transform focus:outline-none focus:ring-1 focus:ring-offset-2 active:translate-y-1">
|
||||||
<span className="absolute inset-px z-10 inline-flex items-center justify-center rounded bg-zinc-900 text-zinc-200">Post</span>
|
<span className="absolute inset-px z-10 inline-flex items-center justify-center rounded bg-zinc-900 text-zinc-200">
|
||||||
|
Post
|
||||||
|
</span>
|
||||||
<span className="absolute inset-0 z-0 scale-x-[2.0] blur before:absolute before:inset-0 before:top-1/2 before:aspect-square before:animate-disco before:bg-gradient-conic before:from-gray-300 before:via-fuchsia-600 before:to-orange-600"></span>
|
<span className="absolute inset-0 z-0 scale-x-[2.0] blur before:absolute before:inset-0 before:top-1/2 before:aspect-square before:animate-disco before:bg-gradient-conic before:from-gray-300 before:via-fuchsia-600 before:to-orange-600"></span>
|
||||||
</div>
|
</div>
|
||||||
),
|
),
|
||||||
|
@ -30,7 +30,10 @@ export default function NavigatorBar() {
|
|||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<div className="flex items-center justify-between px-2">
|
<div className="flex items-center justify-between px-2">
|
||||||
<h3 className="text-sm font-bold text-zinc-400">Newsfeed</h3>
|
<h3 className="text-sm font-bold text-zinc-400">Newsfeed</h3>
|
||||||
<button type="button" className="group flex h-6 w-6 items-center justify-center rounded-full hover:bg-zinc-900">
|
<button
|
||||||
|
type="button"
|
||||||
|
className="group flex h-6 w-6 items-center justify-center rounded-full hover:bg-zinc-900"
|
||||||
|
>
|
||||||
<PlusIcon className="h-3 w-3 text-zinc-400 group-hover:text-zinc-100" />
|
<PlusIcon className="h-3 w-3 text-zinc-400 group-hover:text-zinc-100" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -38,14 +41,16 @@ export default function NavigatorBar() {
|
|||||||
<ActiveLink
|
<ActiveLink
|
||||||
href={`/feed/following`}
|
href={`/feed/following`}
|
||||||
activeClassName="ring-1 ring-white/10 dark:bg-zinc-900 dark:text-white"
|
activeClassName="ring-1 ring-white/10 dark:bg-zinc-900 dark:text-white"
|
||||||
className="flex h-10 items-center gap-1 rounded-lg px-2.5 text-sm font-medium hover:bg-zinc-900">
|
className="flex h-10 items-center gap-1 rounded-lg px-2.5 text-sm font-medium hover:bg-zinc-900"
|
||||||
|
>
|
||||||
<span>#</span>
|
<span>#</span>
|
||||||
<span>following</span>
|
<span>following</span>
|
||||||
</ActiveLink>
|
</ActiveLink>
|
||||||
<ActiveLink
|
<ActiveLink
|
||||||
href={`/feed/global`}
|
href={`/feed/global`}
|
||||||
activeClassName="ring-1 ring-white/10 dark:bg-zinc-900 dark:text-white"
|
activeClassName="ring-1 ring-white/10 dark:bg-zinc-900 dark:text-white"
|
||||||
className="flex h-10 items-center gap-1 rounded-lg px-2.5 text-sm font-medium hover:bg-zinc-900">
|
className="flex h-10 items-center gap-1 rounded-lg px-2.5 text-sm font-medium hover:bg-zinc-900"
|
||||||
|
>
|
||||||
<span>#</span>
|
<span>#</span>
|
||||||
<span>global</span>
|
<span>global</span>
|
||||||
</ActiveLink>
|
</ActiveLink>
|
||||||
@ -55,7 +60,10 @@ export default function NavigatorBar() {
|
|||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
<div className="flex items-center justify-between px-2">
|
<div className="flex items-center justify-between px-2">
|
||||||
<h3 className="text-sm font-bold text-zinc-400">Direct Messages</h3>
|
<h3 className="text-sm font-bold text-zinc-400">Direct Messages</h3>
|
||||||
<button type="button" className="group flex h-6 w-6 items-center justify-center rounded-full hover:bg-zinc-900">
|
<button
|
||||||
|
type="button"
|
||||||
|
className="group flex h-6 w-6 items-center justify-center rounded-full hover:bg-zinc-900"
|
||||||
|
>
|
||||||
<PlusIcon className="h-3 w-3 text-zinc-400 group-hover:text-zinc-100" />
|
<PlusIcon className="h-3 w-3 text-zinc-400 group-hover:text-zinc-100" />
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
|
@ -31,20 +31,24 @@ export const ProfileMenu = memo(function ProfileMenu({ pubkey }: { pubkey: strin
|
|||||||
<DropdownMenu.Portal>
|
<DropdownMenu.Portal>
|
||||||
<DropdownMenu.Content
|
<DropdownMenu.Content
|
||||||
className="min-w-[220px] rounded-md border border-white/20 bg-zinc-800 p-1 shadow-lg shadow-black/30 will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade"
|
className="min-w-[220px] rounded-md border border-white/20 bg-zinc-800 p-1 shadow-lg shadow-black/30 will-change-[opacity,transform] data-[side=top]:animate-slideDownAndFade data-[side=right]:animate-slideLeftAndFade data-[side=bottom]:animate-slideUpAndFade data-[side=left]:animate-slideRightAndFade"
|
||||||
sideOffset={2}>
|
sideOffset={2}
|
||||||
|
>
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
onClick={() => viewProfile()}
|
onClick={() => viewProfile()}
|
||||||
className="group relative flex h-[30px] select-none items-center rounded px-1 pl-6 text-sm leading-none text-zinc-100 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-400 data-[disabled]:text-zinc-400">
|
className="group relative flex h-[30px] select-none items-center rounded px-1 pl-6 text-sm leading-none text-zinc-100 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-400 data-[disabled]:text-zinc-400"
|
||||||
|
>
|
||||||
View profile
|
View profile
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
onClick={() => updateProfile()}
|
onClick={() => updateProfile()}
|
||||||
className="group relative flex h-[30px] select-none items-center rounded px-1 pl-6 text-sm leading-none text-zinc-100 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-400 data-[disabled]:text-zinc-400">
|
className="group relative flex h-[30px] select-none items-center rounded px-1 pl-6 text-sm leading-none text-zinc-100 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-400 data-[disabled]:text-zinc-400"
|
||||||
|
>
|
||||||
Update profile
|
Update profile
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
<DropdownMenu.Item
|
<DropdownMenu.Item
|
||||||
onClick={() => copyPubkey()}
|
onClick={() => copyPubkey()}
|
||||||
className="group relative flex h-[30px] select-none items-center rounded px-1 pl-6 text-sm leading-none text-zinc-100 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-400 data-[disabled]:text-zinc-400">
|
className="group relative flex h-[30px] select-none items-center rounded px-1 pl-6 text-sm leading-none text-zinc-100 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-400 data-[disabled]:text-zinc-400"
|
||||||
|
>
|
||||||
Copy public key
|
Copy public key
|
||||||
</DropdownMenu.Item>
|
</DropdownMenu.Item>
|
||||||
<DropdownMenu.Item className="group relative flex h-[30px] select-none items-center rounded px-1 pl-6 text-sm leading-none text-zinc-100 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-400 data-[disabled]:text-zinc-400">
|
<DropdownMenu.Item className="group relative flex h-[30px] select-none items-center rounded px-1 pl-6 text-sm leading-none text-zinc-100 outline-none data-[disabled]:pointer-events-none data-[highlighted]:bg-zinc-700 data-[highlighted]:text-fuchsia-400 data-[disabled]:text-zinc-400">
|
||||||
|
@ -67,7 +67,11 @@ export default function Reaction({ eventID, eventPubkey }: { eventID: string; ev
|
|||||||
return (
|
return (
|
||||||
<button onClick={(e) => handleReaction(e)} className="group flex w-16 items-center gap-1.5 text-sm text-zinc-500">
|
<button onClick={(e) => handleReaction(e)} className="group flex w-16 items-center gap-1.5 text-sm text-zinc-500">
|
||||||
<div className="rounded-lg p-1 group-hover:bg-zinc-600">
|
<div className="rounded-lg p-1 group-hover:bg-zinc-600">
|
||||||
{isReact ? <HeartFilledIcon className="h-4 w-4 group-hover:text-red-400" /> : <HeartIcon className="h-4 w-4 text-zinc-500" />}
|
{isReact ? (
|
||||||
|
<HeartFilledIcon className="h-4 w-4 group-hover:text-red-400" />
|
||||||
|
) : (
|
||||||
|
<HeartIcon className="h-4 w-4 text-zinc-500" />
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
<span>{reaction}</span>
|
<span>{reaction}</span>
|
||||||
</button>
|
</button>
|
||||||
|
@ -17,7 +17,9 @@ export const User = memo(function User({ pubkey, time }: { pubkey: string; time:
|
|||||||
async (event) => {
|
async (event) => {
|
||||||
const metadata: any = JSON.parse(event.content);
|
const metadata: any = JSON.parse(event.content);
|
||||||
|
|
||||||
await db.execute(`INSERT OR IGNORE INTO cache_profiles (id, metadata) VALUES ("${pubkey}", '${JSON.stringify(metadata)}')`);
|
await db.execute(
|
||||||
|
`INSERT OR IGNORE INTO cache_profiles (id, metadata) VALUES ("${pubkey}", '${JSON.stringify(metadata)}')`
|
||||||
|
);
|
||||||
setProfile(metadata);
|
setProfile(metadata);
|
||||||
},
|
},
|
||||||
[db, pubkey]
|
[db, pubkey]
|
||||||
@ -53,13 +55,20 @@ export const User = memo(function User({ pubkey, time }: { pubkey: string; time:
|
|||||||
{profile.picture ? (
|
{profile.picture ? (
|
||||||
<ImageWithFallback src={profile.picture} alt={pubkey} fill={true} className="rounded-full object-cover" />
|
<ImageWithFallback src={profile.picture} alt={pubkey} fill={true} className="rounded-full object-cover" />
|
||||||
) : (
|
) : (
|
||||||
<Avatar size={44} name={pubkey} variant="beam" colors={['#FEE2E2', '#FEF3C7', '#F59E0B', '#EC4899', '#D946EF', '#8B5CF6']} />
|
<Avatar
|
||||||
|
size={44}
|
||||||
|
name={pubkey}
|
||||||
|
variant="beam"
|
||||||
|
colors={['#FEE2E2', '#FEF3C7', '#F59E0B', '#EC4899', '#D946EF', '#8B5CF6']}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex w-full flex-1 items-start justify-between">
|
<div className="flex w-full flex-1 items-start justify-between">
|
||||||
<div className="flex w-full justify-between">
|
<div className="flex w-full justify-between">
|
||||||
<div className="flex items-baseline gap-2 text-sm">
|
<div className="flex items-baseline gap-2 text-sm">
|
||||||
<span className="font-bold leading-tight">{profile.name ? profile.name : truncate(pubkey, 16, ' .... ')}</span>
|
<span className="font-bold leading-tight">
|
||||||
|
{profile.name ? profile.name : truncate(pubkey, 16, ' .... ')}
|
||||||
|
</span>
|
||||||
<span className="leading-tight text-zinc-500">·</span>
|
<span className="leading-tight text-zinc-500">·</span>
|
||||||
<Moment fromNow unix className="text-zinc-500">
|
<Moment fromNow unix className="text-zinc-500">
|
||||||
{time}
|
{time}
|
||||||
|
@ -25,14 +25,23 @@ export const UserWithUsername = memo(function UserWithUsername({ pubkey }: { pub
|
|||||||
{profile.picture ? (
|
{profile.picture ? (
|
||||||
<ImageWithFallback src={profile.picture} alt={pubkey} fill={true} className="rounded-full object-cover" />
|
<ImageWithFallback src={profile.picture} alt={pubkey} fill={true} className="rounded-full object-cover" />
|
||||||
) : (
|
) : (
|
||||||
<Avatar size={44} name={pubkey} variant="beam" colors={['#FEE2E2', '#FEF3C7', '#F59E0B', '#EC4899', '#D946EF', '#8B5CF6']} />
|
<Avatar
|
||||||
|
size={44}
|
||||||
|
name={pubkey}
|
||||||
|
variant="beam"
|
||||||
|
colors={['#FEE2E2', '#FEF3C7', '#F59E0B', '#EC4899', '#D946EF', '#8B5CF6']}
|
||||||
|
/>
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex w-full flex-1 items-start justify-between">
|
<div className="flex w-full flex-1 items-start justify-between">
|
||||||
<div className="flex w-full justify-between">
|
<div className="flex w-full justify-between">
|
||||||
<div className="flex flex-col gap-1 text-sm">
|
<div className="flex flex-col gap-1 text-sm">
|
||||||
<span className="font-bold leading-tight">{profile.name ? profile.name : truncate(pubkey, 16, ' .... ')}</span>
|
<span className="font-bold leading-tight">
|
||||||
<span className="text-zinc-500">{profile.username ? profile.username : truncate(pubkey, 16, ' .... ')}</span>
|
{profile.name ? profile.name : truncate(pubkey, 16, ' .... ')}
|
||||||
|
</span>
|
||||||
|
<span className="text-zinc-500">
|
||||||
|
{profile.username ? profile.username : truncate(pubkey, 16, ' .... ')}
|
||||||
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<DotsHorizontalIcon className="h-4 w-4 text-zinc-500" />
|
<DotsHorizontalIcon className="h-4 w-4 text-zinc-500" />
|
||||||
|
@ -40,7 +40,14 @@ export const NoteConnector = memo(function NoteConnector({
|
|||||||
`INSERT OR IGNORE INTO
|
`INSERT OR IGNORE INTO
|
||||||
cache_notes
|
cache_notes
|
||||||
(id, pubkey, created_at, kind, tags, content) VALUES
|
(id, pubkey, created_at, kind, tags, content) VALUES
|
||||||
("${event.id}", "${event.pubkey}", "${event.created_at}", "${event.kind}", '${JSON.stringify(event.tags)}', "${event.content}");`
|
(
|
||||||
|
"${event.id}",
|
||||||
|
"${event.pubkey}",
|
||||||
|
"${event.created_at}",
|
||||||
|
"${event.kind}",
|
||||||
|
'${JSON.stringify(event.tags)}',
|
||||||
|
"${event.content}"
|
||||||
|
);`
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
[db]
|
[db]
|
||||||
@ -85,7 +92,10 @@ export const NoteConnector = memo(function NoteConnector({
|
|||||||
<h3 className="text-sm font-semibold text-zinc-500"># following</h3>
|
<h3 className="text-sm font-semibold text-zinc-500"># following</h3>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
<button onClick={() => reloadNewsfeed()} className={`${reload ? 'animate-spin' : ''} rounded-full p-1 hover:bg-zinc-800`}>
|
<button
|
||||||
|
onClick={() => reloadNewsfeed()}
|
||||||
|
className={`${reload ? 'animate-spin' : ''} rounded-full p-1 hover:bg-zinc-800`}
|
||||||
|
>
|
||||||
<ReloadIcon className="h-3.5 w-3.5 text-zinc-500" />
|
<ReloadIcon className="h-3.5 w-3.5 text-zinc-500" />
|
||||||
</button>
|
</button>
|
||||||
<div className="inline-flex items-center gap-1 rounded-full border border-zinc-700 bg-zinc-800 px-2.5 py-1">
|
<div className="inline-flex items-center gap-1 rounded-full border border-zinc-700 bg-zinc-800 px-2.5 py-1">
|
||||||
|
@ -7,7 +7,8 @@ export default function LinkCard({ data }: { data: object }) {
|
|||||||
<Link
|
<Link
|
||||||
href={data['url']}
|
href={data['url']}
|
||||||
target={'_blank'}
|
target={'_blank'}
|
||||||
className="relative mt-2 flex flex-col overflow-hidden rounded-xl border border-zinc-700">
|
className="relative mt-2 flex flex-col overflow-hidden rounded-xl border border-zinc-700"
|
||||||
|
>
|
||||||
<div className="relative aspect-video h-auto w-full">
|
<div className="relative aspect-video h-auto w-full">
|
||||||
<Image src={data['image']} alt="image preview" fill={true} className="object-cover" />
|
<Image src={data['image']} alt="image preview" fill={true} className="object-cover" />
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,3 @@
|
|||||||
export default function BaseLayout({ children }: { children: React.ReactNode }) {
|
export default function BaseLayout({ children }: { children: React.ReactNode }) {
|
||||||
return (
|
return <div className="h-screen w-screen bg-white text-zinc-900 dark:bg-near-black dark:text-white">{children}</div>;
|
||||||
<div className="h-screen w-screen bg-white text-zinc-900 dark:bg-near-black dark:text-white">
|
|
||||||
{children}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,7 @@ export default function FullLayout({ children }: { children: React.ReactNode })
|
|||||||
return (
|
return (
|
||||||
<div className="bg-gradient-radial-page relative h-full overflow-hidden">
|
<div className="bg-gradient-radial-page relative h-full overflow-hidden">
|
||||||
{/* dragging area */}
|
{/* dragging area */}
|
||||||
<div
|
<div data-tauri-drag-region className="absolute top-0 left-0 z-20 h-16 w-full bg-transparent" />
|
||||||
data-tauri-drag-region
|
|
||||||
className="absolute top-0 left-0 z-20 h-16 w-full bg-transparent"
|
|
||||||
/>
|
|
||||||
{/* end dragging area */}
|
{/* end dragging area */}
|
||||||
{/* content */}
|
{/* content */}
|
||||||
<div className="relative z-10 h-full">{children}</div>
|
<div className="relative z-10 h-full">{children}</div>
|
||||||
|
@ -27,13 +27,15 @@ export default function UserLayout({ children }: { children: React.ReactNode })
|
|||||||
<ActiveLink
|
<ActiveLink
|
||||||
href={`/profile/${currentUser.pubkey}`}
|
href={`/profile/${currentUser.pubkey}`}
|
||||||
activeClassName="ring-1 ring-white/10 dark:bg-zinc-900 dark:text-white"
|
activeClassName="ring-1 ring-white/10 dark:bg-zinc-900 dark:text-white"
|
||||||
className="flex h-10 items-center gap-1 rounded-lg px-2.5 text-sm font-medium hover:bg-zinc-900">
|
className="flex h-10 items-center gap-1 rounded-lg px-2.5 text-sm font-medium hover:bg-zinc-900"
|
||||||
|
>
|
||||||
<span>Personal Page</span>
|
<span>Personal Page</span>
|
||||||
</ActiveLink>
|
</ActiveLink>
|
||||||
<ActiveLink
|
<ActiveLink
|
||||||
href={`/profile/update?pubkey=${currentUser.pubkey}`}
|
href={`/profile/update?pubkey=${currentUser.pubkey}`}
|
||||||
activeClassName="ring-1 ring-white/10 dark:bg-zinc-900 dark:text-white"
|
activeClassName="ring-1 ring-white/10 dark:bg-zinc-900 dark:text-white"
|
||||||
className="flex h-10 items-center gap-1 rounded-lg px-2.5 text-sm font-medium hover:bg-zinc-900">
|
className="flex h-10 items-center gap-1 rounded-lg px-2.5 text-sm font-medium hover:bg-zinc-900"
|
||||||
|
>
|
||||||
<span>Update Profile</span>
|
<span>Update Profile</span>
|
||||||
</ActiveLink>
|
</ActiveLink>
|
||||||
</div>
|
</div>
|
||||||
|
@ -69,7 +69,9 @@ export default function Page() {
|
|||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const getData = async () => {
|
const getData = async () => {
|
||||||
const result = await db.select(
|
const result = await db.select(
|
||||||
`SELECT * FROM cache_notes WHERE created_at <= ${dateToUnix(now.current)} ORDER BY created_at DESC LIMIT ${limit.current}`
|
`SELECT * FROM cache_notes WHERE created_at <= ${dateToUnix(now.current)} ORDER BY created_at DESC LIMIT ${
|
||||||
|
limit.current
|
||||||
|
}`
|
||||||
);
|
);
|
||||||
if (result) {
|
if (result) {
|
||||||
setData(result);
|
setData(result);
|
||||||
@ -94,7 +96,8 @@ export default function Page() {
|
|||||||
<div className="absolute top-16 left-1/2 z-50 -translate-x-1/2 transform">
|
<div className="absolute top-16 left-1/2 z-50 -translate-x-1/2 transform">
|
||||||
<button
|
<button
|
||||||
onClick={() => loadNewest()}
|
onClick={() => loadNewest()}
|
||||||
className="inline-flex h-8 transform items-center justify-center gap-1 rounded-full bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-gray-300 via-fuchsia-600 to-orange-600 pl-3 pr-3.5 text-sm shadow-lg active:translate-y-1">
|
className="inline-flex h-8 transform items-center justify-center gap-1 rounded-full bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-gray-300 via-fuchsia-600 to-orange-600 pl-3 pr-3.5 text-sm shadow-lg active:translate-y-1"
|
||||||
|
>
|
||||||
<ArrowUpIcon className="h-4 w-4" />
|
<ArrowUpIcon className="h-4 w-4" />
|
||||||
<span className="drop-shadow-md">Load newest</span>
|
<span className="drop-shadow-md">Load newest</span>
|
||||||
</button>
|
</button>
|
||||||
@ -125,7 +128,13 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
Page.getLayout = function getLayout(
|
||||||
page: string | number | boolean | ReactElement<unknown, string | JSXElementConstructor<unknown>> | ReactFragment | ReactPortal
|
page:
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
||||||
|
| ReactFragment
|
||||||
|
| ReactPortal
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
|
@ -12,7 +12,13 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
Page.getLayout = function getLayout(
|
||||||
page: string | number | boolean | ReactElement<unknown, string | JSXElementConstructor<unknown>> | ReactFragment | ReactPortal
|
page:
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
||||||
|
| ReactFragment
|
||||||
|
| ReactPortal
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
|
@ -36,12 +36,16 @@ export default function Page() {
|
|||||||
<LumeSymbol className="h-16 w-16 text-white" />
|
<LumeSymbol className="h-16 w-16 text-white" />
|
||||||
</motion.div>
|
</motion.div>
|
||||||
<div className="flex flex-col items-center gap-0.5">
|
<div className="flex flex-col items-center gap-0.5">
|
||||||
<motion.h2 layoutId="subtitle" className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-4xl font-medium text-transparent">
|
<motion.h2
|
||||||
|
layoutId="subtitle"
|
||||||
|
className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-4xl font-medium text-transparent"
|
||||||
|
>
|
||||||
A censorship-resistant social network
|
A censorship-resistant social network
|
||||||
</motion.h2>
|
</motion.h2>
|
||||||
<motion.h1
|
<motion.h1
|
||||||
layoutId="title"
|
layoutId="title"
|
||||||
className="bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-gray-300 via-fuchsia-600 to-orange-600 bg-clip-text text-5xl font-bold text-transparent">
|
className="bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-gray-300 via-fuchsia-600 to-orange-600 bg-clip-text text-5xl font-bold text-transparent"
|
||||||
|
>
|
||||||
built on nostr
|
built on nostr
|
||||||
</motion.h1>
|
</motion.h1>
|
||||||
</div>
|
</div>
|
||||||
@ -49,12 +53,18 @@ export default function Page() {
|
|||||||
<div className="flex items-center gap-2 pb-16">
|
<div className="flex items-center gap-2 pb-16">
|
||||||
<div className="h-10">
|
<div className="h-10">
|
||||||
{loading ? (
|
{loading ? (
|
||||||
<svg className="h-5 w-5 animate-spin text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
<svg
|
||||||
|
className="h-5 w-5 animate-spin 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>
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||||
<path
|
<path
|
||||||
className="opacity-75"
|
className="opacity-75"
|
||||||
fill="currentColor"
|
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>
|
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>
|
</svg>
|
||||||
) : (
|
) : (
|
||||||
<></>
|
<></>
|
||||||
@ -65,7 +75,8 @@ export default function Page() {
|
|||||||
<div className="absolute inset-0 bg-gradient-to-r from-fuchsia-400/10 to-orange-100/10 opacity-100 [mask-image:radial-gradient(farthest-side_at_top,white,transparent)]">
|
<div className="absolute inset-0 bg-gradient-to-r from-fuchsia-400/10 to-orange-100/10 opacity-100 [mask-image:radial-gradient(farthest-side_at_top,white,transparent)]">
|
||||||
<svg
|
<svg
|
||||||
aria-hidden="true"
|
aria-hidden="true"
|
||||||
className="dark:fill-white/2.5 absolute inset-x-0 inset-y-[-50%] h-[200%] w-full skew-y-[-18deg] fill-black/40 stroke-black/50 mix-blend-overlay dark:stroke-white/5">
|
className="dark:fill-white/2.5 absolute inset-x-0 inset-y-[-50%] h-[200%] w-full skew-y-[-18deg] fill-black/40 stroke-black/50 mix-blend-overlay dark:stroke-white/5"
|
||||||
|
>
|
||||||
<defs>
|
<defs>
|
||||||
<pattern id=":R11d6:" width="72" height="56" patternUnits="userSpaceOnUse" x="-12" y="4">
|
<pattern id=":R11d6:" width="72" height="56" patternUnits="userSpaceOnUse" x="-12" y="4">
|
||||||
<path d="M.5 56V.5H72" fill="none"></path>
|
<path d="M.5 56V.5H72" fill="none"></path>
|
||||||
@ -86,7 +97,13 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
Page.getLayout = function getLayout(
|
||||||
page: string | number | boolean | ReactElement<unknown, string | JSXElementConstructor<unknown>> | ReactFragment | ReactPortal
|
page:
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
||||||
|
| ReactFragment
|
||||||
|
| ReactPortal
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
|
@ -11,7 +11,16 @@ import { motion } from 'framer-motion';
|
|||||||
import Image from 'next/image';
|
import Image from 'next/image';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { generatePrivateKey, getEventHash, getPublicKey, nip19, signEvent } from 'nostr-tools';
|
import { generatePrivateKey, getEventHash, getPublicKey, nip19, signEvent } from 'nostr-tools';
|
||||||
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useCallback, useContext, useMemo, useState } from 'react';
|
import {
|
||||||
|
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 = {
|
||||||
@ -58,7 +67,9 @@ export default function Page() {
|
|||||||
|
|
||||||
const insertDB = useCallback(async () => {
|
const insertDB = useCallback(async () => {
|
||||||
await db.execute(
|
await db.execute(
|
||||||
`INSERT INTO accounts (id, privkey, npub, nsec, metadata) VALUES ("${pubKey}", "${privKey}", "${npub}", "${nsec}", '${JSON.stringify(data)}')`
|
`INSERT INTO accounts (id, privkey, npub, nsec, metadata) VALUES ("${pubKey}", "${privKey}", "${npub}", "${nsec}", '${JSON.stringify(
|
||||||
|
data
|
||||||
|
)}')`
|
||||||
);
|
);
|
||||||
}, [data, db, npub, nsec, privKey, pubKey]);
|
}, [data, db, npub, nsec, privKey, pubKey]);
|
||||||
|
|
||||||
@ -101,12 +112,15 @@ export default function Page() {
|
|||||||
<div>{/* spacer */}</div>
|
<div>{/* spacer */}</div>
|
||||||
<motion.div layoutId="form">
|
<motion.div layoutId="form">
|
||||||
<div className="mb-8 flex flex-col gap-3">
|
<div className="mb-8 flex flex-col gap-3">
|
||||||
<motion.h1 layoutId="title" className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent">
|
<motion.h1
|
||||||
|
layoutId="title"
|
||||||
|
className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent"
|
||||||
|
>
|
||||||
Create new key
|
Create new key
|
||||||
</motion.h1>
|
</motion.h1>
|
||||||
<motion.h2 layoutId="subtitle" className="w-3/4 text-zinc-400">
|
<motion.h2 layoutId="subtitle" className="w-3/4 text-zinc-400">
|
||||||
Lume will generate key with default profile for you, you can edit it later, and please store your key safely so you can restore your
|
Lume will generate key with default profile for you, you can edit it later, and please store your key safely
|
||||||
account or use other client
|
so you can restore your account or use other client
|
||||||
</motion.h2>
|
</motion.h2>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-4">
|
<div className="flex flex-col gap-4">
|
||||||
@ -131,7 +145,8 @@ export default function Page() {
|
|||||||
/>
|
/>
|
||||||
<button
|
<button
|
||||||
onClick={() => showPrivateKey()}
|
onClick={() => showPrivateKey()}
|
||||||
className="group absolute right-2 top-1/2 -translate-y-1/2 transform rounded p-1 hover:bg-zinc-700">
|
className="group absolute right-2 top-1/2 -translate-y-1/2 transform rounded p-1 hover:bg-zinc-700"
|
||||||
|
>
|
||||||
{type === 'password' ? (
|
{type === 'password' ? (
|
||||||
<EyeClosedIcon className="h-5 w-5 text-zinc-500 group-hover:text-zinc-200" />
|
<EyeClosedIcon className="h-5 w-5 text-zinc-500 group-hover:text-zinc-200" />
|
||||||
) : (
|
) : (
|
||||||
@ -170,18 +185,25 @@ export default function Page() {
|
|||||||
<motion.div layoutId="action" className="pb-5">
|
<motion.div layoutId="action" className="pb-5">
|
||||||
<div className="flex h-10 items-center">
|
<div className="flex h-10 items-center">
|
||||||
{loading === true ? (
|
{loading === true ? (
|
||||||
<svg className="h-5 w-5 animate-spin text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
<svg
|
||||||
|
className="h-5 w-5 animate-spin 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>
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||||
<path
|
<path
|
||||||
className="opacity-75"
|
className="opacity-75"
|
||||||
fill="currentColor"
|
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>
|
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>
|
</svg>
|
||||||
) : (
|
) : (
|
||||||
<div className="relative shrink-0 before:pointer-events-none before:absolute before:-inset-1 before:rounded-[11px] before:border before:border-blue-500 before:opacity-0 before:ring-2 before:ring-blue-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight after:shadow-white/5 after:transition focus-within:before:opacity-100 focus-within:after:shadow-blue-500/100 dark:focus-within:after:shadow-blue-500/20">
|
<div className="relative shrink-0 before:pointer-events-none before:absolute before:-inset-1 before:rounded-[11px] before:border before:border-blue-500 before:opacity-0 before:ring-2 before:ring-blue-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight after:shadow-white/5 after:transition focus-within:before:opacity-100 focus-within:after:shadow-blue-500/100 dark:focus-within:after:shadow-blue-500/20">
|
||||||
<button
|
<button
|
||||||
onClick={() => createAccount()}
|
onClick={() => createAccount()}
|
||||||
className="transform rounded-lg border border-white/10 bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-gray-300 via-fuchsia-600 to-orange-600 px-3.5 py-2 font-medium shadow-input shadow-black/5 active:translate-y-1 disabled:cursor-not-allowed disabled:opacity-50 dark:shadow-black/10">
|
className="transform rounded-lg border border-white/10 bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-gray-300 via-fuchsia-600 to-orange-600 px-3.5 py-2 font-medium shadow-input shadow-black/5 active:translate-y-1 disabled:cursor-not-allowed disabled:opacity-50 dark:shadow-black/10"
|
||||||
|
>
|
||||||
<span className="drop-shadow-lg">Continue →</span>
|
<span className="drop-shadow-lg">Continue →</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -193,7 +215,13 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
Page.getLayout = function getLayout(
|
||||||
page: string | number | boolean | ReactElement<unknown, string | JSXElementConstructor<unknown>> | ReactFragment | ReactPortal
|
page:
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
||||||
|
| ReactFragment
|
||||||
|
| ReactPortal
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
|
@ -33,7 +33,9 @@ export default function Page() {
|
|||||||
|
|
||||||
const insertDB = async () => {
|
const insertDB = async () => {
|
||||||
// self follow
|
// self follow
|
||||||
await db.execute(`INSERT INTO follows (pubkey, account, kind) VALUES ("${currentUser.pubkey}", "${currentUser.pubkey}", "0")`);
|
await db.execute(
|
||||||
|
`INSERT INTO follows (pubkey, account, kind) VALUES ("${currentUser.pubkey}", "${currentUser.pubkey}", "0")`
|
||||||
|
);
|
||||||
// follow selected
|
// follow selected
|
||||||
follow.forEach(async (npub) => {
|
follow.forEach(async (npub) => {
|
||||||
const { data } = nip19.decode(npub);
|
const { data } = nip19.decode(npub);
|
||||||
@ -57,11 +59,15 @@ export default function Page() {
|
|||||||
<div>{/* spacer */}</div>
|
<div>{/* spacer */}</div>
|
||||||
<motion.div layoutId="form" className="flex flex-col">
|
<motion.div layoutId="form" className="flex flex-col">
|
||||||
<div className="mb-8 flex flex-col gap-3">
|
<div className="mb-8 flex flex-col gap-3">
|
||||||
<motion.h1 layoutId="title" className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent">
|
<motion.h1
|
||||||
|
layoutId="title"
|
||||||
|
className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent"
|
||||||
|
>
|
||||||
Choose 10 people you want to following
|
Choose 10 people you want to following
|
||||||
</motion.h1>
|
</motion.h1>
|
||||||
<motion.h2 layoutId="subtitle" className="w-3/4 text-zinc-400">
|
<motion.h2 layoutId="subtitle" className="w-3/4 text-zinc-400">
|
||||||
For better experiences, you should follow the people you care about to personalize your newsfeed, otherwise you will be very bored
|
For better experiences, you should follow the people you care about to personalize your newsfeed, otherwise
|
||||||
|
you will be very bored
|
||||||
</motion.h2>
|
</motion.h2>
|
||||||
</div>
|
</div>
|
||||||
<div className="h-full w-full shrink">
|
<div className="h-full w-full shrink">
|
||||||
@ -73,7 +79,8 @@ export default function Page() {
|
|||||||
data-npub={item.npub}
|
data-npub={item.npub}
|
||||||
className={`col-span-1 inline-flex cursor-pointer items-center gap-3 rounded-lg p-2 hover:bg-zinc-700 ${
|
className={`col-span-1 inline-flex cursor-pointer items-center gap-3 rounded-lg p-2 hover:bg-zinc-700 ${
|
||||||
follow.includes(item.npub) ? 'bg-zinc-800' : ''
|
follow.includes(item.npub) ? 'bg-zinc-800' : ''
|
||||||
}`}>
|
}`}
|
||||||
|
>
|
||||||
<div className="relative h-10 w-10 flex-shrink-0">
|
<div className="relative h-10 w-10 flex-shrink-0">
|
||||||
<Image className="rounded-full object-cover" src={item.avatar} alt={item.name} fill={true} />
|
<Image className="rounded-full object-cover" src={item.avatar} alt={item.name} fill={true} />
|
||||||
</div>
|
</div>
|
||||||
@ -82,7 +89,9 @@ export default function Page() {
|
|||||||
<p className="truncate text-sm font-medium text-zinc-200">{item.name}</p>
|
<p className="truncate text-sm font-medium text-zinc-200">{item.name}</p>
|
||||||
<p className="text-sm leading-tight text-zinc-500">{truncate(item.npub, 16, ' .... ')}</p>
|
<p className="text-sm leading-tight text-zinc-500">{truncate(item.npub, 16, ' .... ')}</p>
|
||||||
</div>
|
</div>
|
||||||
<div>{follow.includes(item.npub) ? <CheckCircledIcon className="h-4 w-4 text-green-500" /> : <></>}</div>
|
<div>
|
||||||
|
{follow.includes(item.npub) ? <CheckCircledIcon className="h-4 w-4 text-green-500" /> : <></>}
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
@ -92,19 +101,26 @@ export default function Page() {
|
|||||||
<motion.div layoutId="action" className="pb-5">
|
<motion.div layoutId="action" className="pb-5">
|
||||||
<div className="flex h-10 items-center">
|
<div className="flex h-10 items-center">
|
||||||
{loading === true ? (
|
{loading === true ? (
|
||||||
<svg className="h-5 w-5 animate-spin text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
<svg
|
||||||
|
className="h-5 w-5 animate-spin 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>
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||||
<path
|
<path
|
||||||
className="opacity-75"
|
className="opacity-75"
|
||||||
fill="currentColor"
|
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>
|
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>
|
</svg>
|
||||||
) : (
|
) : (
|
||||||
<div className="relative shrink-0 before:pointer-events-none before:absolute before:-inset-1 before:rounded-[11px] before:border before:border-blue-500 before:opacity-0 before:ring-2 before:ring-blue-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight after:shadow-white/5 after:transition focus-within:before:opacity-100 focus-within:after:shadow-blue-500/100 dark:focus-within:after:shadow-blue-500/20">
|
<div className="relative shrink-0 before:pointer-events-none before:absolute before:-inset-1 before:rounded-[11px] before:border before:border-blue-500 before:opacity-0 before:ring-2 before:ring-blue-500/20 before:transition after:pointer-events-none after:absolute after:inset-px after:rounded-[7px] after:shadow-highlight after:shadow-white/5 after:transition focus-within:before:opacity-100 focus-within:after:shadow-blue-500/100 dark:focus-within:after:shadow-blue-500/20">
|
||||||
<button
|
<button
|
||||||
onClick={() => createFollowing()}
|
onClick={() => createFollowing()}
|
||||||
disabled={follow.length < 10 ? true : false}
|
disabled={follow.length < 10 ? true : false}
|
||||||
className="transform rounded-lg border border-white/10 bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-gray-300 via-fuchsia-600 to-orange-600 px-3.5 py-2 font-medium shadow-input shadow-black/5 active:translate-y-1 disabled:cursor-not-allowed disabled:opacity-50 dark:shadow-black/10">
|
className="transform rounded-lg border border-white/10 bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-gray-300 via-fuchsia-600 to-orange-600 px-3.5 py-2 font-medium shadow-input shadow-black/5 active:translate-y-1 disabled:cursor-not-allowed disabled:opacity-50 dark:shadow-black/10"
|
||||||
|
>
|
||||||
<span className="drop-shadow-lg">Finish →</span>
|
<span className="drop-shadow-lg">Finish →</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
</div>
|
||||||
@ -116,7 +132,13 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
Page.getLayout = function getLayout(
|
||||||
page: string | number | boolean | ReactElement<unknown, string | JSXElementConstructor<unknown>> | ReactFragment | ReactPortal
|
page:
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
||||||
|
| ReactFragment
|
||||||
|
| ReactPortal
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
|
@ -10,7 +10,10 @@ export default function Page() {
|
|||||||
<div className="flex h-full flex-col justify-between px-8">
|
<div className="flex h-full flex-col justify-between px-8">
|
||||||
<div>{/* spacer */}</div>
|
<div>{/* spacer */}</div>
|
||||||
<div className="flex flex-col gap-3">
|
<div className="flex flex-col gap-3">
|
||||||
<motion.h1 layoutId="title" className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent">
|
<motion.h1
|
||||||
|
layoutId="title"
|
||||||
|
className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent"
|
||||||
|
>
|
||||||
Other social network require email/password
|
Other social network require email/password
|
||||||
<br />
|
<br />
|
||||||
nostr use{' '}
|
nostr use{' '}
|
||||||
@ -19,19 +22,21 @@ export default function Page() {
|
|||||||
</span>
|
</span>
|
||||||
</motion.h1>
|
</motion.h1>
|
||||||
<motion.h2 layoutId="subtitle" className="w-3/4 text-zinc-400">
|
<motion.h2 layoutId="subtitle" className="w-3/4 text-zinc-400">
|
||||||
If you have used nostr before, you can import your own private key. Otherwise, you can create a new key or use auto-generated account
|
If you have used nostr before, you can import your own private key. Otherwise, you can create a new key or use
|
||||||
created by system.
|
auto-generated account created by system.
|
||||||
</motion.h2>
|
</motion.h2>
|
||||||
<motion.div layoutId="form"></motion.div>
|
<motion.div layoutId="form"></motion.div>
|
||||||
<motion.div layoutId="action" className="mt-4 flex gap-2">
|
<motion.div layoutId="action" className="mt-4 flex gap-2">
|
||||||
<Link
|
<Link
|
||||||
href="/onboarding/create"
|
href="/onboarding/create"
|
||||||
className="hover:bg-zinc-900/2.5 transform rounded-lg border border-black/5 bg-zinc-800 px-3.5 py-2 font-medium ring-1 ring-inset ring-zinc-900/10 hover:text-zinc-900 active:translate-y-1 dark:text-zinc-300 dark:ring-white/10 dark:hover:bg-zinc-700 dark:hover:text-white">
|
className="hover:bg-zinc-900/2.5 transform rounded-lg border border-black/5 bg-zinc-800 px-3.5 py-2 font-medium ring-1 ring-inset ring-zinc-900/10 hover:text-zinc-900 active:translate-y-1 dark:text-zinc-300 dark:ring-white/10 dark:hover:bg-zinc-700 dark:hover:text-white"
|
||||||
|
>
|
||||||
Create new key
|
Create new key
|
||||||
</Link>
|
</Link>
|
||||||
<Link
|
<Link
|
||||||
href="/onboarding/login"
|
href="/onboarding/login"
|
||||||
className="hover:bg-zinc-900/2.5 transform rounded-lg border border-black/5 bg-zinc-800 px-3.5 py-2 font-medium ring-1 ring-inset ring-zinc-900/10 hover:text-zinc-900 active:translate-y-1 dark:text-zinc-300 dark:ring-white/10 dark:hover:bg-zinc-700 dark:hover:text-white">
|
className="hover:bg-zinc-900/2.5 transform rounded-lg border border-black/5 bg-zinc-800 px-3.5 py-2 font-medium ring-1 ring-inset ring-zinc-900/10 hover:text-zinc-900 active:translate-y-1 dark:text-zinc-300 dark:ring-white/10 dark:hover:bg-zinc-700 dark:hover:text-white"
|
||||||
|
>
|
||||||
Login with private key
|
Login with private key
|
||||||
</Link>
|
</Link>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
@ -42,7 +47,13 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
Page.getLayout = function getLayout(
|
||||||
page: string | number | boolean | ReactElement<unknown, string | JSXElementConstructor<unknown>> | ReactFragment | ReactPortal
|
page:
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
||||||
|
| ReactFragment
|
||||||
|
| ReactPortal
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
|
@ -10,7 +10,16 @@ import { motion } from 'framer-motion';
|
|||||||
import Link from 'next/link';
|
import Link from 'next/link';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { getPublicKey, nip19 } from 'nostr-tools';
|
import { getPublicKey, nip19 } from 'nostr-tools';
|
||||||
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useCallback, useContext, useMemo, useState } from 'react';
|
import {
|
||||||
|
JSXElementConstructor,
|
||||||
|
ReactElement,
|
||||||
|
ReactFragment,
|
||||||
|
ReactPortal,
|
||||||
|
useCallback,
|
||||||
|
useContext,
|
||||||
|
useMemo,
|
||||||
|
useState,
|
||||||
|
} from 'react';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
const { db }: any = useContext(DatabaseContext);
|
const { db }: any = useContext(DatabaseContext);
|
||||||
@ -44,7 +53,9 @@ export default function Page() {
|
|||||||
async (follows) => {
|
async (follows) => {
|
||||||
follows.forEach(async (item) => {
|
follows.forEach(async (item) => {
|
||||||
if (item) {
|
if (item) {
|
||||||
await db.execute(`INSERT OR IGNORE INTO follows (pubkey, account, kind) VALUES ("${item[1]}", "${pubkey}", "0")`);
|
await db.execute(
|
||||||
|
`INSERT OR IGNORE INTO follows (pubkey, account, kind) VALUES ("${item[1]}", "${pubkey}", "0")`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
},
|
},
|
||||||
@ -80,28 +91,39 @@ export default function Page() {
|
|||||||
<div>{/* spacer */}</div>
|
<div>{/* spacer */}</div>
|
||||||
<motion.div layoutId="form">
|
<motion.div layoutId="form">
|
||||||
<div className="mb-8 flex flex-col gap-3">
|
<div className="mb-8 flex flex-col gap-3">
|
||||||
<motion.h1 layoutId="title" className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent">
|
<motion.h1
|
||||||
|
layoutId="title"
|
||||||
|
className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent"
|
||||||
|
>
|
||||||
Fetching your profile...
|
Fetching your profile...
|
||||||
</motion.h1>
|
</motion.h1>
|
||||||
<motion.h2 layoutId="subtitle" className="w-3/4 text-zinc-400">
|
<motion.h2 layoutId="subtitle" className="w-3/4 text-zinc-400">
|
||||||
As long as you have private key, you alway can sync your profile and follows list on every nostr client, so please keep your key safely
|
As long as you have private key, you alway can sync your profile and follows list on every nostr client, so
|
||||||
|
please keep your key safely
|
||||||
</motion.h2>
|
</motion.h2>
|
||||||
</div>
|
</div>
|
||||||
</motion.div>
|
</motion.div>
|
||||||
<motion.div layoutId="action" className="pb-5">
|
<motion.div layoutId="action" className="pb-5">
|
||||||
<div className="flex h-10 items-center">
|
<div className="flex h-10 items-center">
|
||||||
{loading === true ? (
|
{loading === true ? (
|
||||||
<svg className="h-5 w-5 animate-spin text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
<svg
|
||||||
|
className="h-5 w-5 animate-spin 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>
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||||
<path
|
<path
|
||||||
className="opacity-75"
|
className="opacity-75"
|
||||||
fill="currentColor"
|
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>
|
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>
|
</svg>
|
||||||
) : (
|
) : (
|
||||||
<Link
|
<Link
|
||||||
href="/"
|
href="/"
|
||||||
className="transform rounded-lg bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-gray-300 via-fuchsia-600 to-orange-600 px-3.5 py-2 font-medium active:translate-y-1 disabled:cursor-not-allowed disabled:opacity-30">
|
className="transform rounded-lg bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-gray-300 via-fuchsia-600 to-orange-600 px-3.5 py-2 font-medium active:translate-y-1 disabled:cursor-not-allowed disabled:opacity-30"
|
||||||
|
>
|
||||||
<span className="drop-shadow-lg">Finish</span>
|
<span className="drop-shadow-lg">Finish</span>
|
||||||
</Link>
|
</Link>
|
||||||
)}
|
)}
|
||||||
@ -112,7 +134,13 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
Page.getLayout = function getLayout(
|
||||||
page: string | number | boolean | ReactElement<unknown, string | JSXElementConstructor<unknown>> | ReactFragment | ReactPortal
|
page:
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
||||||
|
| ReactFragment
|
||||||
|
| ReactPortal
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
|
@ -60,12 +60,15 @@ export default function Page() {
|
|||||||
<div>{/* spacer */}</div>
|
<div>{/* spacer */}</div>
|
||||||
<motion.div layoutId="form">
|
<motion.div layoutId="form">
|
||||||
<div className="mb-8 flex flex-col gap-3">
|
<div className="mb-8 flex flex-col gap-3">
|
||||||
<motion.h1 layoutId="title" className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent">
|
<motion.h1
|
||||||
|
layoutId="title"
|
||||||
|
className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent"
|
||||||
|
>
|
||||||
Import your private key
|
Import your private key
|
||||||
</motion.h1>
|
</motion.h1>
|
||||||
<motion.h2 layoutId="subtitle" className="w-3/4 text-zinc-400">
|
<motion.h2 layoutId="subtitle" className="w-3/4 text-zinc-400">
|
||||||
You can import private key format as hex string or nsec. If you have installed Nostr Connect compality wallet in your mobile, you can
|
You can import private key format as hex string or nsec. If you have installed Nostr Connect compality
|
||||||
connect by scan QR Code below
|
wallet in your mobile, you can connect by scan QR Code below
|
||||||
</motion.h2>
|
</motion.h2>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-2">
|
<div className="flex flex-col gap-2">
|
||||||
@ -83,18 +86,25 @@ export default function Page() {
|
|||||||
<motion.div layoutId="action" className="pb-5">
|
<motion.div layoutId="action" className="pb-5">
|
||||||
<div className="flex h-10 items-center">
|
<div className="flex h-10 items-center">
|
||||||
{isSubmitting ? (
|
{isSubmitting ? (
|
||||||
<svg className="h-5 w-5 animate-spin text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
<svg
|
||||||
|
className="h-5 w-5 animate-spin 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>
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||||
<path
|
<path
|
||||||
className="opacity-75"
|
className="opacity-75"
|
||||||
fill="currentColor"
|
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>
|
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>
|
</svg>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={!isDirty || !isValid}
|
disabled={!isDirty || !isValid}
|
||||||
className="transform rounded-lg bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-gray-300 via-fuchsia-600 to-orange-600 px-3.5 py-2 font-medium active:translate-y-1 disabled:cursor-not-allowed disabled:opacity-30">
|
className="transform rounded-lg bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-gray-300 via-fuchsia-600 to-orange-600 px-3.5 py-2 font-medium active:translate-y-1 disabled:cursor-not-allowed disabled:opacity-30"
|
||||||
|
>
|
||||||
<span className="drop-shadow-lg">Continue →</span>
|
<span className="drop-shadow-lg">Continue →</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
@ -105,7 +115,13 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
Page.getLayout = function getLayout(
|
||||||
page: string | number | boolean | ReactElement<unknown, string | JSXElementConstructor<unknown>> | ReactFragment | ReactPortal
|
page:
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
||||||
|
| ReactFragment
|
||||||
|
| ReactPortal
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
|
@ -32,7 +32,8 @@ export default function Page() {
|
|||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
|
|
||||||
const [currentUser]: any = useLocalStorage('current-user');
|
const [currentUser]: any = useLocalStorage('current-user');
|
||||||
const profile = currentUser.metadata !== undefined ? JSON.parse(currentUser.metadata) : { display_name: null, username: null };
|
const profile =
|
||||||
|
currentUser.metadata !== undefined ? JSON.parse(currentUser.metadata) : { display_name: null, username: null };
|
||||||
|
|
||||||
const {
|
const {
|
||||||
register,
|
register,
|
||||||
@ -79,9 +80,12 @@ export default function Page() {
|
|||||||
return (
|
return (
|
||||||
<form onSubmit={handleSubmit(onSubmit)} className="flex h-full w-full flex-col justify-between px-6">
|
<form onSubmit={handleSubmit(onSubmit)} className="flex h-full w-full flex-col justify-between px-6">
|
||||||
<div className="mb-8 flex flex-col gap-3 pt-8">
|
<div className="mb-8 flex flex-col gap-3 pt-8">
|
||||||
<h1 className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent">Update profile</h1>
|
<h1 className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent">
|
||||||
|
Update profile
|
||||||
|
</h1>
|
||||||
<h2 className="w-3/4 text-zinc-400">
|
<h2 className="w-3/4 text-zinc-400">
|
||||||
Your profile will be published to all relays, as long as you have the private key, you always can recover your profile in any client
|
Your profile will be published to all relays, as long as you have the private key, you always can recover your
|
||||||
|
profile in any client
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<fieldset className="flex flex-col gap-2">
|
<fieldset className="flex flex-col gap-2">
|
||||||
@ -179,18 +183,25 @@ export default function Page() {
|
|||||||
<div className="pb-5">
|
<div className="pb-5">
|
||||||
<div className="flex h-10 items-center">
|
<div className="flex h-10 items-center">
|
||||||
{loading === true ? (
|
{loading === true ? (
|
||||||
<svg className="h-5 w-5 animate-spin text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
<svg
|
||||||
|
className="h-5 w-5 animate-spin 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>
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||||
<path
|
<path
|
||||||
className="opacity-75"
|
className="opacity-75"
|
||||||
fill="currentColor"
|
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>
|
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>
|
</svg>
|
||||||
) : (
|
) : (
|
||||||
<button
|
<button
|
||||||
type="submit"
|
type="submit"
|
||||||
disabled={!isDirty || !isValid}
|
disabled={!isDirty || !isValid}
|
||||||
className="transform rounded-lg bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-gray-300 via-fuchsia-600 to-orange-600 px-3.5 py-2 font-medium active:translate-y-1 disabled:cursor-not-allowed disabled:opacity-30">
|
className="transform rounded-lg bg-[radial-gradient(ellipse_at_bottom_right,_var(--tw-gradient-stops))] from-gray-300 via-fuchsia-600 to-orange-600 px-3.5 py-2 font-medium active:translate-y-1 disabled:cursor-not-allowed disabled:opacity-30"
|
||||||
|
>
|
||||||
<span className="drop-shadow-lg">Update</span>
|
<span className="drop-shadow-lg">Update</span>
|
||||||
</button>
|
</button>
|
||||||
)}
|
)}
|
||||||
@ -201,7 +212,13 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
Page.getLayout = function getLayout(
|
||||||
page: string | number | boolean | ReactElement<unknown, string | JSXElementConstructor<unknown>> | ReactFragment | ReactPortal
|
page:
|
||||||
|
| string
|
||||||
|
| number
|
||||||
|
| boolean
|
||||||
|
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
||||||
|
| ReactFragment
|
||||||
|
| ReactPortal
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
|
Loading…
Reference in New Issue
Block a user