converted full sql from onboarding flow to prisma

This commit is contained in:
Ren Amamiya
2023-04-03 15:03:07 +07:00
parent 33000979ed
commit 3f87d510ab
14 changed files with 314 additions and 74 deletions

View File

@@ -1,6 +1,6 @@
import BaseLayout from '@layouts/base';
import { activeAccountAtom } from '@stores/account';
import { activeAccountAtom, activeAccountFollowsAtom } from '@stores/account';
import LumeSymbol from '@assets/icons/Lume';
@@ -11,16 +11,26 @@ import { JSXElementConstructor, ReactElement, ReactFragment, ReactPortal, useCal
export default function Page() {
const router = useRouter();
const setActiveAccount = useSetAtom(activeAccountAtom);
const setActiveAccountFollows = useSetAtom(activeAccountFollowsAtom);
const fetchActiveAccount = useCallback(async () => {
const { getAccount } = await import('@utils/bindings');
return await getAccount();
}, []);
const fetchFollowsByAccount = useCallback(async (id) => {
const { getFollows } = await import('@utils/bindings');
return await getFollows({ account_id: id });
}, []);
useEffect(() => {
fetchActiveAccount()
.then((res: any) => {
if (res.length > 0) {
// fetch follows
fetchFollowsByAccount(res[0].id).then((follows) => {
setActiveAccountFollows(follows);
});
// update local storage
setActiveAccount(res[0]);
// redirect
@@ -30,7 +40,7 @@ export default function Page() {
}
})
.catch(console.error);
}, [fetchActiveAccount, setActiveAccount, router]);
}, [fetchActiveAccount, setActiveAccount, fetchFollowsByAccount, setActiveAccountFollows, router]);
return (
<div className="relative h-full overflow-hidden">

View File

@@ -2,12 +2,10 @@ import BaseLayout from '@layouts/base';
import { RelayContext } from '@components/relaysProvider';
import { activeAccountAtom } from '@stores/account';
import { relaysAtom } from '@stores/relays';
import { activeAccountAtom, activeAccountFollowsAtom, lastLoginAtom } from '@stores/account';
import { dateToUnix, hoursAgo } from '@utils/getDate';
import { countTotalNotes, createCacheNote, getAllFollowsByID, getLastLoginTime } from '@utils/storage';
import { pubkeyArray } from '@utils/transform';
import { getParentID, pubkeyArray } from '@utils/transform';
import LumeSymbol from '@assets/icons/Lume';
@@ -30,64 +28,75 @@ export default function Page() {
const [pool, relays]: any = useContext(RelayContext);
const activeAccount: any = useAtomValue(activeAccountAtom);
const [done, setDone] = useState(false);
const activeAccountFollows: any = useAtomValue(activeAccountFollowsAtom);
const lastLogin: any = useAtomValue(lastLoginAtom);
const now = useRef(new Date());
const unsubscribe = useRef(null);
const timer = useRef(null);
const [eose, setEose] = useState(false);
const fetchData = useCallback(
(since) => {
getAllFollowsByID(activeAccount.id).then((follows) => {
unsubscribe.current = pool.subscribe(
[
{
kinds: [1],
authors: pubkeyArray(follows),
since: dateToUnix(since),
until: dateToUnix(now.current),
},
],
relays,
(event) => {
// insert event to local database
createCacheNote(event);
},
undefined,
() => {
// wait for 8 seconds
timer.current = setTimeout(() => setDone(true), 8000);
},
async (since) => {
const { createNote } = await import('@utils/bindings');
unsubscribe.current = pool.subscribe(
[
{
unsubscribeOnEose: true,
}
);
});
kinds: [1],
authors: pubkeyArray(activeAccountFollows),
since: dateToUnix(since),
until: dateToUnix(now.current),
},
],
relays,
(event) => {
const parentID = getParentID(event.tags, event.id);
// insert event to local database
createNote({
event_id: event.id,
pubkey: event.pubkey,
kind: event.kind,
tags: JSON.stringify(event.tags),
content: event.content,
parent_id: parentID,
parent_comment_id: 'aaa',
account_id: activeAccount.id,
}).catch(console.error);
},
undefined,
() => {
setEose(true);
}
);
},
[activeAccount.id, pool, relays]
[activeAccount.id, activeAccountFollows, pool, relays]
);
useEffect(() => {
if (!done) {
countTotalNotes().then((count) => {
if (count.total === 0) {
fetchData(hoursAgo(24, now.current));
const isNoteExist = useCallback(async () => {
const { checkNote } = await import('@utils/bindings');
checkNote()
.then((res) => {
if (res.length === 5) {
const parseDate = new Date(lastLogin);
fetchData(parseDate);
} else {
getLastLoginTime().then((time) => {
const parseDate = new Date(time.setting_value);
fetchData(parseDate);
});
fetchData(hoursAgo(24, now.current));
}
});
})
.catch(console.error);
}, [fetchData, lastLogin]);
useEffect(() => {
if (eose === false) {
isNoteExist();
} else {
router.replace('/newsfeed/following');
}
return () => {
unsubscribe.current;
clearTimeout(timer.current);
};
}, [activeAccount.id, done, pool, relays, router, fetchData]);
}, [router, eose, isNoteExist]);
return (
<div className="relative h-full overflow-hidden">

View File

@@ -41,7 +41,7 @@ export default function Page() {
};
// auto-generated profile metadata
const metadata = useMemo(
const metadata: any = useMemo(
() => ({
display_name: name,
name: name,
@@ -77,7 +77,7 @@ export default function Page() {
event.sig = signEvent(event, privKey);
// insert to database then broadcast
createAccount({ pubkey: pubKey, privkey: privKey, metadata: JSON.stringify(metadata) })
createAccount({ pubkey: pubKey, privkey: privKey, metadata: metadata })
.then((res) => {
pool.publish(event, relays);
router.push({

View File

@@ -85,7 +85,9 @@ export default function Page() {
for (const follow of follows) {
const metadata: any = await fetchMetadata(follow, pool, relays);
createFollow({ pubkey: follow, kind: 0, metadata: metadata.content, account_id: parseInt(id) });
createFollow({ pubkey: follow, kind: 0, metadata: metadata.content, account_id: parseInt(id) }).catch(
console.error
);
}
// build event

View File

@@ -2,6 +2,8 @@ import BaseLayout from '@layouts/base';
import { RelayContext } from '@components/relaysProvider';
import { DEFAULT_AVATAR } from '@stores/constants';
import { fetchMetadata } from '@utils/metadata';
import { truncate } from '@utils/truncate';
@@ -27,29 +29,34 @@ export default function Page() {
const privkey: any = router.query.privkey || null;
const pubkey = privkey ? getPublicKey(privkey) : null;
const [profile, setProfile] = useState(null);
const [profile, setProfile] = useState({ id: null, metadata: null });
const [done, setDone] = useState(false);
const accountId = useRef(null);
const insertAccountToStorage = useCallback(async (pubkey, privkey, metadata) => {
const { createAccount } = await import('@utils/bindings');
createAccount({ pubkey: pubkey, privkey: privkey, metadata: JSON.stringify(metadata) }).then(
(res) => (accountId.current = res.id)
);
createAccount({ pubkey: pubkey, privkey: privkey, metadata: metadata })
.then((res) =>
setProfile({
id: res.id,
metadata: JSON.parse(res.metadata),
})
)
.catch(console.error);
}, []);
const insertFollowsToStorage = useCallback(
async (tags) => {
const { createFollow } = await import('@utils/bindings');
if (accountId.current !== null) {
if (profile?.id !== null) {
for (const tag of tags) {
const metadata: any = await fetchMetadata(tag[1], pool, relays);
createFollow({ pubkey: tag[1], kind: 0, metadata: metadata.content, account_id: accountId.current });
createFollow({ pubkey: tag[1], kind: 0, metadata: metadata.content, account_id: profile.id }).catch(
console.error
);
}
}
},
[pool, relays]
[pool, profile.id, relays]
);
useEffect(() => {
@@ -64,7 +71,6 @@ export default function Page() {
relays,
(event: any) => {
if (event.kind === 0) {
setProfile(JSON.parse(event.content));
insertAccountToStorage(pubkey, privkey, event.content);
} else {
if (event.tags.length > 0) {
@@ -75,9 +81,6 @@ export default function Page() {
undefined,
() => {
setDone(true);
},
{
unsubscribeOnEose: true,
}
);
@@ -106,13 +109,20 @@ export default function Page() {
<div className="w-full rounded-lg bg-zinc-900 p-4 shadow-input ring-1 ring-zinc-800">
<div className="flex space-x-4">
<div className="relative h-10 w-10 rounded-full">
<Image className="inline-block rounded-full" src={profile?.picture} alt="" fill={true} />
<Image
className="inline-block rounded-full"
src={profile.metadata?.picture || DEFAULT_AVATAR}
alt=""
fill={true}
/>
</div>
<div className="flex-1 space-y-4 py-1">
<div className="flex items-center gap-2">
<p className="font-semibold">{profile?.display_name || profile?.name}</p>
<p className="font-semibold">{profile.metadata?.display_name || profile.metadata?.name}</p>
<span className="leading-tight text-zinc-500">·</span>
<p className="text-zinc-500">@{profile?.username || (pubkey && truncate(pubkey, 16, ' .... '))}</p>
<p className="text-zinc-500">
@{profile.metadata?.username || (pubkey && truncate(pubkey, 16, ' .... '))}
</p>
</div>
<div className="space-y-3">
<div className="grid grid-cols-3 gap-4">