mirror of
https://github.com/lumehq/lume.git
synced 2025-09-20 13:51:19 +02:00
fixed sql query
This commit is contained in:
@@ -27,11 +27,7 @@ export const User = memo(function User({ pubkey, time }: { pubkey: string; time:
|
|||||||
const metadata: any = JSON.parse(rawMetadata.content);
|
const metadata: any = JSON.parse(rawMetadata.content);
|
||||||
if (profile.picture === null || profile.name === null) {
|
if (profile.picture === null || profile.name === null) {
|
||||||
setProfile(metadata);
|
setProfile(metadata);
|
||||||
await db.execute(
|
await db.execute(`INSERT OR IGNORE INTO cache_profiles (id, metadata) VALUES ("${pubkey}", '${JSON.stringify(metadata)}')`);
|
||||||
`INSERT OR IGNORE INTO cache_profiles (pubkey, metadata) VALUES ("${pubkey}", '${JSON.stringify(
|
|
||||||
metadata
|
|
||||||
)}')`
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -42,9 +38,7 @@ export const User = memo(function User({ pubkey, time }: { pubkey: string; time:
|
|||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const initialProfile = async () => {
|
const initialProfile = async () => {
|
||||||
const result: any = await db.select(
|
const result: any = await db.select(`SELECT metadata FROM cache_profiles WHERE id = "${pubkey}"`);
|
||||||
`SELECT metadata FROM cache_profiles WHERE pubkey = "${pubkey}"`
|
|
||||||
);
|
|
||||||
db.close;
|
db.close;
|
||||||
return result;
|
return result;
|
||||||
};
|
};
|
||||||
@@ -62,27 +56,15 @@ export const User = memo(function User({ pubkey, time }: { pubkey: string; time:
|
|||||||
<div className="relative flex items-start gap-4">
|
<div className="relative flex items-start gap-4">
|
||||||
<div className="relative h-11 w-11 shrink overflow-hidden rounded-full border border-white/10">
|
<div className="relative h-11 w-11 shrink overflow-hidden rounded-full border border-white/10">
|
||||||
{profile.picture ? (
|
{profile.picture ? (
|
||||||
<ImageWithFallback
|
<ImageWithFallback src={profile.picture} alt={pubkey} fill={true} className="rounded-full object-cover" />
|
||||||
src={profile.picture}
|
|
||||||
alt={pubkey}
|
|
||||||
fill={true}
|
|
||||||
className="rounded-full object-cover"
|
|
||||||
/>
|
|
||||||
) : (
|
) : (
|
||||||
<Avatar
|
<Avatar size={44} name={pubkey} variant="beam" colors={['#FEE2E2', '#FEF3C7', '#F59E0B', '#EC4899', '#D946EF', '#8B5CF6']} />
|
||||||
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">
|
<span className="font-bold leading-tight">{profile.name ? profile.name : truncate(pubkey, 16, ' .... ')}</span>
|
||||||
{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}
|
||||||
|
@@ -35,14 +35,14 @@ export default function Page() {
|
|||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const getAccount = useCallback(async () => {
|
const getAccount = useCallback(async () => {
|
||||||
const result = await db.select(`SELECT id FROM accounts ASC LIMIT 1`);
|
const result = await db.select(`SELECT * FROM accounts ASC LIMIT 1`);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}, []);
|
}, []);
|
||||||
|
|
||||||
const getFollows = useCallback(async (account) => {
|
const getFollows = useCallback(async (account) => {
|
||||||
const arr = [];
|
const arr = [];
|
||||||
const result: any = await db.select(`SELECT pubkey FROM follows WHERE account = "${account.pubkey}"`);
|
const result: any = await db.select(`SELECT pubkey FROM follows WHERE account = "${account.id}"`);
|
||||||
|
|
||||||
result.forEach((item: { pubkey: string }) => {
|
result.forEach((item: { pubkey: string }) => {
|
||||||
arr.push(item.pubkey);
|
arr.push(item.pubkey);
|
||||||
@@ -59,7 +59,6 @@ export default function Page() {
|
|||||||
requestNotification().then(() => {
|
requestNotification().then(() => {
|
||||||
getAccount()
|
getAccount()
|
||||||
.then((res: any) => {
|
.then((res: any) => {
|
||||||
console.log(res);
|
|
||||||
if (res.length === 0) {
|
if (res.length === 0) {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
|
@@ -43,12 +43,8 @@ export default function Page() {
|
|||||||
|
|
||||||
const [privKey] = useState(() => generatePrivateKey());
|
const [privKey] = useState(() => generatePrivateKey());
|
||||||
const [name] = useState(() => uniqueNamesGenerator(config).toString());
|
const [name] = useState(() => uniqueNamesGenerator(config).toString());
|
||||||
const [avatar] = useState(
|
const [avatar] = useState(() => defaultAvatars[Math.floor(Math.random() * defaultAvatars.length)]);
|
||||||
() => defaultAvatars[Math.floor(Math.random() * defaultAvatars.length)]
|
const [banner] = useState(() => defaultBanners[Math.floor(Math.random() * defaultBanners.length)]);
|
||||||
);
|
|
||||||
const [banner] = useState(
|
|
||||||
() => defaultBanners[Math.floor(Math.random() * defaultBanners.length)]
|
|
||||||
);
|
|
||||||
|
|
||||||
const pubKey = getPublicKey(privKey);
|
const pubKey = getPublicKey(privKey);
|
||||||
const npub = nip19.npubEncode(pubKey);
|
const npub = nip19.npubEncode(pubKey);
|
||||||
@@ -81,9 +77,7 @@ export default function Page() {
|
|||||||
// save account to database
|
// save account to database
|
||||||
const db = await Database.load('sqlite:lume.db');
|
const db = await Database.load('sqlite:lume.db');
|
||||||
await db.execute(
|
await db.execute(
|
||||||
`INSERT INTO accounts (privkey, pubkey, npub, nsec, current, metadata) VALUES ("${privKey}", "${pubKey}", "${npub}", "${nsec}", "1", '${JSON.stringify(
|
`INSERT INTO accounts (id, privkey, npub, nsec, metadata) VALUES ("${pubKey}", "${privKey}", "${npub}", "${nsec}", '${JSON.stringify(data)}')`
|
||||||
data
|
|
||||||
)}')`
|
|
||||||
);
|
);
|
||||||
await db.close();
|
await db.close();
|
||||||
|
|
||||||
@@ -115,14 +109,12 @@ 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
|
<motion.h1 layoutId="title" className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent">
|
||||||
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
|
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
|
||||||
store your key safely so you can restore your account or use other client
|
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">
|
||||||
@@ -145,9 +137,7 @@ export default function Page() {
|
|||||||
value={nsec}
|
value={nsec}
|
||||||
className="relative w-full rounded-lg border border-black/5 px-3.5 py-2 shadow-input shadow-black/5 !outline-none placeholder:text-zinc-400 dark:bg-zinc-800 dark:text-zinc-200 dark:shadow-black/10 dark:placeholder:text-zinc-600"
|
className="relative w-full rounded-lg border border-black/5 px-3.5 py-2 shadow-input shadow-black/5 !outline-none placeholder:text-zinc-400 dark:bg-zinc-800 dark:text-zinc-200 dark:shadow-black/10 dark:placeholder:text-zinc-600"
|
||||||
/>
|
/>
|
||||||
<button
|
<button onClick={() => showNsec()} className="group absolute right-2 top-1/2 -translate-y-1/2 transform rounded p-1 hover:bg-zinc-700">
|
||||||
onClick={() => showNsec()}
|
|
||||||
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" />
|
||||||
) : (
|
) : (
|
||||||
@@ -157,19 +147,12 @@ export default function Page() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-col gap-1">
|
<div className="flex flex-col gap-1">
|
||||||
<label className="text-sm font-semibold text-zinc-400">
|
<label className="text-sm font-semibold text-zinc-400">Default Profile (you can change it later)</label>
|
||||||
Default Profile (you can change it later)
|
|
||||||
</label>
|
|
||||||
<div className="relative max-w-sm 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 max-w-sm 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 max-w-sm rounded-lg border border-black/5 px-3.5 py-4 shadow-input shadow-black/5 !outline-none placeholder:text-zinc-400 dark:bg-zinc-800 dark:text-zinc-200 dark:shadow-black/10 dark:placeholder:text-zinc-600">
|
<div className="relative max-w-sm rounded-lg border border-black/5 px-3.5 py-4 shadow-input shadow-black/5 !outline-none placeholder:text-zinc-400 dark:bg-zinc-800 dark:text-zinc-200 dark:shadow-black/10 dark:placeholder:text-zinc-600">
|
||||||
<div className="flex space-x-4">
|
<div className="flex space-x-4">
|
||||||
<div className="relative h-10 w-10 rounded-full">
|
<div className="relative h-10 w-10 rounded-full">
|
||||||
<Image
|
<Image className="inline-block rounded-full" src={data.picture} alt="" fill={true} />
|
||||||
className="inline-block rounded-full"
|
|
||||||
src={data.picture}
|
|
||||||
alt=""
|
|
||||||
fill={true}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="flex-1 space-y-4 py-1">
|
<div className="flex-1 space-y-4 py-1">
|
||||||
<div className="flex items-center gap-2">
|
<div className="flex items-center gap-2">
|
||||||
@@ -193,18 +176,8 @@ 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
|
<svg className="h-5 w-5 animate-spin text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||||
className="h-5 w-5 animate-spin text-white"
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||||
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
|
<path
|
||||||
className="opacity-75"
|
className="opacity-75"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
@@ -226,13 +199,7 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
Page.getLayout = function getLayout(
|
||||||
page:
|
page: string | number | boolean | ReactElement<unknown, string | JSXElementConstructor<unknown>> | ReactFragment | ReactPortal
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
|
@@ -5,14 +5,7 @@ import OnboardingLayout from '@layouts/onboardingLayout';
|
|||||||
import { motion } from 'framer-motion';
|
import { motion } from 'framer-motion';
|
||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useNostrEvents } from 'nostr-react';
|
import { useNostrEvents } from 'nostr-react';
|
||||||
import {
|
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useEffect, useState } from 'react';
|
||||||
JSXElementConstructor,
|
|
||||||
ReactElement,
|
|
||||||
ReactFragment,
|
|
||||||
ReactPortal,
|
|
||||||
useEffect,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
import Database from 'tauri-plugin-sql-api';
|
import Database from 'tauri-plugin-sql-api';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
@@ -44,9 +37,7 @@ export default function Page() {
|
|||||||
const db = await Database.load('sqlite:lume.db');
|
const db = await Database.load('sqlite:lume.db');
|
||||||
follows.forEach(async (item) => {
|
follows.forEach(async (item) => {
|
||||||
if (item) {
|
if (item) {
|
||||||
await db.execute(
|
await db.execute(`INSERT OR IGNORE INTO follows (pubkey, account) VALUES ("${item[1]}", "${pubkey}")`);
|
||||||
`INSERT OR IGNORE INTO follows (pubkey, account) VALUES ("${item[1]}", "${pubkey}")`
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -68,32 +59,19 @@ 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
|
<motion.h1 layoutId="title" className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent">
|
||||||
layoutId="title"
|
|
||||||
className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent">
|
|
||||||
Fetching your follows...
|
Fetching your follows...
|
||||||
</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">
|
||||||
Not only profile, every nostr client can sync your follows list when you move to a new
|
Not only profile, every nostr client can sync your follows list when you move to a new client, so please keep your key safely (again)
|
||||||
client, so please keep your key safely (again)
|
|
||||||
</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
|
<svg className="h-5 w-5 animate-spin text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||||
className="h-5 w-5 animate-spin text-white"
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||||
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
|
<path
|
||||||
className="opacity-75"
|
className="opacity-75"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
@@ -109,13 +87,7 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
Page.getLayout = function getLayout(
|
||||||
page:
|
page: string | number | boolean | ReactElement<unknown, string | JSXElementConstructor<unknown>> | ReactFragment | ReactPortal
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
|
@@ -6,14 +6,7 @@ import { motion } from 'framer-motion';
|
|||||||
import { useRouter } from 'next/router';
|
import { useRouter } from 'next/router';
|
||||||
import { useNostrEvents } from 'nostr-react';
|
import { useNostrEvents } from 'nostr-react';
|
||||||
import { getPublicKey, nip19 } from 'nostr-tools';
|
import { getPublicKey, nip19 } from 'nostr-tools';
|
||||||
import {
|
import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useCallback, useEffect, useState } from 'react';
|
||||||
JSXElementConstructor,
|
|
||||||
ReactElement,
|
|
||||||
ReactFragment,
|
|
||||||
ReactPortal,
|
|
||||||
useEffect,
|
|
||||||
useState,
|
|
||||||
} from 'react';
|
|
||||||
import Database from 'tauri-plugin-sql-api';
|
import Database from 'tauri-plugin-sql-api';
|
||||||
|
|
||||||
export default function Page() {
|
export default function Page() {
|
||||||
@@ -43,20 +36,19 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
const insertDB = useCallback(async () => {
|
||||||
|
// save account to database
|
||||||
|
const db = await Database.load('sqlite:lume.db');
|
||||||
|
const metadata = JSON.stringify(account);
|
||||||
|
await db.execute(
|
||||||
|
`INSERT INTO accounts (id, privkey, npub, nsec, metadata) VALUES ("${pubkey}", "${privkey}", "${npub}", "${nsec}", '${metadata}')`
|
||||||
|
);
|
||||||
|
await db.close();
|
||||||
|
}, [account, npub, nsec, privkey, pubkey]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
|
|
||||||
const insertDB = async () => {
|
|
||||||
// save account to database
|
|
||||||
const db = await Database.load('sqlite:lume.db');
|
|
||||||
await db.execute(
|
|
||||||
`INSERT INTO accounts (privkey, pubkey, npub, nsec, current, metadata) VALUES ("${privkey}", "${pubkey}", "${npub}", "${nsec}", "1", '${JSON.stringify(
|
|
||||||
account
|
|
||||||
)}')`
|
|
||||||
);
|
|
||||||
await db.close();
|
|
||||||
};
|
|
||||||
|
|
||||||
if (account !== null) {
|
if (account !== null) {
|
||||||
insertDB()
|
insertDB()
|
||||||
.then(() => {
|
.then(() => {
|
||||||
@@ -70,39 +62,26 @@ export default function Page() {
|
|||||||
})
|
})
|
||||||
.catch(console.error);
|
.catch(console.error);
|
||||||
}
|
}
|
||||||
}, [account, npub, nsec, privkey, pubkey, router]);
|
}, [account, insertDB, npub, nsec, privkey, pubkey, router]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<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>
|
||||||
<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
|
<motion.h1 layoutId="title" className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent">
|
||||||
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 on every nostr client,
|
As long as you have private key, you alway can sync your profile on every nostr client, so please keep your key safely
|
||||||
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
|
<svg className="h-5 w-5 animate-spin text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||||
className="h-5 w-5 animate-spin text-white"
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||||
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
|
<path
|
||||||
className="opacity-75"
|
className="opacity-75"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
@@ -118,13 +97,7 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
Page.getLayout = function getLayout(
|
||||||
page:
|
page: string | number | boolean | ReactElement<unknown, string | JSXElementConstructor<unknown>> | ReactFragment | ReactPortal
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
|
@@ -33,14 +33,11 @@ export default function Page() {
|
|||||||
|
|
||||||
const insertDB = async () => {
|
const insertDB = async () => {
|
||||||
const db = await Database.load('sqlite:lume.db');
|
const db = await Database.load('sqlite:lume.db');
|
||||||
await db.execute(
|
// self followed
|
||||||
`INSERT INTO follows (pubkey, account) VALUES ("${$currentUser.pubkey}", "${$currentUser.pubkey}")`
|
await db.execute(`INSERT INTO follows (pubkey, account) VALUES ("${$currentUser.pubkey}", "${$currentUser.pubkey}")`);
|
||||||
);
|
|
||||||
follow.forEach(async (npub) => {
|
follow.forEach(async (npub) => {
|
||||||
const { data } = nip19.decode(npub);
|
const { data } = nip19.decode(npub);
|
||||||
await db.execute(
|
await db.execute(`INSERT INTO follows (pubkey, account) VALUES ("${data}", "${$currentUser.pubkey}")`);
|
||||||
`INSERT INTO follows (pubkey, account) VALUES ("${data}", "${$currentUser.pubkey}")`
|
|
||||||
);
|
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -60,14 +57,11 @@ 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
|
<motion.h1 layoutId="title" className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent">
|
||||||
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
|
For better experiences, you should follow the people you care about to personalize your newsfeed, otherwise you will be very bored
|
||||||
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">
|
||||||
@@ -81,27 +75,14 @@ export default function Page() {
|
|||||||
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
|
<Image className="rounded-full object-cover" src={item.avatar} alt={item.name} fill={true} />
|
||||||
className="rounded-full object-cover"
|
|
||||||
src={item.avatar}
|
|
||||||
alt={item.name}
|
|
||||||
fill={true}
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
<div className="inline-flex flex-1 items-center justify-between">
|
<div className="inline-flex flex-1 items-center justify-between">
|
||||||
<div>
|
<div>
|
||||||
<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">
|
<p className="text-sm leading-tight text-zinc-500">{truncate(item.npub, 16, ' .... ')}</p>
|
||||||
{truncate(item.npub, 16, ' .... ')}
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
<div>
|
|
||||||
{follow.includes(item.npub) ? (
|
|
||||||
<CheckCircledIcon className="h-4 w-4 text-green-500" />
|
|
||||||
) : (
|
|
||||||
<></>
|
|
||||||
)}
|
|
||||||
</div>
|
</div>
|
||||||
|
<div>{follow.includes(item.npub) ? <CheckCircledIcon className="h-4 w-4 text-green-500" /> : <></>}</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
@@ -111,18 +92,8 @@ 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
|
<svg className="h-5 w-5 animate-spin text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||||
className="h-5 w-5 animate-spin text-white"
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||||
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
|
<path
|
||||||
className="opacity-75"
|
className="opacity-75"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
@@ -145,13 +116,7 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
Page.getLayout = function getLayout(
|
||||||
page:
|
page: string | number | boolean | ReactElement<unknown, string | JSXElementConstructor<unknown>> | ReactFragment | ReactPortal
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
|
@@ -60,14 +60,12 @@ 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
|
<motion.h1 layoutId="title" className="bg-gradient-to-br from-zinc-200 to-zinc-400 bg-clip-text text-3xl font-medium text-transparent">
|
||||||
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
|
You can import private key format as hex string or nsec. If you have installed Nostr Connect compality wallet in your mobile, you can
|
||||||
Connect compality wallet in your mobile, you can connect by scan QR Code below
|
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">
|
||||||
@@ -85,18 +83,8 @@ 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
|
<svg className="h-5 w-5 animate-spin text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
|
||||||
className="h-5 w-5 animate-spin text-white"
|
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
|
||||||
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
|
<path
|
||||||
className="opacity-75"
|
className="opacity-75"
|
||||||
fill="currentColor"
|
fill="currentColor"
|
||||||
@@ -117,13 +105,7 @@ export default function Page() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Page.getLayout = function getLayout(
|
Page.getLayout = function getLayout(
|
||||||
page:
|
page: string | number | boolean | ReactElement<unknown, string | JSXElementConstructor<unknown>> | ReactFragment | ReactPortal
|
||||||
| string
|
|
||||||
| number
|
|
||||||
| boolean
|
|
||||||
| ReactElement<unknown, string | JSXElementConstructor<unknown>>
|
|
||||||
| ReactFragment
|
|
||||||
| ReactPortal
|
|
||||||
) {
|
) {
|
||||||
return (
|
return (
|
||||||
<BaseLayout>
|
<BaseLayout>
|
||||||
|
Reference in New Issue
Block a user