fix(layout): fix flickering on home layout

This commit is contained in:
reya 2023-12-14 14:30:49 +07:00
parent 2fcc4dead1
commit 591373fd52
7 changed files with 77 additions and 169 deletions

View File

@ -83,8 +83,7 @@
"sonner": "^1.2.4",
"tippy.js": "^6.3.7",
"tiptap-markdown": "^0.8.8",
"virtua": "^0.17.5",
"zustand": "^4.4.7"
"virtua": "^0.17.5"
},
"devDependencies": {
"@tailwindcss/forms": "^0.5.7",

View File

@ -203,9 +203,6 @@ dependencies:
virtua:
specifier: ^0.17.5
version: 0.17.5(react-dom@18.2.0)(react@18.2.0)
zustand:
specifier: ^4.4.7
version: 4.4.7(@types/react@18.2.43)(react@18.2.0)
devDependencies:
'@tailwindcss/forms':
@ -5967,14 +5964,6 @@ packages:
tslib: 2.6.2
dev: false
/use-sync-external-store@1.2.0(react@18.2.0):
resolution: {integrity: sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==}
peerDependencies:
react: ^16.8.0 || ^17.0.0 || ^18.0.0
dependencies:
react: 18.2.0
dev: false
/utf-8-validate@5.0.10:
resolution: {integrity: sha512-Z6czzLq4u8fPOyx7TU6X3dvUZVvoJmxSQ+IcrlmagKhilxlhZgxPK6C5Jqbkw1IDUmFTM+cz9QDnnLTwDz/2gQ==}
engines: {node: '>=6.14.2'}
@ -6193,23 +6182,3 @@ packages:
resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==}
engines: {node: '>=10'}
dev: true
/zustand@4.4.7(@types/react@18.2.43)(react@18.2.0):
resolution: {integrity: sha512-QFJWJMdlETcI69paJwhSMJz7PPWjVP8Sjhclxmxmxv/RYI7ZOvR5BHX+ktH0we9gTWQMxcne8q1OY8xxz604gw==}
engines: {node: '>=12.7.0'}
peerDependencies:
'@types/react': '>=16.8'
immer: '>=9.0'
react: '>=16.8'
peerDependenciesMeta:
'@types/react':
optional: true
immer:
optional: true
react:
optional: true
dependencies:
'@types/react': 18.2.43
react: 18.2.0
use-sync-external-store: 1.2.0(react@18.2.0)
dev: false

View File

