From 544b9aef2f0caf3f2341b717638c250316c61fa9 Mon Sep 17 00:00:00 2001 From: Chris <67816022+vhsdream@users.noreply.github.com> Date: Wed, 12 Mar 2025 09:46:01 -0400 Subject: [PATCH] Feature: Hoarder service widget (#4913) --- docs/widgets/services/hoarder.md | 17 ++++++++ docs/widgets/services/index.md | 1 + mkdocs.yml | 1 + public/locales/en/common.json | 8 ++++ src/utils/proxy/handlers/credentialed.js | 1 + src/widgets/components.js | 1 + src/widgets/hoarder/component.jsx | 49 ++++++++++++++++++++++++ src/widgets/hoarder/widget.js | 15 ++++++++ src/widgets/widgets.js | 2 + 9 files changed, 95 insertions(+) create mode 100644 docs/widgets/services/hoarder.md create mode 100644 src/widgets/hoarder/component.jsx create mode 100644 src/widgets/hoarder/widget.js diff --git a/docs/widgets/services/hoarder.md b/docs/widgets/services/hoarder.md new file mode 100644 index 00000000..3e8c82ad --- /dev/null +++ b/docs/widgets/services/hoarder.md @@ -0,0 +1,17 @@ +--- +title: Hoarder +description: Hoarder Widget Configuration +--- + +Learn more about [Hoarder](https://hoarder.app). + +Generate an API key for your user at `User Settings > API Keys`. + +Allowed fields: `["bookmarks", "favorites", "archived", "highlights", "lists", "tags"]` (maximum of 4). + +```yaml +widget: + type: hoarder + url: http[s]://hoarder.host.or.ip[:port] + key: hoarderapikey +``` diff --git a/docs/widgets/services/index.md b/docs/widgets/services/index.md index 58b1409d..15caadc2 100644 --- a/docs/widgets/services/index.md +++ b/docs/widgets/services/index.md @@ -51,6 +51,7 @@ You can also find a list of all available service widgets in the sidebar navigat - [HDHomeRun](hdhomerun.md) - [Headscale](headscale.md) - [Healthchecks](healthchecks.md) +- [Hoarder](hoarder.md) - [Home Assistant](homeassistant.md) - [HomeBox](homebox.md) - [Homebridge](homebridge.md) diff --git a/mkdocs.yml b/mkdocs.yml index c5f3a038..01a5295b 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -74,6 +74,7 @@ nav: - widgets/services/hdhomerun.md - widgets/services/headscale.md - widgets/services/healthchecks.md + - widgets/services/hoarder.md - widgets/services/homeassistant.md - widgets/services/homebox.md - widgets/services/homebridge.md diff --git a/public/locales/en/common.json b/public/locales/en/common.json index bd521385..2bc4cf9c 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -1022,5 +1022,13 @@ "load": "Load", "bcharge":"Battery Charge", "timeleft":"Time Left" + }, + "hoarder": { + "bookmarks": "Bookmarks", + "favorites": "Favorites", + "archived": "Archived", + "highlights": "Highlights", + "lists": "Lists", + "tags": "Tags" } } diff --git a/src/utils/proxy/handlers/credentialed.js b/src/utils/proxy/handlers/credentialed.js index 5e7d9dd1..056e919f 100644 --- a/src/utils/proxy/handlers/credentialed.js +++ b/src/utils/proxy/handlers/credentialed.js @@ -41,6 +41,7 @@ export default async function credentialedProxyHandler(req, res, map) { "cloudflared", "ghostfolio", "headscale", + "hoarder", "linkwarden", "mealie", "netalertx", diff --git a/src/widgets/components.js b/src/widgets/components.js index c34b9a4d..6c12d823 100644 --- a/src/widgets/components.js +++ b/src/widgets/components.js @@ -47,6 +47,7 @@ const components = { grafana: dynamic(() => import("./grafana/component")), hdhomerun: dynamic(() => import("./hdhomerun/component")), headscale: dynamic(() => import("./headscale/component")), + hoarder: dynamic(() => import("./hoarder/component")), peanut: dynamic(() => import("./peanut/component")), homeassistant: dynamic(() => import("./homeassistant/component")), homebox: dynamic(() => import("./homebox/component")), diff --git a/src/widgets/hoarder/component.jsx b/src/widgets/hoarder/component.jsx new file mode 100644 index 00000000..99497d6f --- /dev/null +++ b/src/widgets/hoarder/component.jsx @@ -0,0 +1,49 @@ +import { useTranslation } from "next-i18next"; +import Container from "components/services/widget/container"; +import Block from "components/services/widget/block"; + +import useWidgetAPI from "utils/proxy/use-widget-api"; + +export const hoarderDefaultFields = ["bookmarks", "favorites", "archived", "highlights"]; +const MAX_ALLOWED_FIELDS = 4; + +export default function Component({ service }) { + const { t } = useTranslation(); + const { widget } = service; + + const { data: statsData, error: statsError } = useWidgetAPI(widget, "stats"); + + if (statsError) { + return ; + } + + if (!widget.fields || widget.fields.length === 0) { + widget.fields = hoarderDefaultFields; + } else if (widget.fields?.length > MAX_ALLOWED_FIELDS) { + widget.fields = widget.fields.slice(0, MAX_ALLOWED_FIELDS); + } + + if (!statsData) { + return ( + + + + + + + + + ); + } + + return ( + + + + + + + + + ); +} diff --git a/src/widgets/hoarder/widget.js b/src/widgets/hoarder/widget.js new file mode 100644 index 00000000..8a3cfef0 --- /dev/null +++ b/src/widgets/hoarder/widget.js @@ -0,0 +1,15 @@ +import credentialedProxyHandler from "utils/proxy/handlers/credentialed"; +import { asJson } from "utils/proxy/api-helpers"; + +const widget = { + api: `{url}/api/v1/{endpoint}`, + proxyHandler: credentialedProxyHandler, + + mappings: { + stats: { + endpoint: "users/me/stats", + }, + }, +}; + +export default widget; diff --git a/src/widgets/widgets.js b/src/widgets/widgets.js index bb7748ec..1537301c 100644 --- a/src/widgets/widgets.js +++ b/src/widgets/widgets.js @@ -41,6 +41,7 @@ import gotify from "./gotify/widget"; import grafana from "./grafana/widget"; import hdhomerun from "./hdhomerun/widget"; import headscale from "./headscale/widget"; +import hoarder from "./hoarder/widget"; import homeassistant from "./homeassistant/widget"; import homebox from "./homebox/widget"; import homebridge from "./homebridge/widget"; @@ -176,6 +177,7 @@ const widgets = { grafana, hdhomerun, headscale, + hoarder, homeassistant, homebox, homebridge,