);
diff --git a/apps/desktop2/src/routes/$account.home.tsx b/apps/desktop2/src/routes/$account.home.tsx
index 0cb8a17b..e5dd516c 100644
--- a/apps/desktop2/src/routes/$account.home.tsx
+++ b/apps/desktop2/src/routes/$account.home.tsx
@@ -50,8 +50,8 @@ function Screen() {
type: "add",
column: {
label: "store",
- name: "Store",
- content: "/store/official",
+ name: "Column Gallery",
+ content: "/store",
},
});
}, []);
@@ -65,6 +65,23 @@ function Screen() {
setColumns((prev) => prev.filter((t) => t.label !== label));
}, 150);
+ const move = useDebouncedCallback(
+ (label: string, direction: "left" | "right") => {
+ const newCols = [...columns];
+
+ const col = newCols.find((el) => el.label === label);
+ const colIndex = newCols.findIndex((el) => el.label === label);
+
+ newCols.splice(colIndex, 1);
+
+ if (direction === "left") newCols.splice(colIndex - 1, 0, col);
+ if (direction === "right") newCols.splice(colIndex + 1, 0, col);
+
+ setColumns(newCols);
+ },
+ 150,
+ );
+
const updateName = useDebouncedCallback((label: string, title: string) => {
const currentColIndex = columns.findIndex((col) => col.label === label);
@@ -135,6 +152,8 @@ function Screen() {
if (data.payload.type === "reset") reset();
if (data.payload.type === "add") add(data.payload.column);
if (data.payload.type === "remove") remove(data.payload.label);
+ if (data.payload.type === "move")
+ move(data.payload.label, data.payload.direction);
if (data.payload.type === "set_title")
updateName(data.payload.label, data.payload.title);
});
diff --git a/apps/desktop2/src/routes/$account.tsx b/apps/desktop2/src/routes/$account.tsx
index 57e266e9..084b19fa 100644
--- a/apps/desktop2/src/routes/$account.tsx
+++ b/apps/desktop2/src/routes/$account.tsx
@@ -34,8 +34,8 @@ function Screen() {
type: "add",
column: {
label: "store",
- name: "Store",
- content: "/store/official",
+ name: "Column Gallery",
+ content: "/store",
},
});
};
diff --git a/apps/desktop2/src/routes/global.tsx b/apps/desktop2/src/routes/global.tsx
index 8882da17..8496d9e4 100644
--- a/apps/desktop2/src/routes/global.tsx
+++ b/apps/desktop2/src/routes/global.tsx
@@ -81,11 +81,11 @@ export function Screen() {
{isFetching && !isLoading && !isFetchingNextPage ? (
-
+
- Fetching new notes...
+ Getting new notes...
diff --git a/apps/desktop2/src/routes/group.tsx b/apps/desktop2/src/routes/group.tsx
index 7334ea3d..40f95f67 100644
--- a/apps/desktop2/src/routes/group.tsx
+++ b/apps/desktop2/src/routes/group.tsx
@@ -95,11 +95,11 @@ export function Screen() {
{isFetching && !isLoading && !isFetchingNextPage ? (
-
+
- Fetching new notes...
+ Getting new notes...
diff --git a/apps/desktop2/src/routes/newsfeed.tsx b/apps/desktop2/src/routes/newsfeed.tsx
index 65d15aae..0676077d 100644
--- a/apps/desktop2/src/routes/newsfeed.tsx
+++ b/apps/desktop2/src/routes/newsfeed.tsx
@@ -111,7 +111,7 @@ export function Screen() {
{isFetching && !isLoading && !isFetchingNextPage ? (
-
+
diff --git a/apps/desktop2/src/routes/store.community.tsx b/apps/desktop2/src/routes/store.community.tsx
deleted file mode 100644
index 50cc6fa1..00000000
--- a/apps/desktop2/src/routes/store.community.tsx
+++ /dev/null
@@ -1,21 +0,0 @@
-import { createFileRoute } from "@tanstack/react-router";
-
-export const Route = createFileRoute("/store/community")({
- component: Screen,
-});
-
-function Screen() {
- return (
-
-
-
-
Coming Soon
-
- Enhance your experience
by adding column shared by community.
-
-
-
- );
-}
diff --git a/apps/desktop2/src/routes/store.official.tsx b/apps/desktop2/src/routes/store.official.tsx
deleted file mode 100644
index 647b7325..00000000
--- a/apps/desktop2/src/routes/store.official.tsx
+++ /dev/null
@@ -1,69 +0,0 @@
-import type { LumeColumn } from "@lume/types";
-import { createFileRoute } from "@tanstack/react-router";
-import { resolveResource } from "@tauri-apps/api/path";
-import { getCurrent } from "@tauri-apps/api/window";
-import { readTextFile } from "@tauri-apps/plugin-fs";
-
-export const Route = createFileRoute("/store/official")({
- beforeLoad: async () => {
- const resourcePath = await resolveResource(
- "resources/official_columns.json",
- );
- const officialColumns: LumeColumn[] = JSON.parse(
- await readTextFile(resourcePath),
- );
-
- return {
- officialColumns,
- };
- },
- component: Screen,
-});
-
-function Screen() {
- const { officialColumns } = Route.useRouteContext();
-
- const install = async (column: LumeColumn) => {
- const mainWindow = getCurrent();
- await mainWindow.emit("columns", { type: "add", column });
- };
-
- return (
-
- {officialColumns.map((column) => (
-
- {column.cover ? (
-

- ) : null}
-
-
-
-
{column.name}
-
- {column.description}
-
-
-
-
-
-
- ))}
-
- );
-}
diff --git a/apps/desktop2/src/routes/store.tsx b/apps/desktop2/src/routes/store.tsx
index 8c42716e..aab6235a 100644
--- a/apps/desktop2/src/routes/store.tsx
+++ b/apps/desktop2/src/routes/store.tsx
@@ -1,48 +1,104 @@
-import { GlobalIcon, LaurelIcon } from "@lume/icons";
-import { cn } from "@lume/utils";
-import { Link } from "@tanstack/react-router";
-import { Outlet, createFileRoute } from "@tanstack/react-router";
+import { CommunityIcon, LaurelIcon } from "@lume/icons";
+import type { LumeColumn } from "@lume/types";
+import * as ScrollArea from "@radix-ui/react-scroll-area";
+import { createFileRoute } from "@tanstack/react-router";
+import { resolveResource } from "@tauri-apps/api/path";
+import { getCurrent } from "@tauri-apps/api/window";
+import { readTextFile } from "@tauri-apps/plugin-fs";
export const Route = createFileRoute("/store")({
+ beforeLoad: async () => {
+ const path = "resources/official_columns.json";
+ const resourcePath = await resolveResource(path);
+ const fileContent = await readTextFile(resourcePath);
+ const officialColumns: LumeColumn[] = JSON.parse(fileContent);
+
+ return {
+ officialColumns,
+ };
+ },
component: Screen,
});
function Screen() {
+ const { officialColumns } = Route.useRouteContext();
+
+ const install = async (column: LumeColumn) => {
+ const mainWindow = getCurrent();
+ await mainWindow.emit("columns", { type: "add", column });
+ };
+
return (
-
-
-
-
- {({ isActive }) => (
-
+
+
+
+
+
+
- Official
- )}
-
-
- {({ isActive }) => (
-
-
- Community
+ Official
+
+
+ {officialColumns.map((column) => (
+
+
+
+
+
+ {column.cover ? (
+

+ ) : null}
+
+
+
+ {column.name}
+
+
+
+ ))}
+
+
+
-
-
-
+ Community
+
+
+ Coming Soon.
+
+
+
+
+
+
+
+
);
}
diff --git a/apps/desktop2/src/routes/topic.tsx b/apps/desktop2/src/routes/topic.tsx
index 1eaeb044..fb7efaa4 100644
--- a/apps/desktop2/src/routes/topic.tsx
+++ b/apps/desktop2/src/routes/topic.tsx
@@ -105,11 +105,11 @@ export function Screen() {
{isFetching && !isLoading && !isFetchingNextPage ? (
-
+
- Fetching new notes...
+ Getting new notes...
diff --git a/apps/desktop2/src/routes/trending.notes.tsx b/apps/desktop2/src/routes/trending.notes.tsx
index e340937d..955faf06 100644
--- a/apps/desktop2/src/routes/trending.notes.tsx
+++ b/apps/desktop2/src/routes/trending.notes.tsx
@@ -1,11 +1,14 @@
+import { Conversation } from "@/components/conversation";
+import { Quote } from "@/components/quote";
+import { RepostNote } from "@/components/repost";
import { TextNote } from "@/components/text";
import { LumeEvent } from "@lume/system";
-import type { NostrEvent } from "@lume/types";
+import { Kind, type NostrEvent } from "@lume/types";
import { Spinner } from "@lume/ui";
import * as ScrollArea from "@radix-ui/react-scroll-area";
import { Await, createFileRoute } from "@tanstack/react-router";
import { defer } from "@tanstack/react-router";
-import { Suspense, useRef } from "react";
+import { Suspense, useCallback, useRef } from "react";
import { Virtualizer } from "virtua";
export const Route = createFileRoute("/trending/notes")({
@@ -21,7 +24,9 @@ export const Route = createFileRoute("/trending/notes")({
const events: NostrEvent[] = res.notes.map(
(item: { event: NostrEvent }) => item.event,
);
- const lumeEvents = events.map((ev) => new LumeEvent(ev));
+ const lumeEvents = Promise.all(
+ events.map(async (ev) => await LumeEvent.build(ev)),
+ );
return lumeEvents;
}),
),
@@ -35,7 +40,24 @@ export const Route = createFileRoute("/trending/notes")({
export function Screen() {
const { data } = Route.useLoaderData();
+
const ref = useRef
(null);
+ const renderItem = useCallback((event: LumeEvent) => {
+ if (!event) return;
+ switch (event.kind) {
+ case Kind.Repost:
+ return ;
+ default: {
+ if (event.isConversation) {
+ return ;
+ }
+ if (event.isQuote) {
+ return
;
+ }
+ return ;
+ }
+ }
+ }, []);
return (
- {(notes) =>
- notes.map((event) => (
-
- ))
- }
+ {(notes) => notes.map((event) => renderItem(event))}
diff --git a/apps/desktop2/src/routes/trending.tsx b/apps/desktop2/src/routes/trending.tsx
index 1631d8c1..0dcf738e 100644
--- a/apps/desktop2/src/routes/trending.tsx
+++ b/apps/desktop2/src/routes/trending.tsx
@@ -25,14 +25,14 @@ function Screen() {
return (
-
-
+
+
{({ isActive }) => (
@@ -44,8 +44,8 @@ function Screen() {
{({ isActive }) => (
@@ -55,7 +55,7 @@ function Screen() {
-
diff --git a/packages/system/src/commands.ts b/packages/system/src/commands.ts
index 86cc0faa..cf522b9f 100644
--- a/packages/system/src/commands.ts
+++ b/packages/system/src/commands.ts
@@ -428,6 +428,14 @@ try {
else return { status: "error", error: e as any };
}
},
+async reloadColumn(label: string) : Promise
> {
+try {
+ return { status: "ok", data: await TAURI_INVOKE("reload_column", { label }) };
+} catch (e) {
+ if(e instanceof Error) throw e;
+ else return { status: "error", error: e as any };
+}
+},
async openWindow(window: Window) : Promise> {
try {
return { status: "ok", data: await TAURI_INVOKE("open_window", { window }) };
diff --git a/packages/types/index.d.ts b/packages/types/index.d.ts
index 2d4da9e7..46987f62 100644
--- a/packages/types/index.d.ts
+++ b/packages/types/index.d.ts
@@ -78,10 +78,11 @@ export interface LumeColumn {
}
export interface ColumnEvent {
- type: "reset" | "add" | "remove" | "update" | "left" | "right" | "set_title";
+ type: "reset" | "add" | "remove" | "update" | "move" | "set_title";
label?: string;
title?: string;
column?: LumeColumn;
+ direction?: "left" | "right";
}
export interface Relays {
diff --git a/src-tauri/resources/official_columns.json b/src-tauri/resources/official_columns.json
index 9ed0b5f9..316c4f2a 100644
--- a/src-tauri/resources/official_columns.json
+++ b/src-tauri/resources/official_columns.json
@@ -1,52 +1,37 @@
[
- {
- "label": "lZfXLFgPPR4NNrgjlWDxn",
- "name": "Newsfeed",
- "content": "/newsfeed",
- "logo": "",
- "cover": "/newsfeed.png",
- "coverRetina": "/newsfeed@2x.png",
- "author": "Lume",
- "description": "Keep up to date with the people you're following."
- },
- {
- "label": "rRtguZwIpd5G8Wt54OTb7",
- "name": "Topic",
- "content": "/topic",
- "logo": "",
- "cover": "/foryou.png",
- "coverRetina": "/foryou@2x.png",
- "author": "Lume",
- "description": "Keep up to date with content based on your interests."
- },
- {
- "label": "fve9fk2fVyFWORPBkjd79",
- "name": "Group",
- "content": "/group",
- "logo": "",
- "cover": "/group.png",
- "coverRetina": "/group@2x.png",
- "author": "Lume",
- "description": "Focus feeds for people you like."
- },
- {
- "label": "gxtcIbgD8YNPbeI5o92I8",
- "name": "Trending",
- "content": "/trending/notes",
- "logo": "",
- "cover": "/trending.png",
- "coverRetina": "/trending@2x.png",
- "author": "Lume",
- "description": "What is trending on Nostr?."
- },
- {
- "label": "GLFm44za8rhJDP04LMr3M",
- "name": "Global",
- "content": "/global",
- "logo": "",
- "cover": "/global.png",
- "coverRetina": "/global@2x.png",
- "author": "Lume",
- "description": "All events from connected relays."
- }
+ {
+ "label": "lZfXLFgPPR4NNrgjlWDxn",
+ "name": "Local Feeds",
+ "content": "/newsfeed",
+ "cover": "/newsfeed.png",
+ "coverRetina": "/newsfeed@2x.png"
+ },
+ {
+ "label": "GLFm44za8rhJDP04LMr3M",
+ "name": "Global Feeds",
+ "content": "/global",
+ "cover": "/global.png",
+ "coverRetina": "/global@2x.png"
+ },
+ {
+ "label": "fve9fk2fVyFWORPBkjd79",
+ "name": "Group Feeds",
+ "content": "/group",
+ "cover": "/group.png",
+ "coverRetina": "/group@2x.png"
+ },
+ {
+ "label": "rRtguZwIpd5G8Wt54OTb7",
+ "name": "Topic",
+ "content": "/topic",
+ "cover": "/foryou.png",
+ "coverRetina": "/foryou@2x.png"
+ },
+ {
+ "label": "gxtcIbgD8YNPbeI5o92I8",
+ "name": "Trending",
+ "content": "/trending/notes",
+ "cover": "/trending.png",
+ "coverRetina": "/trending@2x.png"
+ }
]
diff --git a/src-tauri/src/commands/window.rs b/src-tauri/src/commands/window.rs
index f41a85bf..bad1fc44 100644
--- a/src-tauri/src/commands/window.rs
+++ b/src-tauri/src/commands/window.rs
@@ -138,6 +138,21 @@ pub fn resize_column(
}
}
+#[tauri::command]
+#[specta::specta]
+pub fn reload_column(label: &str, app_handle: tauri::AppHandle) -> Result<(), String> {
+ match app_handle.get_webview(label) {
+ Some(webview) => {
+ if webview.eval("window.location.reload()").is_ok() {
+ Ok(())
+ } else {
+ Err("Reload column failed".into())
+ }
+ }
+ None => Err("Webview not found".into()),
+ }
+}
+
#[tauri::command]
#[specta::specta]
pub fn open_window(window: Window, app_handle: tauri::AppHandle) -> Result<(), String> {
diff --git a/src-tauri/src/main.rs b/src-tauri/src/main.rs
index a5010ca4..c2348f01 100644
--- a/src-tauri/src/main.rs
+++ b/src-tauri/src/main.rs
@@ -124,6 +124,7 @@ fn main() {
commands::window::close_column,
commands::window::reposition_column,
commands::window::resize_column,
+ commands::window::reload_column,
commands::window::open_window,
commands::window::open_main_window,
commands::window::set_badge