feat: update default column list

This commit is contained in:
reya 2024-01-15 08:36:23 +07:00
parent dae4b1d52b
commit e93aedb703
14 changed files with 122 additions and 77 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 428 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 416 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 103 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 381 KiB

View File

@ -1,7 +1,4 @@
/* Vidstack */
@import '@vidstack/react/player/styles/default/theme.css';
@import '@vidstack/react/player/styles/default/layouts/video.css';
@tailwind base;
@tailwind components;
@tailwind utilities;

View File

@ -82,6 +82,7 @@ export function HomeScreen() {
}}
>
{columns.map((column) => renderItem(column))}
<div className="w-[420px]" />
</VList>
<div className="absolute bottom-3 right-3">
<div className="flex items-center gap-1 p-1 bg-black/50 dark:bg-white/30 backdrop-blur-xl rounded-xl">

View File

@ -42,7 +42,7 @@ export function ColumnProvider({ children }: { children: ReactNode }) {
column.title,
column.content,
);
if (result) setColumns((prev) => [...prev, column]);
if (result) setColumns((prev) => [...prev, result]);
}, []);
const removeColumn = useCallback(async (id: number) => {

View File

@ -11,7 +11,7 @@ export function LinkPreview({ url }: { url: string }) {
if (status === "pending") {
return (
<div className="flex flex-col w-full my-1 rounded-lg bg-neutral-100 dark:bg-neutral-900">
<div className="flex flex-col w-full my-1 rounded-lg overflow-hidden bg-neutral-100 dark:bg-neutral-900">
<div className="w-full h-48 animate-pulse bg-neutral-300 dark:bg-neutral-700" />
<div className="flex flex-col gap-2 px-3 py-3">
<div className="w-2/3 h-3 rounded animate-pulse bg-neutral-300 dark:bg-neutral-700" />

View File

@ -46,21 +46,17 @@ export function AntenasForm({ id }: { id: number }) {
</div>
<div className="flex flex-col h-full gap-5 px-3 pt-2 overflow-y-auto">
<div className="flex flex-col gap-1">
<label
htmlFor="name"
className="select-none text-neutral-950 data-[disabled]:opacity-50 font-medium mb-1 dark:text-white"
>
<label htmlFor="name" className="font-medium">
Name
</label>
<span className="relative block w-full before:absolute before:inset-px before:rounded-[calc(theme(borderRadius.lg)-1px)] before:bg-white before:shadow dark:before:hidden after:pointer-events-none after:absolute after:inset-0 after:rounded-lg after:ring-inset after:ring-transparent sm:after:focus-within:ring-2 sm:after:focus-within:ring-blue-500 has-[[data-disabled]]:opacity-50 before:has-[[data-disabled]]:bg-neutral-950/5 before:has-[[data-disabled]]:shadow-none before:has-[[data-invalid]]:shadow-red-500/10">
<input
name="name"
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="Nostrichs..."
className="relative block w-full appearance-none rounded-lg px-[calc(theme(spacing[3.5])-1px)] py-[calc(theme(spacing[2.5])-1px)] sm:px-[calc(theme(spacing[3])-1px)] sm:py-[calc(theme(spacing[1.5])-1px)] focus:ring-0 text-base/6 text-neutral-950 placeholder:text-neutral-500 sm:text-sm/6 dark:text-white border border-neutral-950/10 data-[hover]:border-neutral-950/20 dark:border-white/10 dark:data-[hover]:border-white/20 bg-transparent dark:bg-white/5 focus:outline-none data-[invalid]:border-red-500 data-[invalid]:data-[hover]:border-red-500 data-[invalid]:dark:border-red-500 data-[invalid]:data-[hover]:dark:border-red-500 data-[disabled]:border-neutral-950/20 dark:data-[hover]:data-[disabled]:border-white/15 data-[disabled]:dark:border-white/15 data-[disabled]:dark:bg-white/[2.5%]"
/>
</span>
<input
type="text"
name="name"
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="Nostrichs..."
className="px-2 border border-neutral-100 dark:border-neutral-900 bg-neutral-50 rounded-lg h-10 dark:bg-neutral-950 placeholder:text-neutral-600 focus:border-blue-500 focus:shadow-none focus:ring-0"
/>
</div>
<div className="flex flex-col gap-1">
<label
@ -69,17 +65,15 @@ export function AntenasForm({ id }: { id: number }) {
>
Source
</label>
<span className="relative block w-full before:absolute before:inset-px before:rounded-[calc(theme(borderRadius.lg)-1px)] before:bg-white before:shadow dark:before:hidden after:pointer-events-none after:absolute after:inset-0 after:rounded-lg after:ring-inset after:ring-transparent sm:after:focus-within:ring-2 sm:after:focus-within:ring-blue-500 has-[[data-disabled]]:opacity-50 before:has-[[data-disabled]]:bg-neutral-950/5 before:has-[[data-disabled]]:shadow-none before:has-[[data-invalid]]:shadow-red-500/10">
<select
name="source"
value={source}
onChange={(e) => setSource(e.target.value)}
className="relative block w-full appearance-none rounded-lg px-[calc(theme(spacing[3.5])-1px)] py-[calc(theme(spacing[2.5])-1px)] sm:px-[calc(theme(spacing[3])-1px)] sm:py-[calc(theme(spacing[1.5])-1px)] focus:ring-0 text-base/6 text-neutral-950 placeholder:text-neutral-500 sm:text-sm/6 dark:text-white border border-neutral-950/10 data-[hover]:border-neutral-950/20 dark:border-white/10 dark:data-[hover]:border-white/20 bg-transparent dark:bg-white/5 focus:outline-none data-[invalid]:border-red-500 data-[invalid]:data-[hover]:border-red-500 data-[invalid]:dark:border-red-500 data-[invalid]:data-[hover]:dark:border-red-500 data-[disabled]:border-neutral-950/20 dark:data-[hover]:data-[disabled]:border-white/15 data-[disabled]:dark:border-white/15 data-[disabled]:dark:bg-white/[2.5%]"
>
<option value="contacts">Contacts</option>
<option value="global">Global</option>
</select>
</span>
<select
name="source"
value={source}
onChange={(e) => setSource(e.target.value)}
className="px-2 w-full border border-neutral-100 dark:border-neutral-900 bg-neutral-50 rounded-lg dark:bg-neutral-950 placeholder:text-neutral-600 focus:border-blue-500 focus:shadow-none focus:ring-0"
>
<option value="contacts">Contacts</option>
<option value="global">Global</option>
</select>
</div>
<div className="flex flex-col gap-1">
<label
@ -89,18 +83,16 @@ export function AntenasForm({ id }: { id: number }) {
Hashtags to listen to
</label>
<div className="flex items-center justify-between gap-2 mb-1">
<span className="relative block flex-1 before:absolute before:inset-px before:rounded-[calc(theme(borderRadius.lg)-1px)] before:bg-white before:shadow dark:before:hidden after:pointer-events-none after:absolute after:inset-0 after:rounded-lg after:ring-inset after:ring-transparent sm:after:focus-within:ring-2 sm:after:focus-within:ring-blue-500 has-[[data-disabled]]:opacity-50 before:has-[[data-disabled]]:bg-neutral-950/5 before:has-[[data-disabled]]:shadow-none before:has-[[data-invalid]]:shadow-red-500/10">
<input
name="name"
value={hashtag}
onChange={(e) => setHashtag(e.target.value)}
onKeyPress={(event) => {
if (event.key === "Enter") addHashtag();
}}
placeholder="#nostr..."
className="relative block w-full appearance-none rounded-lg px-[calc(theme(spacing[3.5])-1px)] py-[calc(theme(spacing[2.5])-1px)] sm:px-[calc(theme(spacing[3])-1px)] sm:py-[calc(theme(spacing[1.5])-1px)] focus:ring-0 text-base/6 text-neutral-950 placeholder:text-neutral-500 sm:text-sm/6 dark:text-white border border-neutral-950/10 data-[hover]:border-neutral-950/20 dark:border-white/10 dark:data-[hover]:border-white/20 bg-transparent dark:bg-white/5 focus:outline-none data-[invalid]:border-red-500 data-[invalid]:data-[hover]:border-red-500 data-[invalid]:dark:border-red-500 data-[invalid]:data-[hover]:dark:border-red-500 data-[disabled]:border-neutral-950/20 dark:data-[hover]:data-[disabled]:border-white/15 data-[disabled]:dark:border-white/15 data-[disabled]:dark:bg-white/[2.5%]"
/>
</span>
<input
name="name"
value={hashtag}
onChange={(e) => setHashtag(e.target.value)}
onKeyPress={(event) => {
if (event.key === "Enter") addHashtag();
}}
placeholder="#nostr..."
className="px-2 w-full border border-neutral-100 dark:border-neutral-900 bg-neutral-50 rounded-lg h-10 dark:bg-neutral-950 placeholder:text-neutral-600 focus:border-blue-500 focus:shadow-none focus:ring-0"
/>
<button
type="button"
onClick={() => addHashtag()}
@ -127,7 +119,7 @@ export function AntenasForm({ id }: { id: number }) {
type="button"
onClick={submit}
disabled={hashtags.length < 1}
className="inline-flex items-center justify-center h-10 px-4 font-semibold text-white transform bg-blue-500 rounded-lg active:translate-y-1 hover:bg-blue-600 focus:outline-none disabled:opacity-50"
className="w-full inline-flex items-center justify-center h-10 px-4 font-semibold text-white transform bg-blue-500 rounded-lg active:translate-y-1 hover:bg-blue-600 focus:outline-none disabled:opacity-50"
>
Create
</button>

View File

@ -1,9 +1,11 @@
import { Column } from "@lume/ark";
import { Column, useColumnContext } from "@lume/ark";
import { ColumnIcon } from "@lume/icons";
import { IColumn } from "@lume/types";
import { TOPICS } from "@lume/utils";
import { COL_TYPES } from "@lume/utils";
export function Default({ column }: { column: IColumn }) {
const { addColumn } = useColumnContext();
return (
<Column.Root>
<Column.Header
@ -11,32 +13,86 @@ export function Default({ column }: { column: IColumn }) {
title="Add columns"
icon={<ColumnIcon className="size-4" />}
/>
<div className="h-full px-3 mt-3 overflow-y-auto scrollbar-none">
<div className="flex flex-col gap-5">
<div>
<h1 className="text-lg font-semibold leading-tight">Topics</h1>
<p className="text-neutral-600 dark:text-neutral-400">
Discover content based on your interests.
</p>
<div className="h-full px-3 mt-3 flex flex-col gap-3 overflow-y-auto scrollbar-none">
<div className="flex flex-col rounded-xl overflow-hidden">
<div className="h-[100px] w-full">
<img
src="/columns/topic.jpg"
srcSet="/columns/topic@2x.jpg 2x"
alt="topic"
className="w-full h-auto object-cover"
/>
</div>
<div className="grid grid-cols-2 gap-3">
{TOPICS.sort((a, b) => a.title.localeCompare(b.title)).map(
(topic, index) => (
<div
key={topic + index.toString()}
className="flex flex-col w-full px-3 rounded-lg bg-neutral-100"
>
<div className="rounded-md h-9 w-9 shrink-0">
<img
src={`/${topic.title.toLowerCase()}.jpg`}
alt={topic.title}
className="rounded-md h-9 w-9"
/>
</div>
<p className="font-medium">{topic.title}</p>
</div>
),
)}
<div className="h-16 shrink-0 px-3 flex items-center justify-between bg-neutral-50 dark:bg-neutral-950">
<div>
<h1 className="font-semibold">Topic</h1>
<p className="max-w-[18rem] truncate text-sm text-neutral-500 dark:text-neutral-600">
Explore all content based on your interest.
</p>
</div>
<button
type="button"
onClick={() => {
addColumn({ kind: COL_TYPES.topic, title: "", 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="flex flex-col rounded-xl overflow-hidden">
<div className="h-[100px] w-full">
<img
src="/columns/group.jpg"
srcSet="/columns/group@2x.jpg 2x"
alt="group"
className="w-full h-auto object-cover"
/>
</div>
<div className="h-16 shrink-0 px-3 flex items-center justify-between bg-neutral-50 dark:bg-neutral-950">
<div>
<h1 className="font-semibold">Group Feeds</h1>
<p className="max-w-[18rem] truncate text-sm text-neutral-500 dark:text-neutral-600">
Collective of people you're interested in.
</p>
</div>
<button
type="button"
onClick={() => {
addColumn({ kind: COL_TYPES.group, title: "", 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="flex flex-col rounded-xl overflow-hidden">
<div className="h-[100px] w-full">
<img
src="/columns/antenas.jpg"
srcSet="/columns/antenas@2x.jpg 2x"
alt="antenas"
className="w-full h-auto object-cover"
/>
</div>
<div className="h-16 shrink-0 px-3 flex items-center justify-between bg-neutral-50 dark:bg-neutral-950">
<div>
<h1 className="font-semibold">Antenas</h1>
<p className="max-w-[18rem] truncate text-sm text-neutral-500 dark:text-neutral-600">
Keep track to specific content.
</p>
</div>
<button
type="button"
onClick={() => {
addColumn({ kind: COL_TYPES.antenas, title: "", 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>

View File

@ -7,7 +7,7 @@ export function GroupForm({ id }: { id: number }) {
const ark = useArk();
const { updateColumn, removeColumn } = useColumnContext();
const [title, setTitle] = useState<string>(`Group-${id}`);
const [title, setTitle] = useState<string>("Just a new group");
const [users, setUsers] = useState<Array<string>>([]);
// toggle follow state
@ -36,7 +36,7 @@ export function GroupForm({ id }: { id: number }) {
</button>
</div>
<div className="flex flex-col gap-5 px-3 pt-2 overflow-y-auto">
<div className="flex flex-col gap-1">
<div className="flex flex-col gap-1.5">
<label
htmlFor="name"
className="font-medium text-neutral-700 dark:text-neutral-300"
@ -48,7 +48,7 @@ export function GroupForm({ id }: { id: number }) {
value={title}
onChange={(e) => setTitle(e.target.value)}
placeholder="Nostrichs..."
className="px-3 rounded-lg border-neutral-200 dark:border-neutral-900 h-11 placeholder:text-neutral-500 focus:border-blue-500 focus:ring focus:ring-blue-200 dark:placeholder:text-neutral-400 dark:focus:ring-blue-800"
className="px-2 border border-neutral-100 dark:border-neutral-900 bg-neutral-50 rounded-lg h-10 dark:bg-neutral-950 placeholder:text-neutral-600 focus:border-blue-500 focus:shadow-none focus:ring-0"
/>
</div>
<div className="flex flex-col gap-1">
@ -64,7 +64,7 @@ export function GroupForm({ id }: { id: number }) {
key={item}
type="button"
onClick={() => toggleUser(item)}
className="inline-flex items-center justify-between px-3 py-2 rounded-lg bg-neutral-50 dark:bg-neutral-950 hover:bg-neutral-100 dark:hover:bg-neutral-900"
className="inline-flex items-center justify-between px-3 py-2 rounded-xl bg-neutral-50 dark:bg-neutral-950 hover:bg-neutral-100 dark:hover:bg-neutral-900"
>
<User pubkey={item} variant="simple" />
{users.includes(item) ? (

View File

@ -341,13 +341,12 @@ export class LumeStorage {
if (insert) {
const columns: Array<IColumn> = await this.#db.select(
"SELECT * FROM columns ORDER BY id DESC LIMIT 1;",
"SELECT * FROM columns WHERE id = $1 ORDER BY id DESC LIMIT 1;",
[insert.lastInsertId],
);
if (columns.length < 1) console.error("get created widget failed");
if (!columns.length) console.error("get created widget failed");
return columns[0];
}
console.error("create widget failed");
}
public async updateColumn(id: number, title: string, content: string) {