feat: add waifu column and fix wrong package

This commit is contained in:
reya 2024-01-31 11:04:47 +07:00
parent ad488ff72d
commit 0539c5649d
28 changed files with 280 additions and 1496 deletions

View File

@ -17,6 +17,7 @@
"@columns/timeline": "workspace:^", "@columns/timeline": "workspace:^",
"@columns/trending-notes": "workspace:^", "@columns/trending-notes": "workspace:^",
"@columns/user": "workspace:^", "@columns/user": "workspace:^",
"@columns/waifu": "workspace:^",
"@getalby/sdk": "^3.2.3", "@getalby/sdk": "^3.2.3",
"@lume/ark": "workspace:^", "@lume/ark": "workspace:^",
"@lume/icons": "workspace:^", "@lume/icons": "workspace:^",

Binary file not shown.

After

Width:  |  Height:  |  Size: 121 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 457 KiB

View File

@ -8,6 +8,7 @@ import { Thread } from "@columns/thread";
import { Timeline } from "@columns/timeline"; import { Timeline } from "@columns/timeline";
import { TrendingNotes } from "@columns/trending-notes"; import { TrendingNotes } from "@columns/trending-notes";
import { User } from "@columns/user"; import { User } from "@columns/user";
import { Waifu } from "@columns/waifu";
import { useColumnContext } from "@lume/ark"; import { useColumnContext } from "@lume/ark";
import { import {
ArrowLeftIcon, ArrowLeftIcon,
@ -51,6 +52,8 @@ export function HomeScreen() {
return <Global key={column.id} column={column} />; return <Global key={column.id} column={column} />;
case COL_TYPES.trendingNotes: case COL_TYPES.trendingNotes:
return <TrendingNotes key={column.id} column={column} />; return <TrendingNotes key={column.id} column={column} />;
case COL_TYPES.waifu:
return <Waifu key={column.id} column={column} />;
default: default:
return <Default key={column.id} column={column} />; return <Default key={column.id} column={column} />;
} }

View File

@ -20,7 +20,7 @@
"@lume/tsconfig": "workspace:^", "@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^", "@lume/types": "workspace:^",
"@types/react": "^18.2.48", "@types/react": "^18.2.48",
"tailwind": "^4.0.0", "tailwindcss": "^3.4.1",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
} }

View File