@ -1,4 +1,5 @@
import { fetch } from '@tauri-apps/plugin-http';
import { nip19 } from 'nostr-tools';
import { RouterProvider, createBrowserRouter, defer, redirect } from 'react-router-dom';
import { ErrorScreen } from '@app/error';
import { useArk } from '@libs/ark';
@ -43,6 +44,21 @@ export default function App() {
return { Component: HomeScreen };
},
},
{
path: ':address',
loader: ({ params }) => {
const address = params.address;
const decode = nip19.decode(address);
if (decode.type === 'npub') return redirect(`/users/${decode.data}`);
if (decode.type === 'nprofile')
return redirect(`/users/${decode.data.pubkey}`);
if (decode.type === 'note') return redirect(`/events/${decode.data}`);
if (decode.type === 'nrelay') return redirect(`/relays/${decode.data}`);
if (decode.type === 'nevent')
return redirect(`/relays/${decode.data.id}`);
return null;
},
},
{
path: 'nwc',
async lazy() {
@ -65,20 +81,6 @@ export default function App() {
return { Component: RelayScreen };
},
},
{
path: 'users/:pubkey',
async lazy() {
const { UserScreen } = await import('@app/users');
return { Component: UserScreen };
},
},
{
path: 'events/:id',
async lazy() {
const { TextNoteScreen } = await import('@app/notes/text');
return { Component: TextNoteScreen };
},
},
{
path: 'new',
element: <ComposerLayout />,

View File

@ -93,44 +93,46 @@ export function HomeScreen() {
}
return (
<VList
ref={ref}
className="h-full w-full flex-nowrap overflow-x-auto !overflow-y-hidden scrollbar-none focus:outline-none"
initialItemSize={420}
tabIndex={0}
horizontal
onKeyDown={(e) => {
if (!ref.current) return;
switch (e.code) {
case 'ArrowUp':
case 'ArrowLeft': {
e.preventDefault();
const prevIndex = Math.max(selectedIndex - 1, 0);
setSelectedIndex(prevIndex);
ref.current.scrollToIndex(prevIndex, {
align: 'center',
smooth: true,
});
break;
<div className="h-full w-full">
<VList
ref={ref}
className="h-full w-full flex-nowrap overflow-x-auto !overflow-y-hidden scrollbar-none focus:outline-none"
initialItemSize={420}
tabIndex={0}
horizontal
onKeyDown={(e) => {
if (!ref.current) return;
switch (e.code) {
case 'ArrowUp':
case 'ArrowLeft': {
e.preventDefault();
const prevIndex = Math.max(selectedIndex - 1, 0);
setSelectedIndex(prevIndex);
ref.current.scrollToIndex(prevIndex, {
align: 'center',
smooth: true,
});
break;
}
case 'ArrowDown':
case 'ArrowRight': {
e.preventDefault();
const nextIndex = Math.min(selectedIndex + 1, data.length - 1);
setSelectedIndex(nextIndex);
ref.current.scrollToIndex(nextIndex, {
align: 'center',
smooth: true,
});
break;
}
default:
break;
}
case 'ArrowDown':
case 'ArrowRight': {
e.preventDefault();
const nextIndex = Math.min(selectedIndex + 1, data.length - 1);
setSelectedIndex(nextIndex);
ref.current.scrollToIndex(nextIndex, {
align: 'center',
smooth: true,
});
break;
}
default:
break;
}
}}
>
{data.map((widget) => renderItem(widget))}
<ToggleWidgetList />
</VList>
}}
>
{data.map((widget) => renderItem(widget))}
<ToggleWidgetList />
</VList>
</div>
);
}

View File

@ -43,6 +43,7 @@ export class Ark {
readonly platform: Platform | null;
readonly settings: {
autoupdate: boolean;
bunker: boolean;
outbox: boolean;
media: boolean;
hashtag: boolean;
@ -53,6 +54,7 @@ export class Ark {
this.platform = platform;
this.settings = {
autoupdate: false,
bunker: false,
outbox: false,
media: true,
hashtag: true,
@ -100,7 +102,7 @@ export class Ark {
const bunker = new NDK({
explicitRelayUrls: ['wss://relay.nsecbunker.com', 'wss://nostr.vulpem.com'],
});
await bunker.connect();
await bunker.connect(3000);
const remoteSigner = new NDKNip46Signer(bunker, this.account.pubkey, localSigner);
await remoteSigner.blockUntilReady();
@ -134,11 +136,14 @@ export class Ark {
}
public async init() {
const outboxSetting = await this.getSettingValue('outbox');
const bunkerSetting = await this.getSettingValue('nsecbunker');
const bunker = !!parseInt(bunkerSetting);
const enableOutboxModel = !!parseInt(outboxSetting);
const settings = await this.getAllSettings();
for (const item of settings) {
if (item.key === 'nsecbunker') this.settings.bunker = !!parseInt(item.value);
if (item.key === 'outbox') this.settings.outbox = !!parseInt(item.value);
if (item.key === 'media') this.settings.media = !!parseInt(item.value);
if (item.key === 'hashtag') this.settings.hashtag = !!parseInt(item.value);
if (item.key === 'autoupdate') this.settings.autoupdate = !!parseInt(item.value);
}
const explicitRelayUrls = normalizeRelayUrlSet([
'wss://relay.damus.io',
@ -159,7 +164,7 @@ export class Ark {
explicitRelayUrls,
outboxRelayUrls,
blacklistRelayUrls,
enableOutboxModel,
enableOutboxModel: this.settings.outbox,
autoConnectUserRelays: true,
autoFetchUserMutelist: true,
// clientName: 'Lume',
@ -167,11 +172,11 @@ export class Ark {
});
// add signer if exist
const signer = await this.#initNostrSigner({ nsecbunker: bunker });
const signer = await this.#initNostrSigner({ nsecbunker: this.settings.bunker });
if (signer) ndk.signer = signer;
// connect
await ndk.connect();
await ndk.connect(5000);
const fetcher = NostrFetcher.withCustomPool(ndkAdapter(ndk));
// update account's metadata
@ -356,7 +361,7 @@ export class Ark {
const results: { key: string; value: string }[] = await this.#storage.select(
'SELECT * FROM settings ORDER BY id DESC;'
);
if (results.length < 1) return null;
if (results.length < 1) return [];
return results;
}

View File

@ -1,5 +1,3 @@
import { NDKKind } from '@nostr-dev-kit/ndk';
import { useQueryClient } from '@tanstack/react-query';
import { ask } from '@tauri-apps/plugin-dialog';
import { platform } from '@tauri-apps/plugin-os';
import { relaunch } from '@tauri-apps/plugin-process';
@ -9,7 +7,7 @@ import Markdown from 'markdown-to-jsx';
import { PropsWithChildren, createContext, useContext, useEffect, useState } from 'react';
import { Ark } from '@libs/ark';
import { LoaderIcon } from '@shared/icons';
import { FETCH_LIMIT, QUOTES } from '@utils/constants';
import { QUOTES } from '@utils/constants';
const ArkContext = createContext<Ark>(undefined);
@ -17,8 +15,6 @@ const ArkProvider = ({ children }: PropsWithChildren<object>) => {
const [ark, setArk] = useState<Ark>(undefined);
const [isNewVersion, setIsNewVersion] = useState(false);
const queryClient = useQueryClient();
async function initArk() {
try {
const sqlite = await Database.load('sqlite:lume_v2.db');
@ -27,24 +23,7 @@ const ArkProvider = ({ children }: PropsWithChildren<object>) => {
const _ark = new Ark({ storage: sqlite, platform: platformName });
await _ark.init();
const settings = await _ark.getAllSettings();
let autoUpdater = false;
if (settings) {
settings.forEach((item) => {
if (item.key === 'outbox') _ark.settings.outbox = !!parseInt(item.value);
if (item.key === 'media') _ark.settings.media = !!parseInt(item.value);
if (item.key === 'hashtag') _ark.settings.hashtag = !!parseInt(item.value);
if (item.key === 'autoupdate') {
if (parseInt(item.value)) autoUpdater = true;
}
});
}
if (autoUpdater) {
if (_ark.settings.autoupdate) {
// check update
const update = await check();
// install new version
@ -56,56 +35,6 @@ const ArkProvider = ({ children }: PropsWithChildren<object>) => {
}
}
if (_ark.account) {
// prefetch newsfeed
await queryClient.prefetchInfiniteQuery({
queryKey: ['newsfeed'],
initialPageParam: 0,
queryFn: async ({
signal,
pageParam,
}: {
signal: AbortSignal;
pageParam: number;
}) => {
return await ark.getInfiniteEvents({
filter: {
kinds: [NDKKind.Text, NDKKind.Repost],
authors: !ark.account.contacts.length
? [ark.account.pubkey]
: ark.account.contacts,
},
limit: FETCH_LIMIT,
pageParam,
signal,
});
},
});
// prefetch notification
await queryClient.prefetchInfiniteQuery({
queryKey: ['notification'],
initialPageParam: 0,
queryFn: async ({
signal,
pageParam,
}: {
signal: AbortSignal;
pageParam: number;
}) => {
return await ark.getInfiniteEvents({
filter: {
kinds: [NDKKind.Text, NDKKind.Repost, NDKKind.Reaction, NDKKind.Zap],
'#p': [ark.account.pubkey],
},
limit: FETCH_LIMIT,
pageParam,
signal,
});
},
});
}
setArk(_ark);
} catch (e) {
console.error(e);

View File

@ -4,7 +4,9 @@ import { Navigation } from '@shared/navigation';
export function HomeLayout() {
return (
<div className="flex h-full w-full">
<Navigation />
<div className="w-[68px] shrink-0">
<Navigation />
</div>
<div className="min-h-0 flex-1 rounded-tl-lg bg-white shadow-[rgba(50,_50,_105,_0.15)_0px_2px_5px_0px,_rgba(0,_0,_0,_0.05)_0px_1px_1px_0px] dark:bg-black dark:shadow-[inset_0_0_0.5px_1px_hsla(0,0%,100%,0.075),0_0_0_1px_hsla(0,0%,0%,0.05),0_0.3px_0.4px_hsla(0,0%,0%,0.02),0_0.9px_1.5px_hsla(0,0%,0%,0.045),0_3.5px_6px_hsla(0,0%,0%,0.09)]">
<Outlet />
</div>