diff --git a/app/fportal/components/interfaces.ts b/app/fportal/components/interfaces.ts index ed88c0b..b5b6cb9 100644 --- a/app/fportal/components/interfaces.ts +++ b/app/fportal/components/interfaces.ts @@ -1,12 +1,26 @@ type HandleStateChangeType = (state: boolean) => void; +const wTypes = ["simple", "excerpt"] as const; + interface WidgetType { id: string; color: string; sizeLimit?: number; - wType?: "simple" | "excerpt"; + wType?: (typeof wTypes)[number]; } -type HandleCommandType = (name: string, data?: string) => void; +type HandleCommandType = { + (name: "toggleCollapse"): void; + (name: "toggleConfiguring"): void; + (name: "size", data: string): void; + (name: "wType", data: string): void; + (name: "color", data: WidgetType["color"]): void; + (name: "reset"): void; + (name: "save"): void; + (name: "remove"): void; + (name: "move", data: string): void; + (name: "startMoving"): void; + (name: "readAll", data?: string): void; +}; -export type { HandleStateChangeType, WidgetType, HandleCommandType }; +export { wTypes, type HandleStateChangeType, type WidgetType, type HandleCommandType }; diff --git a/app/fportal/components/widget.tsx b/app/fportal/components/widget.tsx index ac74f8e..b3257a1 100644 --- a/app/fportal/components/widget.tsx +++ b/app/fportal/components/widget.tsx @@ -1,6 +1,6 @@ import React from "react"; import { FeedContent, freshRss, FullFeed } from "../freshrss"; -import type { WidgetType, HandleCommandType } from "./interfaces"; +import { wTypes, type WidgetType, type HandleCommandType } from "./interfaces"; import Loading from "./loading"; import WidgetConfig from "./widgetConfig"; @@ -41,76 +41,100 @@ export default function Widget({ feed, config, updateConfig, updateFeed, move }: }); } }, [feed, pag, sizeLimit, isCollapsed]); - const handleCommand: HandleCommandType = (name: string, data?: string) => { - if (name === "toggleCollapse") { - setCollapsed(!isCollapsed); - } else if (name === "toggleConfiguring") { - setConfiguring(!isConfiguring); - setSizeLimit(config.sizeLimit || 10); - setWType(config.wType || "excerpt"); - setSizeLimit(config.sizeLimit || 10); - setColor(config.color || "gray"); - setMoving(false); - } else if (name === "size" && data) { - setSizeLimit(parseInt(data, 10)); - } else if (name === "wType" && data) { - switch (data) { - case "excerpt": - case "simple": - setWType(data); - } - } else if (name === "color" && data) { - setColor(data); - } else if (name === "reset") { - setSizeLimit(config.sizeLimit || 10); - setWType(config.wType || "excerpt"); - setSizeLimit(config.sizeLimit || 10); - setColor(config.color || "gray"); - } else if (name === "save") { - updateConfig({ - id: feed.id, - sizeLimit, - wType, - color - }); - setConfiguring(false); - } else if (name === "remove") { - updateConfig({ id: feed.id, color }, true); - setConfiguring(false); - } else if (name === "move" && data) { - move(feed.id, data); - } else if (name === "startMoving") { - setConfiguring(false); - setMoving(!isMoving); - } else if (name === "readAll") { - const unreadRows = rows.filter( - (e) => e.categories.indexOf("user/-/state/com.google/read") === -1 - ); - let markAction = () => - freshRss.markReadFeed(feed.id).catch((error) => { - console.error("markReadFeed error", error); - }); - if (unreadRows.length === unread) { - markAction = () => - freshRss.markReadItems(unreadRows.map((e) => e.id)).catch((error) => { - console.error("markReadItems error", error); - }); + const handleCommand: HandleCommandType = ( + name: HandleCommandType["name"], + data?: string | number + ) => { + switch (name) { + case "toggleCollapse": + setCollapsed(!isCollapsed); + break; + case "toggleConfiguring": + setConfiguring(!isConfiguring); + setSizeLimit(config.sizeLimit || 10); + setWType(config.wType || "excerpt"); + setSizeLimit(config.sizeLimit || 10); + setColor(config.color || "gray"); + setMoving(false); + break; + case "size": + if (typeof data === "string") { + setSizeLimit(parseInt(data, 10)); + } + break; + case "wType": { + const awType = wTypes.find((validName) => validName === data); + if (awType) { + setWType(awType); + } + break; } - markAction() - .then(() => { - const newRows = [...rows]; - newRows.forEach((row) => { - if (row.categories.indexOf("user/-/state/com.google/read") === -1) { - row.categories.push("user/-/state/com.google/read"); - } - }); - feed.unread = 0; - updateFeed(feed); - setRows(newRows); - }) - .catch((error) => { - console.error("markAction error", error); + case "color": + if (typeof data === "string") { + setColor(data); + } + break; + case "reset": + setSizeLimit(config.sizeLimit || 10); + setWType(config.wType || "excerpt"); + setColor(config.color || "gray"); + break; + case "save": + updateConfig({ + id: feed.id, + sizeLimit, + wType, + color }); + setConfiguring(false); + break; + case "remove": + updateConfig({ id: feed.id, color }, true); + setConfiguring(false); + break; + case "move": + if (typeof data === "string") { + move(feed.id, data); + } + break; + case "startMoving": + setConfiguring(false); + setMoving(!isMoving); + break; + case "readAll": + { + const unreadRows = rows + .slice(0, sizeLimit) + .filter((e) => e.categories.indexOf("user/-/state/com.google/read") === -1); + let markAction = () => + freshRss.markReadFeed(feed.id).catch((error) => { + console.error("markReadFeed error", error); + }); + if (unreadRows.length === unread || data == "current") { + markAction = () => + freshRss.markReadItems(unreadRows.map((e) => e.id)).catch((error) => { + console.error("markReadItems error", error); + }); + } + markAction() + .then(() => { + const newRows = [...rows]; + let marked = 0; + newRows.forEach((row) => { + if (row.categories.indexOf("user/-/state/com.google/read") === -1) { + marked += 1; + row.categories.push("user/-/state/com.google/read"); + } + }); + feed.unread = Math.max(0, feed.unread - marked); + updateFeed(feed); + setRows(newRows); + }) + .catch((error) => { + console.error("markAction error", error); + }); + } + break; } }; const setContinuation = (c: string) => { diff --git a/app/fportal/components/widgetHeader.tsx b/app/fportal/components/widgetHeader.tsx index 5d2bafb..bb17442 100644 --- a/app/fportal/components/widgetHeader.tsx +++ b/app/fportal/components/widgetHeader.tsx @@ -39,8 +39,8 @@ export default function WidgetHeader({