@ -1,9 +1,8 @@
import { Column } from "@lume/ark"; import { Column } from "@lume/ark";
import { GroupFeedsIcon } from "@lume/icons";
import { IColumn } from "@lume/types"; import { IColumn } from "@lume/types";
import { EventRoute, UserRoute } from "@lume/ui";
import { AntenasForm } from "./components/form"; import { AntenasForm } from "./components/form";
import { HomeRoute } from "./home"; import { HomeRoute } from "./home";
import { EventRoute, UserRoute } from "@lume/ui";
export function Antenas({ column }: { column: IColumn }) { export function Antenas({ column }: { column: IColumn }) {
const colKey = `antenas-${column.id}`; const colKey = `antenas-${column.id}`;
@ -13,11 +12,7 @@ export function Antenas({ column }: { column: IColumn }) {
<Column.Root> <Column.Root>
{created ? ( {created ? (
<> <>
<Column.Header <Column.Header id={column.id} title={column.title} />
id={column.id}
title={column.title}
icon={<GroupFeedsIcon className="size-4" />}
/>
<Column.Content> <Column.Content>
<Column.Route <Column.Route
path="/" path="/"

View File

@ -20,7 +20,7 @@
"@lume/tsconfig": "workspace:^", "@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^", "@lume/types": "workspace:^",
"@types/react": "^18.2.48", "@types/react": "^18.2.48",
"tailwind": "^4.0.0", "tailwindcss": "^3.4.1",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
} }

View File

@ -8,8 +8,8 @@ export function Default({ column }: { column: IColumn }) {
return ( return (
<Column.Root> <Column.Root>
<Column.Header id={column.id} title="Add columns" /> <Column.Header id={column.id} title="Add columns" />
<div className="h-full px-3 mt-3 flex flex-col gap-3 overflow-y-auto scrollbar-none"> <div className="h-full flex-1 px-3 mt-3 flex flex-col gap-3 overflow-y-auto scrollbar-none">
<div className="h-11 flex items-center gap-5"> <div className="shrink-0 h-11 flex items-center gap-5">
<button <button
type="button" type="button"
className="h-9 w-max px-3 text-sm font-semibold inline-flex items-center justify-center bg-neutral-100 dark:bg-neutral-900 rounded-lg" className="h-9 w-max px-3 text-sm font-semibold inline-flex items-center justify-center bg-neutral-100 dark:bg-neutral-900 rounded-lg"
@ -24,7 +24,7 @@ export function Default({ column }: { column: IColumn }) {
Community (Coming Soon) Community (Coming Soon)
</button> </button>
</div> </div>
<div className="flex flex-col rounded-xl overflow-hidden bg-neutral-50 dark:bg-neutral-950 ring-1 ring-neutral-100 dark:ring-neutral-900"> <div className="shrink-0 flex flex-col rounded-xl overflow-hidden bg-neutral-50 dark:bg-neutral-950 ring-1 ring-neutral-100 dark:ring-neutral-900">
<div className="h-[100px] w-full px-3 pt-3"> <div className="h-[100px] w-full px-3 pt-3">
<img <img
src="/columns/group.jpg" src="/columns/group.jpg"
@ -53,7 +53,7 @@ export function Default({ column }: { column: IColumn }) {
</button> </button>
</div> </div>
</div> </div>
<div className="flex flex-col rounded-xl overflow-hidden bg-neutral-50 dark:bg-neutral-950 ring-1 ring-neutral-100 dark:ring-neutral-900"> <div className="shrink-0 flex flex-col rounded-xl overflow-hidden bg-neutral-50 dark:bg-neutral-950 ring-1 ring-neutral-100 dark:ring-neutral-900">
<div className="h-[100px] w-full px-3 pt-3"> <div className="h-[100px] w-full px-3 pt-3">
<img <img
src="/columns/antenas.jpg" src="/columns/antenas.jpg"
@ -82,7 +82,7 @@ export function Default({ column }: { column: IColumn }) {
</button> </button>
</div> </div>
</div> </div>
<div className="flex flex-col rounded-xl overflow-hidden bg-neutral-50 dark:bg-neutral-950 ring-1 ring-neutral-100 dark:ring-neutral-900"> <div className="shrink-0 flex flex-col rounded-xl overflow-hidden bg-neutral-50 dark:bg-neutral-950 ring-1 ring-neutral-100 dark:ring-neutral-900">
<div className="h-[100px] w-full px-3 pt-3"> <div className="h-[100px] w-full px-3 pt-3">
<img <img
src="/columns/trending-notes.jpg" src="/columns/trending-notes.jpg"
@ -97,7 +97,7 @@ export function Default({ column }: { column: IColumn }) {
<div> <div>
<h1 className="font-semibold">Trending Notes</h1> <h1 className="font-semibold">Trending Notes</h1>
<p className="max-w-[18rem] truncate text-sm text-neutral-600 dark:text-neutral-500"> <p className="max-w-[18rem] truncate text-sm text-neutral-600 dark:text-neutral-500">
What is trending on Nostr? What is trending on Nostr?.
</p> </p>
</div> </div>
<button <button
@ -115,7 +115,7 @@ export function Default({ column }: { column: IColumn }) {
</button> </button>
</div> </div>
</div> </div>
<div className="flex flex-col rounded-xl overflow-hidden bg-neutral-50 dark:bg-neutral-950 ring-1 ring-neutral-100 dark:ring-neutral-900"> <div className="shrink-0 flex flex-col rounded-xl overflow-hidden bg-neutral-50 dark:bg-neutral-950 ring-1 ring-neutral-100 dark:ring-neutral-900">
<div className="h-[100px] w-full px-3 pt-3"> <div className="h-[100px] w-full px-3 pt-3">
<img <img
src="/columns/global.jpg" src="/columns/global.jpg"
@ -130,7 +130,7 @@ export function Default({ column }: { column: IColumn }) {
<div> <div>
<h1 className="font-semibold">Global</h1> <h1 className="font-semibold">Global</h1>
<p className="max-w-[18rem] truncate text-sm text-neutral-600 dark:text-neutral-500"> <p className="max-w-[18rem] truncate text-sm text-neutral-600 dark:text-neutral-500">
All things around the world All things around the world.
</p> </p>
</div> </div>
<button <button
@ -148,6 +148,40 @@ export function Default({ column }: { column: IColumn }) {
</button> </button>
</div> </div>
</div> </div>
<div className="shrink-0 flex flex-col rounded-xl overflow-hidden bg-neutral-50 dark:bg-neutral-950 ring-1 ring-neutral-100 dark:ring-neutral-900">
<div className="h-[100px] w-full px-3 pt-3">
<img
src="/columns/waifu.jpg"
srcSet="/columns/waifu@2x.jpg 2x"
alt="waifu"
loading="lazy"
decoding="async"
className="w-full h-auto object-cover rounded-lg"
/>
</div>
<div className="h-16 shrink-0 px-3 flex items-center justify-between">
<div>
<h1 className="font-semibold">Waifu</h1>
<p className="max-w-[18rem] truncate text-sm text-neutral-600 dark:text-neutral-500">
Show a random waifu image to boost your morale.
</p>
</div>
<button
type="button"
onClick={() => {
addColumn({
kind: COL_TYPES.waifu,
title: "Waifu",
content: "",
});
}}
className="shrink-0 w-16 h-8 rounded-lg text-sm font-semibold bg-neutral-100 dark:bg-neutral-900 text-blue-500 hover:bg-neutral-200 dark:hover:bg-neutral-800 inline-flex items-center justify-center"
>
Add
</button>
</div>
</div>
<div className="h-3" />
</div> </div>
</Column.Root> </Column.Root>
); );

View File

@ -21,7 +21,7 @@
"@lume/tsconfig": "workspace:^", "@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^", "@lume/types": "workspace:^",
"@types/react": "^18.2.48", "@types/react": "^18.2.48",
"tailwind": "^4.0.0", "tailwindcss": "^3.4.1",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
} }

View File

@ -1,5 +1,4 @@
import { Column } from "@lume/ark"; import { Column } from "@lume/ark";
import { ForyouIcon } from "@lume/icons";
import { useStorage } from "@lume/storage"; import { useStorage } from "@lume/storage";
import { IColumn } from "@lume/types"; import { IColumn } from "@lume/types";
import { EventRoute, UserRoute } from "@lume/ui"; import { EventRoute, UserRoute } from "@lume/ui";
@ -27,12 +26,7 @@ export function ForYou({ column }: { column: IColumn }) {
return ( return (
<Column.Root> <Column.Root>
<Column.Header <Column.Header id={column.id} queryKey={[colKey]} title="For You" />
id={column.id}
queryKey={[colKey]}
title="For You"
icon={<ForyouIcon className="size-4" />}
/>
{storage.interests?.hashtags ? ( {storage.interests?.hashtags ? (
<Column.Live <Column.Live
filter={{ filter={{

View File

@ -20,7 +20,7 @@
"@lume/tsconfig": "workspace:^", "@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^", "@lume/types": "workspace:^",
"@types/react": "^18.2.48", "@types/react": "^18.2.48",
"tailwind": "^4.0.0", "tailwindcss": "^3.4.1",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
} }

View File

@ -20,7 +20,7 @@
"@lume/tsconfig": "workspace:^", "@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^", "@lume/types": "workspace:^",
"@types/react": "^18.2.48", "@types/react": "^18.2.48",
"tailwind": "^4.0.0", "tailwindcss": "^3.4.1",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
} }

View File

@ -1,9 +1,8 @@
import { Column } from "@lume/ark"; import { Column } from "@lume/ark";
import { GroupFeedsIcon } from "@lume/icons";
import { IColumn } from "@lume/types"; import { IColumn } from "@lume/types";
import { EventRoute, UserRoute } from "@lume/ui";
import { GroupForm } from "./components/form"; import { GroupForm } from "./components/form";
import { HomeRoute } from "./home"; import { HomeRoute } from "./home";
import { EventRoute, UserRoute } from "@lume/ui";
export function Group({ column }: { column: IColumn }) { export function Group({ column }: { column: IColumn }) {
const colKey = `group-${column.id}`; const colKey = `group-${column.id}`;
@ -13,11 +12,7 @@ export function Group({ column }: { column: IColumn }) {
<Column.Root> <Column.Root>
{created ? ( {created ? (
<> <>
<Column.Header <Column.Header id={column.id} title={column.title} />
id={column.id}
title={column.title}
icon={<GroupFeedsIcon className="size-4" />}
/>
<Column.Content> <Column.Content>
<Column.Route <Column.Route
path="/" path="/"

View File

@ -20,7 +20,7 @@
"@lume/tsconfig": "workspace:^", "@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^", "@lume/types": "workspace:^",
"@types/react": "^18.2.48", "@types/react": "^18.2.48",
"tailwind": "^4.0.0", "tailwindcss": "^3.4.1",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
} }

View File

@ -1,8 +1,7 @@
import { Column } from "@lume/ark"; import { Column } from "@lume/ark";
import { HashtagIcon } from "@lume/icons";
import { IColumn } from "@lume/types"; import { IColumn } from "@lume/types";
import { HomeRoute } from "./home";
import { EventRoute, UserRoute } from "@lume/ui"; import { EventRoute, UserRoute } from "@lume/ui";
import { HomeRoute } from "./home";
export function Hashtag({ column }: { column: IColumn }) { export function Hashtag({ column }: { column: IColumn }) {
const colKey = `hashtag-${column.id}`; const colKey = `hashtag-${column.id}`;
@ -10,12 +9,7 @@ export function Hashtag({ column }: { column: IColumn }) {
return ( return (
<Column.Root> <Column.Root>
<Column.Header <Column.Header id={column.id} queryKey={[colKey]} title={hashtag} />
id={column.id}
queryKey={[colKey]}
title={hashtag}
icon={<HashtagIcon className="size-4" />}
/>
<Column.Content> <Column.Content>
<Column.Route <Column.Route
path="/" path="/"

View File

@ -20,7 +20,7 @@
"@lume/tsconfig": "workspace:^", "@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^", "@lume/types": "workspace:^",
"@types/react": "^18.2.48", "@types/react": "^18.2.48",
"tailwind": "^4.0.0", "tailwindcss": "^3.4.1",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
} }

View File

@ -20,7 +20,7 @@
"@lume/tsconfig": "workspace:^", "@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^", "@lume/types": "workspace:^",
"@types/react": "^18.2.48", "@types/react": "^18.2.48",
"tailwind": "^4.0.0", "tailwindcss": "^3.4.1",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
} }

View File

@ -1,5 +1,4 @@
import { Column, useArk } from "@lume/ark"; import { Column, useArk } from "@lume/ark";
import { TimelineIcon } from "@lume/icons";
import { IColumn } from "@lume/types"; import { IColumn } from "@lume/types";
import { EventRoute, SuggestRoute, UserRoute } from "@lume/ui"; import { EventRoute, SuggestRoute, UserRoute } from "@lume/ui";
import { NDKEvent, NDKKind } from "@nostr-dev-kit/ndk"; import { NDKEvent, NDKKind } from "@nostr-dev-kit/ndk";
@ -26,12 +25,7 @@ export function Timeline({ column }: { column: IColumn }) {
return ( return (
<Column.Root> <Column.Root>
<Column.Header <Column.Header id={column.id} queryKey={[colKey]} title="Timeline" />
id={column.id}
queryKey={[colKey]}
title="Timeline"
icon={<TimelineIcon className="size-5" />}
/>
{ark.account.contacts.length ? ( {ark.account.contacts.length ? (
<Column.Live <Column.Live
filter={{ filter={{

View File

@ -20,7 +20,7 @@
"@lume/tsconfig": "workspace:^", "@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^", "@lume/types": "workspace:^",
"@types/react": "^18.2.48", "@types/react": "^18.2.48",
"tailwind": "^4.0.0", "tailwindcss": "^3.4.1",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
} }

View File

@ -20,7 +20,7 @@
"@lume/tsconfig": "workspace:^", "@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^", "@lume/types": "workspace:^",
"@types/react": "^18.2.48", "@types/react": "^18.2.48",
"tailwind": "^4.0.0", "tailwindcss": "^3.4.1",
"typescript": "^5.3.3" "typescript": "^5.3.3"
} }
} }

View File

@ -1,17 +1,12 @@
import { Column } from "@lume/ark"; import { Column } from "@lume/ark";
import { UserIcon } from "@lume/icons";
import { IColumn } from "@lume/types"; import { IColumn } from "@lume/types";
import { HomeRoute } from "./home";
import { EventRoute, UserRoute } from "@lume/ui"; import { EventRoute, UserRoute } from "@lume/ui";
import { HomeRoute } from "./home";
export function User({ column }: { column: IColumn }) { export function User({ column }: { column: IColumn }) {
return ( return (
<Column.Root> <Column.Root>
<Column.Header <Column.Header id={column.id} title={column.title} />
id={column.id}
title={column.title}
icon={<UserIcon className="size-4" />}
/>
<Column.Content> <Column.Content>
<Column.Route path="/" element={<HomeRoute id={column.content} />} /> <Column.Route path="/" element={<HomeRoute id={column.content} />} />
<Column.Route path="/events/:id" element={<EventRoute />} /> <Column.Route path="/events/:id" element={<EventRoute />} />

View File

@ -0,0 +1,23 @@
{
"name": "@columns/waifu",
"version": "0.0.0",
"private": true,
"main": "./src/index.tsx",
"dependencies": {
"@lume/ark": "workspace:^",
"@lume/icons": "workspace:^",
"@lume/ui": "workspace:^",
"@lume/utils": "workspace:^",
"@tanstack/react-query": "^5.17.19",
"react": "^18.2.0",
"react-router-dom": "^6.21.3"
},
"devDependencies": {
"@lume/tailwindcss": "workspace:^",
"@lume/tsconfig": "workspace:^",
"@lume/types": "workspace:^",
"@types/react": "^18.2.48",
"tailwindcss": "^3.4.1",
"typescript": "^5.3.3"
}
}

View File

@ -0,0 +1,69 @@
import { LoaderIcon, RefreshIcon } from "@lume/icons";
import { cn } from "@lume/utils";
import { useQuery } from "@tanstack/react-query";
export function HomeRoute({ colKey }: { colKey: string }) {
const { data, isLoading, isError, isRefetching, refetch } = useQuery({
queryKey: [colKey],
queryFn: async ({ signal }: { signal: AbortSignal }) => {
const apiUrl = "https://api.waifu.im/search";
const params = {
included_tags: "waifu",
height: ">=2000",
};
const queryParams = new URLSearchParams(params);
const requestUrl = `${apiUrl}?${queryParams}`;
const res = await fetch(requestUrl, { signal });
if (!res.ok) throw new Error("Failed to get image url");
const data = await res.json();
return data.images[0];
},
refetchOnMount: false,
refetchOnWindowFocus: false,
});
return (
<div className="p-3 h-full flex flex-col justify-center items-center">
{isLoading ? (
<LoaderIcon className="size-5 animate-spin" />
) : isError ? (
<p className="text-center text-sm font-medium">
Failed to get image, please try again later.
</p>
) : (
<div className="relative min-h-0 flex-1 grow-0 w-full rounded-xl flex items-stretch">
<img
src={data.url}
alt={data.signature}
loading="lazy"
decoding="async"
className="object-cover w-full rounded-xl ring-1 ring-black/5 dark:ring-white/5"
/>
<div className="absolute bottom-3 right-3 flex items-center gap-2">
<button
type="button"
onClick={() => refetch()}
className="text-sm font-medium px-2 h-7 inline-flex items-center justify-center bg-black/50 hover:bg-black/30 backdrop-blur-2xl rounded-md text-white"
>
<RefreshIcon
className={cn("size-4", isRefetching ? "animate-spin" : "")}
/>
</button>
<a
href={data.source}
target="_blank"
rel="noreferrer"
className="text-sm font-medium px-2 h-7 inline-flex items-center justify-center bg-black/50 hover:bg-black/30 backdrop-blur-2xl rounded-md text-white"
>
Source
</a>
</div>
</div>
)}
</div>
);
}

View File

@ -0,0 +1,16 @@
import { Column } from "@lume/ark";
import { IColumn } from "@lume/types";
import { HomeRoute } from "./home";
export function Waifu({ column }: { column: IColumn }) {
const colKey = `waifu-${column.id}`;
return (
<Column.Root>
<Column.Header id={column.id} title={column.title} />
<Column.Content>
<Column.Route path="/" element={<HomeRoute colKey={colKey} />} />
</Column.Content>
</Column.Root>
);
}

View File

@ -0,0 +1,8 @@
import sharedConfig from "@lume/tailwindcss";
const config = {
content: ["./src/**/*.{js,ts,jsx,tsx}"],
presets: [sharedConfig],
};
export default config;

View File

@ -0,0 +1,8 @@
{
"extends": "@lume/tsconfig/base.json",
"compilerOptions": {
"outDir": "dist"
},
"include": ["src"],
"exclude": ["node_modules", "dist"]
}

View File

@ -59,6 +59,7 @@ export const COL_TYPES = {
antenas: 5, antenas: 5,
global: 6, global: 6,
trendingNotes: 9000, trendingNotes: 9000,
waifu: 9001,
foryou: 9998, foryou: 9998,
newsfeed: 9999, newsfeed: 9999,
}; };

File diff suppressed because it is too large Load Diff