feat: readd for you column
This commit is contained in:
@@ -28,7 +28,7 @@ const persister = createSyncStoragePersister({
|
||||
|
||||
const ark = new Ark();
|
||||
const platformName = await platform();
|
||||
const osLocale = (await locale()).slice(0, 2);
|
||||
const osLocale = await locale();
|
||||
|
||||
// Set up a Router instance
|
||||
const router = createRouter({
|
||||
@@ -37,6 +37,8 @@ const router = createRouter({
|
||||
platform: platformName,
|
||||
locale: osLocale,
|
||||
settings: null,
|
||||
accounts: null,
|
||||
interests: null,
|
||||
ark,
|
||||
queryClient,
|
||||
},
|
||||
|
||||
@@ -19,7 +19,7 @@ const DEFAULT_COLUMNS: LumeColumn[] = [
|
||||
];
|
||||
|
||||
function Screen() {
|
||||
const search = Route.useSearch();
|
||||
const { account } = Route.useParams();
|
||||
const vlistRef = useRef<VListHandle>(null);
|
||||
|
||||
const [columns, setColumns] = useState(DEFAULT_COLUMNS);
|
||||
@@ -139,8 +139,7 @@ function Screen() {
|
||||
<Col
|
||||
key={column.id}
|
||||
column={column}
|
||||
// @ts-ignore, yolo !!!
|
||||
account={search.acccount}
|
||||
account={account}
|
||||
isScroll={isScroll}
|
||||
/>
|
||||
))}
|
||||
|
||||
@@ -5,6 +5,16 @@ import { Accounts } from "@/components/accounts";
|
||||
|
||||
export const Route = createFileRoute("/$account")({
|
||||
component: App,
|
||||
beforeLoad: async ({ params, context }) => {
|
||||
const ark = context.ark;
|
||||
const settings = await ark.get_settings(params.account);
|
||||
const interests = await ark.get_interest(params.account);
|
||||
|
||||
return {
|
||||
settings,
|
||||
interests,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
function App() {
|
||||
|
||||
@@ -7,7 +7,7 @@ import {
|
||||
import { type Ark } from "@lume/ark";
|
||||
import { type QueryClient } from "@tanstack/react-query";
|
||||
import { type Platform } from "@tauri-apps/plugin-os";
|
||||
import { Settings } from "@lume/types";
|
||||
import { Account, Interests, Settings } from "@lume/types";
|
||||
|
||||
interface RouterContext {
|
||||
ark: Ark;
|
||||
@@ -15,6 +15,8 @@ interface RouterContext {
|
||||
platform: Platform;
|
||||
locale: string;
|
||||
settings: Settings;
|
||||
interests: Interests;
|
||||
accounts: Account[];
|
||||
}
|
||||
|
||||
export const Route = createRootRouteWithContext<RouterContext>()({
|
||||
|
||||
@@ -221,12 +221,7 @@ function Screen() {
|
||||
</div>
|
||||
<div className="flex h-full min-h-0 w-full">
|
||||
<div className="flex h-full w-full flex-1 flex-col gap-2 px-2 pb-2">
|
||||
{reply_to && !quote ? (
|
||||
<div className="flex flex-col rounded-xl bg-white p-5 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-none dark:ring-1 dark:ring-white/5">
|
||||
<h3 className="font-medium">Reply to:</h3>
|
||||
<MentionNote eventId={reply_to} />
|
||||
</div>
|
||||
) : null}
|
||||
{reply_to && !quote ? <MentionNote eventId={reply_to} /> : null}
|
||||
<div className="h-full w-full flex-1 overflow-hidden overflow-y-auto rounded-xl bg-white p-5 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-none dark:ring-1 dark:ring-white/5">
|
||||
<Editable
|
||||
key={JSON.stringify(editorValue)}
|
||||
@@ -235,7 +230,9 @@ function Screen() {
|
||||
autoCorrect="none"
|
||||
spellCheck={false}
|
||||
renderElement={(props) => <Element {...props} />}
|
||||
placeholder={t("editor.placeholder")}
|
||||
placeholder={
|
||||
reply_to ? "Type your reply..." : t("editor.placeholder")
|
||||
}
|
||||
className="focus:outline-none"
|
||||
/>
|
||||
{target && filters.length > 0 && (
|
||||
|
||||
@@ -2,9 +2,9 @@ import { useEvent } from "@lume/ark";
|
||||
import { LoaderIcon } from "@lume/icons";
|
||||
import { Box, Container, Note, User } from "@lume/ui";
|
||||
import { createLazyFileRoute } from "@tanstack/react-router";
|
||||
import { WindowVirtualizer } from "virtua";
|
||||
import { ReplyList } from "./-components/replyList";
|
||||
import { Event } from "@lume/types";
|
||||
import { WindowVirtualizer } from "virtua";
|
||||
import { type Event } from "@lume/types";
|
||||
|
||||
export const Route = createLazyFileRoute("/events/$eventId")({
|
||||
component: Event,
|
||||
@@ -29,14 +29,14 @@ function Event() {
|
||||
}
|
||||
|
||||
return (
|
||||
<WindowVirtualizer>
|
||||
<Container withDrag>
|
||||
<Box className="px-3 pt-3">
|
||||
<Container withDrag>
|
||||
<Box className="px-3 pt-3 scrollbar-none">
|
||||
<WindowVirtualizer>
|
||||
<MainNote data={data} />
|
||||
{data ? <ReplyList eventId={eventId} /> : null}
|
||||
</Box>
|
||||
</Container>
|
||||
</WindowVirtualizer>
|
||||
</WindowVirtualizer>
|
||||
</Box>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,30 +1,60 @@
|
||||
import { RepostNote } from "@/components/repost";
|
||||
import { Suggest } from "@/components/suggest";
|
||||
import { TextNote } from "@/components/text";
|
||||
import { useEvents } from "@lume/ark";
|
||||
import { LoaderIcon, ArrowRightCircleIcon, InfoIcon } from "@lume/icons";
|
||||
import { Event, Kind } from "@lume/types";
|
||||
import { Column } from "@lume/ui";
|
||||
import { createLazyFileRoute } from "@tanstack/react-router";
|
||||
import { useInfiniteQuery } from "@tanstack/react-query";
|
||||
import { createFileRoute, redirect } from "@tanstack/react-router";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Virtualizer } from "virtua";
|
||||
|
||||
export const Route = createLazyFileRoute("/foryou")({
|
||||
export const Route = createFileRoute("/foryou")({
|
||||
beforeLoad: async ({ search, context }) => {
|
||||
const ark = context.ark;
|
||||
// @ts-ignore, useless !!!
|
||||
const interests = await ark.get_interest(search.account);
|
||||
|
||||
if (!interests) {
|
||||
throw redirect({
|
||||
to: "/interests",
|
||||
replace: false,
|
||||
search,
|
||||
});
|
||||
}
|
||||
|
||||
return {
|
||||
interests,
|
||||
};
|
||||
},
|
||||
component: Screen,
|
||||
});
|
||||
|
||||
export function Screen() {
|
||||
// @ts-ignore, just work!!!
|
||||
const { id, name, account } = Route.useSearch();
|
||||
const { ark, interests } = Route.useRouteContext();
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
data,
|
||||
hasNextPage,
|
||||
isLoading,
|
||||
isRefetching,
|
||||
isFetchingNextPage,
|
||||
fetchNextPage,
|
||||
} = useEvents("local", account);
|
||||
const { data, isLoading, isFetchingNextPage, hasNextPage, fetchNextPage } =
|
||||
useInfiniteQuery({
|
||||
queryKey: ["foryou", account],
|
||||
initialPageParam: 0,
|
||||
queryFn: async ({ pageParam }: { pageParam: number }) => {
|
||||
const events = await ark.get_events_from_interests(
|
||||
interests.hashtags,
|
||||
20,
|
||||
pageParam,
|
||||
true,
|
||||
);
|
||||
return events;
|
||||
},
|
||||
getNextPageParam: (lastPage) => {
|
||||
const lastEvent = lastPage?.at(-1);
|
||||
return lastEvent ? lastEvent.created_at - 1 : null;
|
||||
},
|
||||
select: (data) => data?.pages.flatMap((page) => page),
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
|
||||
const renderItem = (event: Event) => {
|
||||
if (!event) return;
|
||||
@@ -40,17 +70,23 @@ export function Screen() {
|
||||
<Column.Root>
|
||||
<Column.Header id={id} name={name} />
|
||||
<Column.Content>
|
||||
{isLoading || isRefetching ? (
|
||||
{isLoading ? (
|
||||
<div className="flex h-20 w-full flex-col items-center justify-center gap-1">
|
||||
<LoaderIcon className="size-5 animate-spin" />
|
||||
<button type="button" className="size-5" disabled>
|
||||
<LoaderIcon className="size-5 animate-spin" />
|
||||
</button>
|
||||
</div>
|
||||
) : !data.length ? (
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="flex items-center gap-2 rounded-xl bg-neutral-50 p-5 dark:bg-neutral-950">
|
||||
<div className="flex flex-col gap-3 p-3">
|
||||
<div className="flex items-center gap-2 rounded-xl bg-neutral-100 p-5 dark:bg-neutral-900">
|
||||
<InfoIcon className="size-6" />
|
||||
<div>
|
||||
<p className="leading-tight">{t("emptyFeedTitle")}</p>
|
||||
<p className="leading-tight">{t("emptyFeedSubtitle")}</p>
|
||||
<p className="font-medium leading-tight">
|
||||
{t("global.emptyFeedTitle")}
|
||||
</p>
|
||||
<p className="leading-tight text-neutral-700 dark:text-neutral-300">
|
||||
{t("global.emptyFeedSubtitle")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Suggest />
|
||||
@@ -60,12 +96,13 @@ export function Screen() {
|
||||
{data.map((item) => renderItem(item))}
|
||||
</Virtualizer>
|
||||
)}
|
||||
<div className="flex h-20 items-center justify-center">
|
||||
{hasNextPage ? (
|
||||
|
||||
{data?.length && hasNextPage ? (
|
||||
<div className="flex h-20 items-center justify-center">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => fetchNextPage()}
|
||||
disabled={!hasNextPage || isFetchingNextPage}
|
||||
disabled={isFetchingNextPage || isFetchingNextPage}
|
||||
className="inline-flex h-12 w-36 items-center justify-center gap-2 rounded-full bg-neutral-100 px-3 font-medium hover:bg-neutral-200 focus:outline-none dark:bg-neutral-900 dark:hover:bg-neutral-800"
|
||||
>
|
||||
{isFetchingNextPage ? (
|
||||
@@ -77,8 +114,8 @@ export function Screen() {
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</Column.Content>
|
||||
</Column.Root>
|
||||
);
|
||||
@@ -1,10 +1,10 @@
|
||||
import { RepostNote } from "@/components/repost";
|
||||
import { Suggest } from "@/components/suggest";
|
||||
import { TextNote } from "@/components/text";
|
||||
import { useEvents } from "@lume/ark";
|
||||
import { LoaderIcon, ArrowRightCircleIcon, InfoIcon } from "@lume/icons";
|
||||
import { Event, Kind } from "@lume/types";
|
||||
import { Column } from "@lume/ui";
|
||||
import { useInfiniteQuery } from "@tanstack/react-query";
|
||||
import { createLazyFileRoute } from "@tanstack/react-router";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { Virtualizer } from "virtua";
|
||||
@@ -16,15 +16,23 @@ export const Route = createLazyFileRoute("/global")({
|
||||
export function Screen() {
|
||||
// @ts-ignore, just work!!!
|
||||
const { id, name, account } = Route.useSearch();
|
||||
const { ark } = Route.useRouteContext();
|
||||
const { t } = useTranslation();
|
||||
const {
|
||||
data,
|
||||
hasNextPage,
|
||||
isLoading,
|
||||
isRefetching,
|
||||
isFetchingNextPage,
|
||||
fetchNextPage,
|
||||
} = useEvents("global", account);
|
||||
const { data, isLoading, isFetchingNextPage, hasNextPage, fetchNextPage } =
|
||||
useInfiniteQuery({
|
||||
queryKey: ["global", account],
|
||||
initialPageParam: 0,
|
||||
queryFn: async ({ pageParam }: { pageParam: number }) => {
|
||||
const events = await ark.get_events(20, pageParam, undefined, true);
|
||||
return events;
|
||||
},
|
||||
getNextPageParam: (lastPage) => {
|
||||
const lastEvent = lastPage?.at(-1);
|
||||
return lastEvent ? lastEvent.created_at - 1 : null;
|
||||
},
|
||||
select: (data) => data?.pages.flatMap((page) => page),
|
||||
refetchOnWindowFocus: false,
|
||||
});
|
||||
|
||||
const renderItem = (event: Event) => {
|
||||
if (!event) return;
|
||||
@@ -40,17 +48,23 @@ export function Screen() {
|
||||
<Column.Root>
|
||||
<Column.Header id={id} name={name} />
|
||||
<Column.Content>
|
||||
{isLoading || isRefetching ? (
|
||||
{isLoading ? (
|
||||
<div className="flex h-20 w-full flex-col items-center justify-center gap-1">
|
||||
<LoaderIcon className="size-5 animate-spin" />
|
||||
<button type="button" className="size-5" disabled>
|
||||
<LoaderIcon className="size-5 animate-spin" />
|
||||
</button>
|
||||
</div>
|
||||
) : !data.length ? (
|
||||
<div className="flex flex-col gap-3">
|
||||
<div className="flex items-center gap-2 rounded-xl bg-neutral-50 p-5 dark:bg-neutral-950">
|
||||
<div className="flex flex-col gap-3 p-3">
|
||||
<div className="flex items-center gap-2 rounded-xl bg-neutral-100 p-5 dark:bg-neutral-900">
|
||||
<InfoIcon className="size-6" />
|
||||
<div>
|
||||
<p className="leading-tight">{t("emptyFeedTitle")}</p>
|
||||
<p className="leading-tight">{t("emptyFeedSubtitle")}</p>
|
||||
<p className="font-medium leading-tight">
|
||||
{t("global.emptyFeedTitle")}
|
||||
</p>
|
||||
<p className="leading-tight text-neutral-700 dark:text-neutral-300">
|
||||
{t("global.emptyFeedSubtitle")}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<Suggest />
|
||||
@@ -60,12 +74,13 @@ export function Screen() {
|
||||
{data.map((item) => renderItem(item))}
|
||||
</Virtualizer>
|
||||
)}
|
||||
<div className="flex h-20 items-center justify-center">
|
||||
{hasNextPage ? (
|
||||
|
||||
{data?.length && hasNextPage ? (
|
||||
<div className="flex h-20 items-center justify-center">
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => fetchNextPage()}
|
||||
disabled={!hasNextPage || isFetchingNextPage}
|
||||
disabled={isFetchingNextPage || isFetchingNextPage}
|
||||
className="inline-flex h-12 w-36 items-center justify-center gap-2 rounded-full bg-neutral-100 px-3 font-medium hover:bg-neutral-200 focus:outline-none dark:bg-neutral-900 dark:hover:bg-neutral-800"
|
||||
>
|
||||
{isFetchingNextPage ? (
|
||||
@@ -77,8 +92,8 @@ export function Screen() {
|
||||
</>
|
||||
)}
|
||||
</button>
|
||||
) : null}
|
||||
</div>
|
||||
</div>
|
||||
) : null}
|
||||
</Column.Content>
|
||||
</Column.Root>
|
||||
);
|
||||
|
||||
@@ -5,7 +5,7 @@ import { createFileRoute, redirect, useNavigate } from "@tanstack/react-router";
|
||||
import { useState } from "react";
|
||||
|
||||
export const Route = createFileRoute("/")({
|
||||
beforeLoad: async ({ search, context }) => {
|
||||
beforeLoad: async ({ context }) => {
|
||||
const ark = context.ark;
|
||||
const accounts = await ark.get_all_accounts();
|
||||
|
||||
@@ -18,15 +18,8 @@ export const Route = createFileRoute("/")({
|
||||
});
|
||||
// Only 1 account, skip account selection screen
|
||||
case 1:
|
||||
// @ts-ignore, totally fine !!!
|
||||
if (search.manually) return;
|
||||
|
||||
const account = accounts[0].npub;
|
||||
const loadedAccount = await ark.load_selected_account(account);
|
||||
const settings = await ark.get_settings(account);
|
||||
|
||||
// Update settings
|
||||
context.settings = settings;
|
||||
|
||||
if (loadedAccount) {
|
||||
throw redirect({
|
||||
@@ -37,7 +30,7 @@ export const Route = createFileRoute("/")({
|
||||
}
|
||||
// Account selection
|
||||
default:
|
||||
return;
|
||||
return { accounts };
|
||||
}
|
||||
},
|
||||
component: Screen,
|
||||
@@ -51,11 +44,12 @@ function Screen() {
|
||||
|
||||
const select = async (npub: string) => {
|
||||
setLoading(true);
|
||||
const loadAccount = await context.ark.load_selected_account(npub);
|
||||
context.settings = await context.ark.get_settings(npub);
|
||||
|
||||
const ark = context.ark;
|
||||
const loadAccount = await ark.load_selected_account(npub);
|
||||
|
||||
if (loadAccount) {
|
||||
navigate({
|
||||
return navigate({
|
||||
to: "/$account/home",
|
||||
params: { account: npub },
|
||||
replace: true,
|
||||
@@ -83,7 +77,7 @@ function Screen() {
|
||||
</div>
|
||||
) : (
|
||||
<>
|
||||
{context.ark.accounts.map((account) => (
|
||||
{context.accounts.map((account) => (
|
||||
<button
|
||||
type="button"
|
||||
key={account.npub}
|
||||
|
||||
115
apps/desktop2/src/routes/interests.lazy.tsx
Normal file
115
apps/desktop2/src/routes/interests.lazy.tsx
Normal file
@@ -0,0 +1,115 @@
|
||||
import { Column } from "@lume/ui";
|
||||
import { TOPICS, cn } from "@lume/utils";
|
||||
import { createLazyFileRoute } from "@tanstack/react-router";
|
||||
import { useState } from "react";
|
||||
import { useTranslation } from "react-i18next";
|
||||
import { toast } from "sonner";
|
||||
|
||||
export const Route = createLazyFileRoute("/interests")({
|
||||
component: Screen,
|
||||
});
|
||||
|
||||
function Screen() {
|
||||
const { t } = useTranslation();
|
||||
|
||||
const [hashtags, setHashtags] = useState<string[]>([]);
|
||||
const [isDone, setIsDone] = useState(false);
|
||||
|
||||
const context = Route.useRouteContext();
|
||||
const search = Route.useSearch();
|
||||
|
||||
const toggleHashtag = (item: string) => {
|
||||
const arr = hashtags.includes(item)
|
||||
? hashtags.filter((i) => i !== item)
|
||||
: [...hashtags, item];
|
||||
setHashtags(arr);
|
||||
};
|
||||
|
||||
const toggleAll = (item: string[]) => {
|
||||
const sets = new Set([...hashtags, ...item]);
|
||||
setHashtags([...sets]);
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
try {
|
||||
if (isDone) {
|
||||
return history.back();
|
||||
}
|
||||
|
||||
const ark = context.ark;
|
||||
const eventId = await ark.set_interest(undefined, undefined, hashtags);
|
||||
|
||||
if (eventId) {
|
||||
setIsDone(true);
|
||||
toast.success("Interest has been updated successfully.");
|
||||
}
|
||||
} catch (e) {
|
||||
toast.error(String(e));
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<Column.Root>
|
||||
<Column.Header id={search.id} name={search.name} />
|
||||
<Column.Content>
|
||||
<div className="sticky left-0 top-0 flex h-16 w-full items-center justify-between border-b border-neutral-100 bg-white px-3 dark:border-neutral-900 dark:bg-black">
|
||||
<div className="flex flex-1 flex-col">
|
||||
<h3 className="font-semibold">Interests</h3>
|
||||
<p className="text-sm leading-tight text-neutral-700 dark:text-neutral-300">
|
||||
Pick things you'd like to see.
|
||||
</p>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={submit}
|
||||
className="inline-flex h-8 w-20 items-center justify-center rounded-full bg-blue-500 px-2 text-sm font-medium text-white hover:bg-blue-600 disabled:opacity-50"
|
||||
>
|
||||
{isDone ? t("global.back") : t("global.update")}
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex w-full flex-col p-3">
|
||||
<div className="flex flex-col gap-8">
|
||||
{TOPICS.map((topic) => (
|
||||
<div key={topic.title} className="flex flex-col gap-4">
|
||||
<div className="flex w-full items-center justify-between">
|
||||
<div className="inline-flex items-center gap-2.5">
|
||||
<img
|
||||
src={topic.icon}
|
||||
alt={topic.title}
|
||||
className="size-8 rounded-lg object-cover"
|
||||
/>
|
||||
<h3 className="text-lg font-semibold">{topic.title}</h3>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={() => toggleAll(topic.content)}
|
||||
className="text-sm font-medium text-neutral-700 dark:text-neutral-300"
|
||||
>
|
||||
{t("interests.followAll")}
|
||||
</button>
|
||||
</div>
|
||||
<div className="flex flex-wrap items-center gap-3">
|
||||
{topic.content.map((hashtag) => (
|
||||
<button
|
||||
key={hashtag}
|
||||
type="button"
|
||||
onClick={() => toggleHashtag(hashtag)}
|
||||
className={cn(
|
||||
"inline-flex items-center rounded-full border border-transparent bg-neutral-100 px-2 py-1 text-sm font-medium dark:bg-neutral-900",
|
||||
hashtags.includes(hashtag)
|
||||
? "border-blue-500 text-blue-500"
|
||||
: "",
|
||||
)}
|
||||
>
|
||||
{hashtag}
|
||||
</button>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</Column.Content>
|
||||
</Column.Root>
|
||||
);
|
||||
}
|
||||
@@ -23,13 +23,12 @@ export function Screen() {
|
||||
queryKey: ["local", account],
|
||||
initialPageParam: 0,
|
||||
queryFn: async ({ pageParam }: { pageParam: number }) => {
|
||||
const events = await ark.get_events("local", 20, pageParam, true);
|
||||
const events = await ark.get_events(20, pageParam);
|
||||
return events;
|
||||
},
|
||||
getNextPageParam: (lastPage) => {
|
||||
const lastEvent = lastPage?.at(-1);
|
||||
if (!lastEvent) return;
|
||||
return lastEvent.created_at - 1;
|
||||
return lastEvent ? lastEvent.created_at - 1 : null;
|
||||
},
|
||||
select: (data) => data?.pages.flatMap((page) => page),
|
||||
refetchOnWindowFocus: false,
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { ArrowRightIcon, ZapIcon } from "@lume/icons";
|
||||
import { ZapIcon } from "@lume/icons";
|
||||
import { Container } from "@lume/ui";
|
||||
import { createLazyFileRoute } from "@tanstack/react-router";
|
||||
import { useState } from "react";
|
||||
@@ -15,14 +15,11 @@ function Screen() {
|
||||
|
||||
const save = async () => {
|
||||
const nwc = await ark.set_nwc(uri);
|
||||
|
||||
if (nwc) {
|
||||
setIsDone(true);
|
||||
}
|
||||
setIsDone(nwc);
|
||||
};
|
||||
|
||||
return (
|
||||
<Container withDrag>
|
||||
<Container withDrag withNavigate={false}>
|
||||
<div className="h-full w-full flex-1 px-5">
|
||||
{!isDone ? (
|
||||
<>
|
||||
@@ -44,17 +41,15 @@ function Screen() {
|
||||
value={uri}
|
||||
onChange={(e) => setUri(e.target.value)}
|
||||
placeholder="nostrconnect://"
|
||||
className="h-24 w-full resize-none rounded-lg border-transparent bg-white placeholder:text-neutral-600 focus:border-blue-500 focus:ring focus:ring-blue-100 dark:bg-black dark:focus:ring-blue-900"
|
||||
className="h-24 w-full rounded-lg border-neutral-300 bg-transparent px-3 placeholder:text-neutral-500 focus:border-blue-500 focus:ring focus:ring-blue-200 dark:border-neutral-700 dark:placeholder:text-neutral-400 dark:focus:ring-blue-800"
|
||||
/>
|
||||
</div>
|
||||
<button
|
||||
type="button"
|
||||
onClick={save}
|
||||
className="inline-flex h-11 w-full items-center justify-between gap-1.5 rounded-lg bg-blue-500 px-5 font-medium text-white hover:bg-blue-600"
|
||||
className="inline-flex h-11 w-full items-center justify-center gap-1.5 rounded-lg bg-blue-500 px-5 font-medium text-white hover:bg-blue-600"
|
||||
>
|
||||
<div className="size-5" />
|
||||
<div>Save & Connect</div>
|
||||
<ArrowRightIcon className="size-5" />
|
||||
Save & Connect
|
||||
</button>
|
||||
</div>
|
||||
</>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { createLazyFileRoute } from "@tanstack/react-router";
|
||||
import { WindowVirtualizer } from "virtua";
|
||||
import { User } from "@lume/ui";
|
||||
import { Box, Container, User } from "@lume/ui";
|
||||
import { EventList } from "./-components/eventList";
|
||||
|
||||
export const Route = createLazyFileRoute("/users/$pubkey")({
|
||||
@@ -11,36 +11,33 @@ function Screen() {
|
||||
const { pubkey } = Route.useParams();
|
||||
|
||||
return (
|
||||
<WindowVirtualizer>
|
||||
<div className="flex h-screen w-screen flex-col bg-gradient-to-tr from-neutral-200 to-neutral-100 dark:from-neutral-950 dark:to-neutral-900">
|
||||
<div data-tauri-drag-region className="h-11 w-full shrink-0" />
|
||||
<div className="flex h-full min-h-0 w-full">
|
||||
<div className="h-full w-full flex-1 px-2 pb-2">
|
||||
<div className="h-full w-full overflow-hidden overflow-y-auto rounded-xl 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-none dark:ring-1 dark:ring-white/5">
|
||||
<User.Provider pubkey={pubkey}>
|
||||
<User.Root>
|
||||
<User.Cover className="h-44 w-full object-cover" />
|
||||
<div className="relative -mt-8 flex flex-col gap-4 px-5">
|
||||
<User.Avatar className="size-14 rounded-full" />
|
||||
<div className="inline-flex items-start justify-between">
|
||||
<div>
|
||||
<User.Name className="font-semibold leading-tight" />
|
||||
<User.NIP05 className="text-sm leading-tight text-neutral-600 dark:text-neutral-400" />
|
||||
</div>
|
||||
<User.Button className="h-9 w-24 rounded-full bg-black text-sm font-medium text-white hover:bg-neutral-900 dark:bg-neutral-900" />
|
||||
</div>
|
||||
<User.About />
|
||||
<Container withDrag>
|
||||
<Box className="px-0 scrollbar-none">
|
||||
<WindowVirtualizer>
|
||||
<User.Provider pubkey={pubkey}>
|
||||
<User.Root>
|
||||
<User.Cover className="h-44 w-full object-cover" />
|
||||
<div className="relative -mt-8 flex flex-col gap-4 px-3">
|
||||
<User.Avatar className="size-14 rounded-full" />
|
||||
<div className="inline-flex items-start justify-between">
|
||||
<div>
|
||||
<User.Name className="font-semibold leading-tight" />
|
||||
<User.NIP05 className="text-sm leading-tight text-neutral-600 dark:text-neutral-400" />
|
||||
</div>
|
||||
</User.Root>
|
||||
</User.Provider>
|
||||
<div className="mt-4 px-5">
|
||||
<h3 className="mb-4 text-lg font-semibold">Notes</h3>
|
||||
<EventList id={pubkey} />
|
||||
<User.Button className="h-9 w-24 rounded-full bg-black text-sm font-medium text-white hover:bg-neutral-900 dark:bg-neutral-900" />
|
||||
</div>
|
||||
<User.About />
|
||||
</div>
|
||||
</User.Root>
|
||||
</User.Provider>
|
||||
<div className="mt-4">
|
||||
<div className="px-3">
|
||||
<h3 className="text-lg font-semibold">Latest notes</h3>
|
||||
</div>
|
||||
<EventList id={pubkey} />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</WindowVirtualizer>
|
||||
</WindowVirtualizer>
|
||||
</Box>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user