Compare commits

..

643 Commits

Author SHA1 Message Date
Ben Phelps
de4ce73a9a fix hidden scrollbars
this was an adventure
2022-09-30 23:34:48 +03:00
Ben Phelps
f52c6f3b41 improved static styles and x-browser scrollbars 2022-09-30 22:13:37 +03:00
Ben Phelps
2271cc0044 cache github response for 5 min 2022-09-30 21:56:22 +03:00
Ben Phelps
931ffe4c84 Merge pull request #309 from JazzFisch/configurable-widget-fields
Allow widget field visibility to be configurable
2022-09-30 21:51:34 +03:00
lok
45f39120da Translated using Weblate (Yue)
Currently translated at 100.0% (118 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/yue/
2022-09-30 09:22:30 +02:00
FunsKiTo
000e15640a Translated using Weblate (Spanish)
Currently translated at 100.0% (118 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-30 09:22:30 +02:00
Jason Fischer
d4ad11a63f Slightly simplify container.jsx 2022-09-29 21:20:01 -07:00
Jason Fischer
c533966050 Merge branch 'main' into configurable-widget-fields 2022-09-29 21:15:56 -07:00
Jason Fischer
9b7d6b196f Allow widget field visibility to be configurable 2022-09-29 21:15:25 -07:00
C8opmBM
512a6cd4b9 Translated using Weblate (Romanian)
Currently translated at 100.0% (118 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ro/
2022-09-29 10:41:07 +02:00
Nonoss117
6b0659af1f Translated using Weblate (French)
Currently translated at 100.0% (118 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-29 10:41:07 +02:00
Sascha Jelinek
12279e9bda Translated using Weblate (German)
Currently translated at 100.0% (118 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-29 10:41:07 +02:00
Ben Phelps
dadd501843 fix case with empty bookmarks and widgets 2022-09-29 11:40:09 +03:00
Jason Fischer
756f6310af Merge pull request #302 from JazzFisch/fix-prowlarr
Fix Prowlarr show API Error
2022-09-28 16:06:46 -07:00
Jason Fischer
7a19bedc25 Fix Prowlarr show API Error 2022-09-28 15:36:08 -07:00
Ben Phelps
a10a30a22c fix some error edge cases 2022-09-28 22:40:54 +03:00
Ben Phelps
57e4ca355b add widgets to config hash 2022-09-28 21:58:43 +03:00
Anonymous
fed3102492 Translated using Weblate (Yue)
Currently translated at 97.4% (115 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/yue/
2022-09-28 19:17:58 +02:00
Anonymous
64e0e256ce Translated using Weblate (Portuguese (Brazil))
Currently translated at 97.4% (115 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt_BR/
2022-09-28 19:17:58 +02:00
Anonymous
287581025e Translated using Weblate (Romanian)
Currently translated at 97.4% (115 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ro/
2022-09-28 19:17:58 +02:00
Anonymous
3184b9ea0d Translated using Weblate (Hebrew)
Currently translated at 85.5% (101 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/he/
2022-09-28 19:17:57 +02:00
Anonymous
233eb7e785 Translated using Weblate (Hungarian)
Currently translated at 91.5% (108 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hu/
2022-09-28 19:17:57 +02:00
Anonymous
a801f8f65f Translated using Weblate (Croatian)
Currently translated at 97.4% (115 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hr/
2022-09-28 19:17:57 +02:00
Anonymous
4afe654bcc Translated using Weblate (Swedish)
Currently translated at 90.6% (107 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sv/
2022-09-28 19:17:57 +02:00
Anonymous
926be245a9 Translated using Weblate (Polish)
Currently translated at 83.0% (98 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pl/
2022-09-28 19:17:57 +02:00
Anonymous
f1615e6660 Translated using Weblate (Catalan)
Currently translated at 97.4% (115 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2022-09-28 19:17:56 +02:00
Anonymous
ac6ecf21a0 Translated using Weblate (Chinese (Traditional))
Currently translated at 7.6% (9 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hant/
2022-09-28 19:17:56 +02:00
Anonymous
8629f0a26d Translated using Weblate (Dutch)
Currently translated at 53.3% (63 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-28 19:17:56 +02:00
Anonymous
7a6ef23adb Translated using Weblate (Vietnamese)
Currently translated at 37.2% (44 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-28 19:17:56 +02:00
Anonymous
dfa19c96b9 Translated using Weblate (Norwegian Bokmål)
Currently translated at 66.9% (79 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-28 19:17:55 +02:00
Anonymous
334c023b4f Translated using Weblate (Italian)
Currently translated at 65.2% (77 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-28 19:17:55 +02:00
Anonymous
1f373e0b3e Translated using Weblate (Chinese (Simplified))
Currently translated at 92.3% (109 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-28 19:17:55 +02:00
Anonymous
47fc4040d5 Translated using Weblate (Russian)
Currently translated at 19.4% (23 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-28 19:17:54 +02:00
Anonymous
f5e47ab61a Translated using Weblate (Portuguese)
Currently translated at 97.4% (115 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-28 19:17:54 +02:00
Anonymous
83cdb2ed2b Translated using Weblate (French)
Currently translated at 97.4% (115 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-28 19:17:54 +02:00
Anonymous
d67eca8882 Translated using Weblate (Spanish)
Currently translated at 97.4% (115 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-28 19:17:54 +02:00
Anonymous
a0044dd3ad Translated using Weblate (German)
Currently translated at 97.4% (115 of 118 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-28 19:17:53 +02:00
Jason Fischer
149ed8c266 Fix transmission leech and seed showing NaN 2022-09-28 09:58:01 -07:00
Jason Fischer
65755a08aa Better login strategy for qbittorrent proxy
- Additional logging in httpProxy
2022-09-28 09:55:18 -07:00
Jason Fischer
1ea8e38372 Fix Transmission proxy error with URL and CSRF caching 2022-09-28 08:57:04 -07:00
Ben Phelps
69adb3fde2 Merge branch 'main' into widget-refactor 2022-09-28 17:51:30 +03:00
lok
28be9b5988 Translated using Weblate (Yue)
Currently translated at 100.0% (115 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/yue/
2022-09-28 16:18:58 +02:00
Ben Phelps
0590896453 display as ms, not millisec or milliseconds 2022-09-28 10:15:18 +03:00
Ben Phelps
8f59c4a236 trim url trailing slashes 2022-09-28 10:14:44 +03:00
Jason Fischer
550af91030 Add Lidarr as a recognized widget type 2022-09-27 21:22:26 -07:00
Ben Phelps
bb5721c473 ui polish 2022-09-28 02:32:39 +03:00
Ben Phelps
68c93c65e6 bring all transfer rates inline, using bitrate 2022-09-28 02:32:30 +03:00
Ben Phelps
d36efa5796 styled scollbars
lets see how this one lands
2022-09-27 22:59:29 +03:00
Ben Phelps
0a58f259ff wrapped proxy calls via useWidgetAPI 2022-09-27 22:59:14 +03:00
Ben Phelps
649f0038bc update images 2022-09-27 20:49:49 +03:00
Ben Phelps
9697e302d7 add a little more spacing 2022-09-27 20:41:19 +03:00
Ben Phelps
415d59eeb3 header spacing 2022-09-27 20:40:50 +03:00
Ben Phelps
3cb06eb526 smaller text 2022-09-27 20:40:21 +03:00
Ben Phelps
2087c775fc actually styling 2022-09-27 20:38:10 +03:00
Ben Phelps
4dd4363e91 readme styling 2022-09-27 20:37:13 +03:00
Ben Phelps
314050b568 Merge branch 'main' into widget-refactor 2022-09-27 19:26:37 +03:00
Jason Fischer
1765a97f31 Merge pull request #284 from josways/main
support Baidu search engine
2022-09-27 08:48:38 -07:00
Ben Phelps
30ac8cb41c new preview image 2022-09-27 17:44:50 +03:00
Anonymous
959b778cd7 Translated using Weblate (Yue)
Currently translated at 100.0% (0 of 0 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/yue/
2022-09-27 15:38:18 +02:00
Juan Manuel Bennàssar Carretero
ca87a5527d Translated using Weblate (Spanish)
Currently translated at 100.0% (115 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-27 15:38:17 +02:00
lok
711c3d1b67 Added translation using Weblate (Yue) 2022-09-27 15:38:07 +02:00
Ben Phelps
5210a68cc6 remove debug 2022-09-27 10:51:00 +03:00
Ben Phelps
616e56e3f5 fix qbittorrent widget 2022-09-27 10:49:03 +03:00
Ben Phelps
8e0075ff90 expire all cookies after 1 hour 2022-09-27 10:48:52 +03:00
Ben Phelps
c980c70798 revalidate config changes, check on focus changes 2022-09-26 22:54:12 +03:00
Josway
fa2763d8cd support Baidu search engine 2022-09-26 23:06:42 +08:00
Josway
d18e472623 support Baidu search engine 2022-09-26 23:02:59 +08:00
Ben Phelps
5f0c1ec70a tweak styles 2022-09-26 16:56:20 +03:00
Ben Phelps
4386999c38 further restructuring 2022-09-26 15:25:10 +03:00
Ben Phelps
9b07f3eb90 Merge branch 'main' into widget-refactor 2022-09-26 15:06:26 +03:00
Ben Phelps
b280e18651 fix nightly issue 2022-09-26 15:06:14 +03:00
Ben Phelps
086bfa310f lighthouse requirements 2022-09-26 15:03:02 +03:00
Ben Phelps
990ae8464e only render en by default 2022-09-26 14:43:03 +03:00
Ben Phelps
e4c82b5e8d fix always loading docker stats block 2022-09-26 14:42:40 +03:00
Ben Phelps
4d790feaae formatting cleanup 2022-09-26 14:42:31 +03:00
Ben Phelps
b72dca0e2e only create each logger once 2022-09-26 14:42:13 +03:00
Ben Phelps
e1a3a82f75 utils cleanup, initial static generation 2022-09-26 12:04:37 +03:00
Ben Phelps
ec8700f3e9 fix widgets without mappings 2022-09-26 10:58:31 +03:00
Ben Phelps
d999bb3f09 fix portainer widget 2022-09-26 10:58:22 +03:00
Ben Phelps
a83d5132d9 refactor lidarr widget 2022-09-26 10:58:14 +03:00
Jason Fischer
1840e9a57a Add authentik 2022-09-25 17:42:16 -07:00
Jason Fischer
d876ba30d4 Merge branch 'main' into widget-refactor 2022-09-25 16:23:31 -07:00
Ben Phelps
47bc073fb4 widget refactoring and cleanup 2022-09-26 02:23:02 +03:00
Jason Fischer
808e79e2ac Add Docker, Emby, Gotify, Jackett, and JellySeerr widgets 2022-09-25 16:15:47 -07:00
Mauricio Kalil
371eacb354 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (115 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt_BR/
2022-09-26 00:26:59 +02:00
Ben Phelps
f04f5921e1 fix fr number formatting 2022-09-26 01:26:55 +03:00
Ben Phelps
035dd25ece widget refactoring 2022-09-26 00:35:54 +03:00
Jason Fischer
03fa2f86d7 Add AdGuard, Bazarr, and Coin Market Cap widgets
- Allow setting HTTP method in widget.js
- Allow sending allow listed query params to proxy
2022-09-25 14:31:41 -07:00
Jason Fischer
f999f4a467 Add Sonarr refactor 2022-09-25 10:13:31 -07:00
Ben Phelps
5cfadaea7f Merge branch 'main' into widget-refactor 2022-09-25 19:44:22 +03:00
Ben Phelps
562235f828 starting of widget refactoring 2022-09-25 19:43:47 +03:00
Ben Phelps
d6f6ea9dba add meta tag 2022-09-25 19:43:27 +03:00
Ben Phelps
8bc240b934 refactor i18n to be server side 2022-09-25 19:43:00 +03:00
Ben Phelps
3ae4113043 refactor docker stats open/close 2022-09-25 19:38:02 +03:00
Anonymous
1f52435bc1 Translated using Weblate (Portuguese (Brazil))
Currently translated at 100.0% (0 of 0 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt_BR/
2022-09-25 15:20:25 +02:00
Mauricio Kalil
4d0dfcca61 Added translation using Weblate (Portuguese (Brazil)) 2022-09-25 15:20:17 +02:00
C8opmBM
ea9076652a Translated using Weblate (Romanian)
Currently translated at 100.0% (115 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ro/
2022-09-25 15:18:08 +02:00
Milo Ivir
af1a464d87 Translated using Weblate (Croatian)
Currently translated at 100.0% (115 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hr/
2022-09-25 15:18:08 +02:00
Ben Phelps
50fe6041f0 better fallback support 2022-09-24 15:13:14 +03:00
Ben Phelps
555a4b6b05 extralight is extra… light 2022-09-24 14:54:37 +03:00
Ben Phelps
7709be8118 fix Head 2022-09-24 14:53:46 +03:00
Ben Phelps
130ac76e0c update packages 2022-09-24 14:52:54 +03:00
Ben Phelps
ae315f1789 use new Manrope font, remove external font dep 2022-09-24 14:51:12 +03:00
Ben Phelps
4782e72d88 remove unused font 2022-09-24 14:49:14 +03:00
C8opmBM
d69cafee01 Translated using Weblate (Romanian)
Currently translated at 10.4% (12 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ro/
2022-09-24 13:45:23 +02:00
Anonymous
e066ed58ca Translated using Weblate (Romanian)
Currently translated at 100.0% (0 of 0 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ro/
2022-09-24 13:42:48 +02:00
C8opmBM
05a65cbf9d Added translation using Weblate (Romanian) 2022-09-24 13:42:39 +02:00
Ben Phelps
ea6a668a84 add version information 2022-09-24 01:18:37 +03:00
Ben Phelps
08615fe9f6 Update docker-publish.yml 2022-09-24 00:17:23 +03:00
SuperDOS
f8ef5ddf5a Translated using Weblate (Swedish)
Currently translated at 93.0% (107 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sv/
2022-09-23 13:44:01 +02:00
XNRavenZen
595d81dd2f Translated using Weblate (Chinese (Simplified))
Currently translated at 94.7% (109 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-23 13:44:01 +02:00
nicedc
00c654953d Translated using Weblate (Chinese (Simplified))
Currently translated at 94.7% (109 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-23 13:44:01 +02:00
Bruno Rossetto
bf2f3a7d17 Translated using Weblate (Portuguese)
Currently translated at 100.0% (115 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-23 13:44:01 +02:00
Nonoss117
612f0fde2d Translated using Weblate (French)
Currently translated at 100.0% (115 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-23 13:44:00 +02:00
Ángel Fernández Sánchez
a701e031a7 Translated using Weblate (Spanish)
Currently translated at 100.0% (115 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-23 13:44:00 +02:00
Juan Manuel Bennàssar Carretero
d51854e663 Translated using Weblate (Spanish)
Currently translated at 100.0% (115 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-23 13:44:00 +02:00
Moritz Neumann
cb9a18fd40 Translated using Weblate (German)
Currently translated at 100.0% (115 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-23 13:44:00 +02:00
Ben Phelps
ed28d69d76 Merge pull request #251 from JazzFisch/patch-nextjs-logging
Patch console object to instead use homepage's logger for logging
2022-09-23 11:51:15 +03:00
Jason Fischer
5667cedafc Merge branch 'main' into patch-nextjs-logging 2022-09-21 23:38:53 -07:00
Jason Fischer
42fe535df7 Patch console object to instead use winston for logging
- Allow setting labels via new createLogger method
- Make logger initialization more robust
2022-09-21 23:37:17 -07:00
Ben Phelps
0e1e2bde22 Update FUNDING.yml 2022-09-22 03:01:00 +03:00
Ben Phelps
1a5e2f3cda Update FUNDING.yml 2022-09-22 03:00:39 +03:00
Ben Phelps
32cb113014 Create FUNDING.yml 2022-09-22 02:57:58 +03:00
Ben Phelps
559af0cd56 Update README.md 2022-09-21 22:53:19 +03:00
Ben Phelps
0e5477eecf experiment with lazily loaded widgets 2022-09-21 22:26:58 +03:00
Jason Fischer
ab631fa26e Merge pull request #246 from JazzFisch/fix-log-folder
Write homepage.log into config folder
2022-09-21 08:46:21 -07:00
Jason Fischer
5776544c20 Write homepage.log into config folder
This will make it easier for people to find their log file(s)
2022-09-21 08:32:37 -07:00
Ben Phelps
666e2a42cf fix context state race 2022-09-21 17:39:46 +03:00
Ben Phelps
2fc1dda122 add tailwind-scollbars 2022-09-21 16:11:48 +03:00
Juan Manuel Bennàssar Carretero
0115b594d6 Translated using Weblate (Catalan)
Currently translated at 100.0% (115 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2022-09-21 11:32:07 +02:00
Juan Manuel Bennàssar Carretero
c5828978b2 Translated using Weblate (Spanish)
Currently translated at 100.0% (115 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-21 11:32:07 +02:00
Ben Phelps
3ff756e057 update readme 2022-09-21 10:09:24 +03:00
Anonymous
1c405ff4ec Translated using Weblate (Hebrew)
Currently translated at 87.8% (101 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/he/
2022-09-21 08:06:43 +02:00
Anonymous
5d1041d564 Translated using Weblate (Hungarian)
Currently translated at 93.9% (108 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hu/
2022-09-21 08:06:42 +02:00
Anonymous
9e8942398c Translated using Weblate (Croatian)
Currently translated at 7.8% (9 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hr/
2022-09-21 08:06:42 +02:00
Anonymous
a5b7c8439d Translated using Weblate (Swedish)
Currently translated at 83.4% (96 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sv/
2022-09-21 08:06:42 +02:00
Anonymous
9131a8f118 Translated using Weblate (Polish)
Currently translated at 85.2% (98 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pl/
2022-09-21 08:06:42 +02:00
Anonymous
8687fe6b26 Translated using Weblate (Catalan)
Currently translated at 93.9% (108 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2022-09-21 08:06:41 +02:00
Anonymous
1d38fd8dea Translated using Weblate (Chinese (Traditional))
Currently translated at 7.8% (9 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hant/
2022-09-21 08:06:41 +02:00
Anonymous
4186bbb3c3 Translated using Weblate (Dutch)
Currently translated at 54.7% (63 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-21 08:06:41 +02:00
Anonymous
897c71f36e Translated using Weblate (Vietnamese)
Currently translated at 38.2% (44 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-21 08:06:41 +02:00
Anonymous
f9ce9b7716 Translated using Weblate (Norwegian Bokmål)
Currently translated at 68.6% (79 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-21 08:06:40 +02:00
Anonymous
ec230ba249 Translated using Weblate (Italian)
Currently translated at 66.9% (77 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-21 08:06:40 +02:00
Anonymous
6bfa49689e Translated using Weblate (Chinese (Simplified))
Currently translated at 93.9% (108 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-21 08:06:39 +02:00
Anonymous
177acf86d7 Translated using Weblate (Russian)
Currently translated at 20.0% (23 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-21 08:06:39 +02:00
Anonymous
c89ed904cc Translated using Weblate (Portuguese)
Currently translated at 76.5% (88 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-21 08:06:39 +02:00
Anonymous
6add7c3d82 Translated using Weblate (French)
Currently translated at 96.5% (111 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-21 08:06:39 +02:00
Anonymous
c562035776 Translated using Weblate (Spanish)
Currently translated at 93.9% (108 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-21 08:06:38 +02:00
Anonymous
4757e25fdc Translated using Weblate (German)
Currently translated at 90.4% (104 of 115 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-21 08:06:38 +02:00
Nonoss117
077bc356b8 Translated using Weblate (French)
Currently translated at 100.0% (111 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-21 08:06:30 +02:00
Ben Phelps
1dff880a93 Merge pull request #230 from DevPGSV/feature/widget_strelaysrv
Add Syncthing Relay Server widget
2022-09-21 09:06:26 +03:00
Ben Phelps
122b987fa3 Merge branch 'main' into feature/widget_strelaysrv 2022-09-21 09:05:42 +03:00
Ben Phelps
c024c4f01c Merge pull request #241 from JazzFisch/add-logger
Add Winston for log handling
2022-09-21 09:03:52 +03:00
Ben Phelps
a677fbefbf add global settings context
will be useful going forward, and simplify widget props being passed around all over the place
2022-09-21 09:00:57 +03:00
Ben Phelps
244a76de0b fix bookmark styling 2022-09-21 08:58:24 +03:00
Ben Phelps
20ac15b18c allow setting a global link target 2022-09-21 08:40:19 +03:00
Anonymous
75244cc40e Translated using Weblate (Hebrew)
Currently translated at 90.9% (101 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/he/
2022-09-21 07:39:32 +02:00
Anonymous
3e731298a5 Translated using Weblate (Hungarian)
Currently translated at 97.2% (108 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hu/
2022-09-21 07:39:32 +02:00
Anonymous
ed0bf027fc Translated using Weblate (Croatian)
Currently translated at 8.1% (9 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hr/
2022-09-21 07:39:31 +02:00
Anonymous
7a10131768 Translated using Weblate (Swedish)
Currently translated at 86.4% (96 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sv/
2022-09-21 07:39:31 +02:00
Anonymous
19522b8712 Translated using Weblate (Polish)
Currently translated at 88.2% (98 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pl/
2022-09-21 07:39:31 +02:00
Anonymous
af79061a45 Translated using Weblate (Catalan)
Currently translated at 97.2% (108 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2022-09-21 07:39:31 +02:00
Anonymous
d56d9f7a50 Translated using Weblate (Chinese (Traditional))
Currently translated at 8.1% (9 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hant/
2022-09-21 07:39:30 +02:00
Anonymous
45a1a9ed5a Translated using Weblate (Dutch)
Currently translated at 56.7% (63 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-21 07:39:30 +02:00
Anonymous
50954cf3d4 Translated using Weblate (Vietnamese)
Currently translated at 39.6% (44 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-21 07:39:30 +02:00
Anonymous
6beefbf39a Translated using Weblate (Norwegian Bokmål)
Currently translated at 71.1% (79 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-21 07:39:30 +02:00
Anonymous
8f21d1ae31 Translated using Weblate (Italian)
Currently translated at 69.3% (77 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-21 07:39:29 +02:00
Anonymous
e4825531c4 Translated using Weblate (Chinese (Simplified))
Currently translated at 97.2% (108 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-21 07:39:29 +02:00
Anonymous
6174f53f37 Translated using Weblate (Russian)
Currently translated at 20.7% (23 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-21 07:39:29 +02:00
Anonymous
42baa4b188 Translated using Weblate (Portuguese)
Currently translated at 79.2% (88 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-21 07:39:28 +02:00
Anonymous
52eaddae37 Translated using Weblate (French)
Currently translated at 97.2% (108 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-21 07:39:28 +02:00
Anonymous
f43ce0db44 Translated using Weblate (Spanish)
Currently translated at 97.2% (108 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-21 07:39:28 +02:00
Anonymous
b46cb0a1f7 Translated using Weblate (German)
Currently translated at 93.6% (104 of 111 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-21 07:39:28 +02:00
Juan Manuel Bennàssar Carretero
e4e5ad7eba Translated using Weblate (Catalan)
Currently translated at 100.0% (108 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2022-09-21 07:39:20 +02:00
Ben Phelps
0e6ea57023 Merge pull request #229 from DevPGSV/feature/widget_mastodon
Add Mastodon widget
2022-09-21 08:39:16 +03:00
Jason Fischer
280bb5fc81 Add Winston for log handling
- write log data to 'homepage.log'
2022-09-20 20:16:04 -07:00
Pablo Garcia de los Salmones Valencia
077d21eb7e Updated stat literals to single words 2022-09-21 02:15:25 +02:00
Pablo Garcia de los Salmones Valencia
f281d86e8a Fixed missing text 2022-09-20 05:29:24 +02:00
Pablo Garcia de los Salmones Valencia
f7000a280e Add Syncthing Relay Server widget 2022-09-20 04:42:04 +02:00
Pablo Garcia de los Salmones Valencia
586ded6b3f Add Mastodon widget 2022-09-20 03:41:10 +02:00
3vilson
539e0f005a Translated using Weblate (German)
Currently translated at 96.2% (104 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-19 19:16:41 +02:00
Ben Phelps
330575bab3 fix links 2022-09-18 18:49:50 +03:00
Ben Phelps
30ec4aed28 Translated using Weblate (Dutch)
Currently translated at 58.3% (63 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-18 16:53:21 +02:00
Ben Phelps
ee456fd8e5 Translated using Weblate (Italian)
Currently translated at 71.2% (77 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-18 16:53:21 +02:00
Ben Phelps
ed25c8a84b Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (108 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-18 16:53:21 +02:00
Ben Phelps
b0a45fe09c Translated using Weblate (Russian)
Currently translated at 21.2% (23 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-18 16:53:20 +02:00
Nonoss117
50f0f46ad9 Translated using Weblate (French)
Currently translated at 100.0% (108 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-18 16:53:20 +02:00
Ben Phelps
bd61d459ad Translated using Weblate (Spanish)
Currently translated at 100.0% (108 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-18 16:53:20 +02:00
Ben Phelps
4f73c60d37 Translated using Weblate (German)
Currently translated at 62.0% (67 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-18 16:53:20 +02:00
Ben Phelps
7c536f0cb0 update attribution sorting 2022-09-18 17:05:31 +03:00
Ben Phelps
d5a489198a update readme 2022-09-18 17:00:40 +03:00
Ben Phelps
17f54da524 yaml validation 2022-09-18 16:41:01 +03:00
ShlomiPorush
b5065673ab Translated using Weblate (Hebrew)
Currently translated at 93.5% (101 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/he/
2022-09-18 15:13:10 +02:00
Pacux
610b0f63e0 Translated using Weblate (Catalan)
Currently translated at 100.0% (108 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2022-09-18 15:13:09 +02:00
yahoo~~
73317bda67 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (108 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-18 15:13:09 +02:00
Nonoss117
f690f3acba Translated using Weblate (French)
Currently translated at 100.0% (108 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-18 15:13:09 +02:00
Anonymous
eea9f1f6cb Translated using Weblate (Hebrew)
Currently translated at 100.0% (0 of 0 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/he/
2022-09-18 08:37:27 +02:00
Daniel Varga
d9089e8d1c Translated using Weblate (Hungarian)
Currently translated at 100.0% (108 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hu/
2022-09-18 08:37:26 +02:00
Nonoss117
bed5acc9d5 Translated using Weblate (French)
Currently translated at 100.0% (108 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-18 08:37:25 +02:00
Ángel Fernández Sánchez
f46feff445 Translated using Weblate (Spanish)
Currently translated at 100.0% (108 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-18 08:37:25 +02:00
Daniel Varga
d46a98c7d5 Translated using Weblate (German)
Currently translated at 62.0% (67 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-18 08:37:25 +02:00
ShlomiPorush
05af60df4f Added translation using Weblate (Hebrew) 2022-09-18 08:37:17 +02:00
Ben Phelps
5fc266ed81 better status icon logic for tautulli 2022-09-18 02:12:24 +03:00
Ben Phelps
38356c31b0 handle when structure differs from expectation 2022-09-18 01:38:41 +03:00
Ben Phelps
2703cfb81e update attributions and features 2022-09-17 22:03:21 +03:00
Ben Phelps
8a226ca473 Merge pull request #198 from JazzFisch/fix-incorrect-widget-values
Fix issues with incorrect values in widgets
2022-09-17 19:21:26 +03:00
Jason Fischer
33e6d54fd2 Fix issues with incorrect values in widgets
associated: #180
associated: #194
2022-09-17 09:17:03 -07:00
Ben Phelps
d36f37a4ed remove as it’s causing troubles 2022-09-17 17:23:45 +03:00
Ben Phelps
f3ebbb6547 pass errors 2022-09-17 16:55:18 +03:00
Ben Phelps
28b2f79e5b use aggregate mapped data
to reduce the size of the API responses
2022-09-17 13:05:44 +03:00
Anonymous
9a77115a30 Translated using Weblate (Hungarian)
Currently translated at 100.0% (0 of 0 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hu/
2022-09-17 09:25:24 +02:00
Daniel Varga
2d899e364d Added translation using Weblate (Hungarian) 2022-09-17 09:25:17 +02:00
Anonymous
32b881891c Translated using Weblate (Croatian)
Currently translated at 8.3% (9 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hr/
2022-09-17 09:06:55 +02:00
Anonymous
9eefc07c7c Translated using Weblate (Swedish)
Currently translated at 88.8% (96 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sv/
2022-09-17 09:06:55 +02:00
Anonymous
792accffb6 Translated using Weblate (Polish)
Currently translated at 82.4% (89 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pl/
2022-09-17 09:06:54 +02:00
Anonymous
03af88aba5 Translated using Weblate (Catalan)
Currently translated at 92.5% (100 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2022-09-17 09:06:54 +02:00
Anonymous
f56b6b4ad0 Translated using Weblate (Chinese (Traditional))
Currently translated at 8.3% (9 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hant/
2022-09-17 09:06:54 +02:00
Anonymous
4ce1681e79 Translated using Weblate (Dutch)
Currently translated at 57.4% (62 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-17 09:06:54 +02:00
Anonymous
7570fa71f0 Translated using Weblate (Vietnamese)
Currently translated at 40.7% (44 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-17 09:06:53 +02:00
Anonymous
8a61c76cd9 Translated using Weblate (Norwegian Bokmål)
Currently translated at 73.1% (79 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-17 09:06:53 +02:00
Anonymous
fbf5381699 Translated using Weblate (Italian)
Currently translated at 63.8% (69 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-17 09:06:53 +02:00
Anonymous
ff77f0db4f Translated using Weblate (Chinese (Simplified))
Currently translated at 76.8% (83 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-17 09:06:52 +02:00
Anonymous
2e30abedc9 Translated using Weblate (Russian)
Currently translated at 19.4% (21 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-17 09:06:52 +02:00
Anonymous
c4cb4f7475 Translated using Weblate (Portuguese)
Currently translated at 81.4% (88 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-17 09:06:52 +02:00
Anonymous
7432bb813e Translated using Weblate (French)
Currently translated at 96.2% (104 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-17 09:06:52 +02:00
Anonymous
572a104779 Translated using Weblate (Spanish)
Currently translated at 96.2% (104 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-17 09:06:51 +02:00
Anonymous
f77dc23d92 Translated using Weblate (German)
Currently translated at 59.2% (64 of 108 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-17 09:06:51 +02:00
nicedc
e92fc74dd3 Translated using Weblate (Chinese (Simplified))
Currently translated at 79.8% (83 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-17 09:06:42 +02:00
Nonoss117
9479c3d5c3 Translated using Weblate (French)
Currently translated at 100.0% (104 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-17 09:06:42 +02:00
Ángel Fernández Sánchez
cfc37a64e1 Translated using Weblate (Spanish)
Currently translated at 100.0% (104 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-17 09:06:42 +02:00
Ben Phelps
2d5294804c Merge pull request #192 from JazzFisch/add-qbittorrent
Add qBittorrent Widget
2022-09-17 10:06:38 +03:00
Jason Fischer
6c01a85077 Merge branch 'main' into add-qbittorrent 2022-09-16 23:19:24 -07:00
Ben Phelps
cf41e988eb fix error with no map 2022-09-17 08:38:53 +03:00
Ben Phelps
d7a161c088 remove map for now 2022-09-17 08:34:32 +03:00
Ben Phelps
379c4040fe Merge branch 'JazzFisch-proxy-with-mapping' 2022-09-17 08:32:48 +03:00
Ben Phelps
3f17618ad5 allow endpoint specific maps 2022-09-17 08:32:40 +03:00
Andy
d7be64c3d9 add backgroundOpacity option 2022-09-17 08:24:12 +03:00
Juan Manuel Bennàssar Carretero
ef7737e9be Translated using Weblate (Spanish)
Currently translated at 100.0% (104 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-17 08:24:12 +03:00
Ben Phelps
51ad3184b6 Merge pull request #183 from andrii-kryvoviaz/add-background-image-opacity
Add backgroundOpacity option
2022-09-17 07:33:35 +03:00
Jason Fischer
efc8fd878a Merge branch 'main' into add-qbittorrent 2022-09-16 19:12:41 -07:00
Jason Fischer
6da1e98c83 Add qBittorrent Widget
- extract cookie jar functionality into its own file
- use i18n for more strings in existing widgets

completes: #152
associated: #123
2022-09-16 19:11:57 -07:00
Juan Manuel Bennàssar Carretero
513a06740c Translated using Weblate (Spanish)
Currently translated at 100.0% (104 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-16 21:23:35 +02:00
Jason Fischer
743a070724 Proposal to add ability to map data in a proxy 2022-09-16 11:33:11 -07:00
Andy
5fb0e76669 add backgroundOpacity option 2022-09-16 15:31:13 +03:00
Anonymous
bedeab686e Translated using Weblate (Croatian)
Currently translated at 100.0% (0 of 0 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/hr/
2022-09-16 14:31:03 +02:00
Nonoss117
9d9fa352ce Translated using Weblate (French)
Currently translated at 100.0% (104 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-16 14:31:02 +02:00
sheep
1bfa6ce862 Added translation using Weblate (Croatian) 2022-09-16 14:30:39 +02:00
Ben Phelps
755b29c859 update readme 2022-09-16 14:18:27 +03:00
Anonymous
aab5b0247a Translated using Weblate (Swedish)
Currently translated at 92.3% (96 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sv/
2022-09-16 13:06:38 +02:00
Anonymous
d7e4b0bd17 Translated using Weblate (Polish)
Currently translated at 85.5% (89 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pl/
2022-09-16 13:06:38 +02:00
Anonymous
3bacdadb80 Translated using Weblate (Catalan)
Currently translated at 96.1% (100 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2022-09-16 13:06:38 +02:00
Anonymous
1d75ee44ed Translated using Weblate (Chinese (Traditional))
Currently translated at 8.6% (9 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hant/
2022-09-16 13:06:37 +02:00
Anonymous
230cc343af Translated using Weblate (Dutch)
Currently translated at 59.6% (62 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-16 13:06:37 +02:00
Anonymous
b318ee165c Translated using Weblate (Vietnamese)
Currently translated at 42.3% (44 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-16 13:06:37 +02:00
Anonymous
f677646365 Translated using Weblate (Norwegian Bokmål)
Currently translated at 75.9% (79 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-16 13:06:36 +02:00
Anonymous
8db7d820d7 Translated using Weblate (Italian)
Currently translated at 66.3% (69 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-16 13:06:36 +02:00
Anonymous
adb0632566 Translated using Weblate (Chinese (Simplified))
Currently translated at 79.8% (83 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-16 13:06:36 +02:00
Anonymous
4d5c8db333 Translated using Weblate (Russian)
Currently translated at 20.1% (21 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-16 13:06:35 +02:00
Anonymous
01d6a3d5f8 Translated using Weblate (Portuguese)
Currently translated at 84.6% (88 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-16 13:06:35 +02:00
Anonymous
fbeadbc32f Translated using Weblate (French)
Currently translated at 96.1% (100 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-16 13:06:35 +02:00
Anonymous
1289be888f Translated using Weblate (Spanish)
Currently translated at 96.1% (100 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-16 13:06:35 +02:00
Anonymous
aa7e3a955c Translated using Weblate (German)
Currently translated at 61.5% (64 of 104 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-16 13:06:34 +02:00
SuperDOS
2823f3b921 Translated using Weblate (Swedish)
Currently translated at 96.0% (96 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sv/
2022-09-16 13:06:26 +02:00
Ben Phelps
ddb2a74540 add AdGuard widget 2022-09-16 14:05:56 +03:00
Ben Phelps
37d8d7a2f8 fix indentation 2022-09-16 14:05:43 +03:00
Ben Phelps
578b715a1f allow HTTP basic auth on generic proxy 2022-09-16 14:05:27 +03:00
Anonymous
f14a811ce9 Translated using Weblate (Swedish)
Currently translated at 100.0% (0 of 0 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/sv/
2022-09-16 11:02:49 +02:00
SuperDOS
06dd6d2213 Added translation using Weblate (Swedish) 2022-09-16 11:02:42 +02:00
Pacux
72471c47f4 Translated using Weblate (Catalan)
Currently translated at 100.0% (100 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2022-09-16 10:56:30 +02:00
Nonoss117
aec5f7173c Translated using Weblate (French)
Currently translated at 100.0% (100 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-16 10:56:29 +02:00
Ángel Fernández Sánchez
f7b68789ac Translated using Weblate (Spanish)
Currently translated at 100.0% (100 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-16 10:56:29 +02:00
Ángel Fernández Sánchez
0672da621e Translated using Weblate (Spanish)
Currently translated at 100.0% (100 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-16 10:40:37 +02:00
Juan Manuel Bennàssar Carretero
a7f9b78533 Translated using Weblate (Spanish)
Currently translated at 100.0% (100 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-16 10:40:36 +02:00
Ben Phelps
0075429e08 add greeting and datetime info widgets 2022-09-16 10:53:12 +03:00
Ben Phelps
43f7ccd166 update readme attributions 2022-09-16 10:49:20 +03:00
Ángel Fernández Sánchez
8c64e0f288 Translated using Weblate (Spanish)
Currently translated at 100.0% (100 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-16 09:10:38 +02:00
Juan Manuel Bennàssar Carretero
c91a387833 Translated using Weblate (Spanish)
Currently translated at 100.0% (100 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-16 09:10:38 +02:00
Ben Phelps
93d5dd88ba add options for layout, theme and color settings 2022-09-15 19:58:41 +03:00
Ben Phelps
05427253b9 tweak streaming widget spacings 2022-09-15 19:53:48 +03:00
Ben Phelps
e2bc541089 show transcoding info on streaming widgets 2022-09-15 19:48:23 +03:00
Kamil Ganczarek
9a959bab16 Translated using Weblate (Polish)
Currently translated at 89.0% (89 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pl/
2022-09-15 11:30:42 +02:00
Anonymous
45ca4a15f7 Translated using Weblate (Polish)
Currently translated at 100.0% (0 of 0 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pl/
2022-09-15 11:01:12 +02:00
Kamil Ganczarek
ddd2ff53ff Added translation using Weblate (Polish) 2022-09-15 11:01:05 +02:00
Nonoss117
5c3266b48f Translated using Weblate (French)
Currently translated at 100.0% (100 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-15 10:58:49 +02:00
Ben Phelps
0da6db9d9f update readme with supported integrations 2022-09-15 09:00:40 +03:00
Ben Phelps
adeffbcf71 update readme 2022-09-15 08:44:52 +03:00
Anonymous
f0ca7b753f Translated using Weblate (Catalan)
Currently translated at 93.0% (93 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2022-09-15 07:21:24 +02:00
Anonymous
1bbde65121 Translated using Weblate (Chinese (Traditional))
Currently translated at 9.0% (9 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hant/
2022-09-15 07:21:24 +02:00
Anonymous
3acdf041e9 Translated using Weblate (Dutch)
Currently translated at 62.0% (62 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-15 07:21:23 +02:00
Anonymous
fce755f0c4 Translated using Weblate (Vietnamese)
Currently translated at 44.0% (44 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-15 07:21:23 +02:00
Anonymous
b1cdccc020 Translated using Weblate (Norwegian Bokmål)
Currently translated at 79.0% (79 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-15 07:21:23 +02:00
Anonymous
eee070f1cd Translated using Weblate (Italian)
Currently translated at 69.0% (69 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-15 07:21:23 +02:00
Anonymous
e36dd56e3b Translated using Weblate (Chinese (Simplified))
Currently translated at 83.0% (83 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-15 07:21:22 +02:00
Anonymous
aa7d08e93f Translated using Weblate (Russian)
Currently translated at 21.0% (21 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-15 07:21:22 +02:00
Anonymous
df67896a55 Translated using Weblate (Portuguese)
Currently translated at 88.0% (88 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-15 07:21:22 +02:00
Anonymous
3fb790c33c Translated using Weblate (French)
Currently translated at 95.0% (95 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-15 07:21:21 +02:00
Anonymous
850a1a39fe Translated using Weblate (Spanish)
Currently translated at 93.0% (93 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-15 07:21:21 +02:00
Anonymous
942b575c18 Translated using Weblate (German)
Currently translated at 64.0% (64 of 100 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-15 07:21:21 +02:00
Ben Phelps
6dc53052b6 Merge pull request #163 from JazzFisch/add-lidarr
Add Lidarr widget
2022-09-15 08:21:10 +03:00
Jason Fischer
7e99b3e505 Merge branch 'main' into add-lidarr 2022-09-14 19:41:43 -07:00
Anonymous
0c474e6b74 Translated using Weblate (Catalan)
Currently translated at 95.8% (93 of 97 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2022-09-15 04:36:31 +02:00
Anonymous
d5b92478ba Translated using Weblate (Chinese (Traditional))
Currently translated at 9.2% (9 of 97 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hant/
2022-09-15 04:36:31 +02:00
Anonymous
3b45699e58 Translated using Weblate (Dutch)
Currently translated at 63.9% (62 of 97 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-15 04:36:31 +02:00
Anonymous
587a317e91 Translated using Weblate (Vietnamese)
Currently translated at 45.3% (44 of 97 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-15 04:36:31 +02:00
Anonymous
62db38b0d1 Translated using Weblate (Norwegian Bokmål)
Currently translated at 81.4% (79 of 97 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-15 04:36:31 +02:00
Anonymous
34ccca6a91 Translated using Weblate (Italian)
Currently translated at 71.1% (69 of 97 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-15 04:36:30 +02:00
Anonymous
bf94d6bf5b Translated using Weblate (Chinese (Simplified))
Currently translated at 85.5% (83 of 97 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-15 04:36:30 +02:00
Anonymous
fc0658574c Translated using Weblate (Russian)
Currently translated at 21.6% (21 of 97 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-15 04:36:30 +02:00
Anonymous
b9e8ee4d0e Translated using Weblate (Portuguese)
Currently translated at 90.7% (88 of 97 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-15 04:36:30 +02:00
Anonymous
47dc1a3960 Translated using Weblate (French)
Currently translated at 97.9% (95 of 97 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-15 04:36:29 +02:00
Anonymous
6796f5cb28 Translated using Weblate (Spanish)
Currently translated at 95.8% (93 of 97 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-15 04:36:29 +02:00
Anonymous
f5fb5b32e4 Translated using Weblate (German)
Currently translated at 65.9% (64 of 97 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-15 04:36:29 +02:00
Trung Le
3941e7fb1c Translated using Weblate (Vietnamese)
Currently translated at 46.3% (44 of 95 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-15 04:36:23 +02:00
Nonoss117
a28051fa16 Translated using Weblate (French)
Currently translated at 100.0% (95 of 95 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-15 04:36:23 +02:00
Ben Phelps
ace1610dfc Merge pull request #160 from JazzFisch/add-bazarr
Add Bazarr widget
2022-09-15 05:36:19 +03:00
Jason Fischer
cf2f987fd4 Update completed album logic 2022-09-14 19:36:15 -07:00
Jason Fischer
1f2639fbb5 Add Lidarr widget 2022-09-14 19:30:51 -07:00
Ben Phelps
3c2880e4ba allow search to be auto-focused 2022-09-15 05:28:40 +03:00
Ben Phelps
db18519c16 allow changing language from settings.yaml 2022-09-15 05:17:30 +03:00
Jason Fischer
b520713dc3 Add Bazarr widget
associated: #110
2022-09-14 16:15:26 -07:00
Anonymous
15a8c4f0d7 Translated using Weblate (Catalan)
Currently translated at 97.8% (93 of 95 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2022-09-14 21:29:51 +02:00
Anonymous
a7d80fec89 Translated using Weblate (Chinese (Traditional))
Currently translated at 9.4% (9 of 95 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hant/
2022-09-14 21:29:51 +02:00
Anonymous
d32ecc9080 Translated using Weblate (Dutch)
Currently translated at 65.2% (62 of 95 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-14 21:29:51 +02:00
Anonymous
370f156ae0 Translated using Weblate (Vietnamese)
Currently translated at 34.7% (33 of 95 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-14 21:29:50 +02:00
Anonymous
97736d4163 Translated using Weblate (Norwegian Bokmål)
Currently translated at 83.1% (79 of 95 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-14 21:29:50 +02:00
Anonymous
a0338beaae Translated using Weblate (Italian)
Currently translated at 72.6% (69 of 95 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-14 21:29:50 +02:00
Anonymous
8bb850d96b Translated using Weblate (Chinese (Simplified))
Currently translated at 87.3% (83 of 95 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-14 21:29:50 +02:00
Anonymous
999e55c7af Translated using Weblate (Russian)
Currently translated at 22.1% (21 of 95 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-14 21:29:49 +02:00
Anonymous
c3533de7fa Translated using Weblate (Portuguese)
Currently translated at 92.6% (88 of 95 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-14 21:29:49 +02:00
Anonymous
0543f28fd4 Translated using Weblate (French)
Currently translated at 97.8% (93 of 95 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-14 21:29:49 +02:00
Anonymous
48f73eab06 Translated using Weblate (Spanish)
Currently translated at 97.8% (93 of 95 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-14 21:29:49 +02:00
Anonymous
14c572102e Translated using Weblate (German)
Currently translated at 67.3% (64 of 95 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-14 21:29:48 +02:00
Juan Manuel Bennàssar Carretero
c58a52c797 Translated using Weblate (Catalan)
Currently translated at 100.0% (93 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2022-09-14 21:29:44 +02:00
nicedc
8c0c0f1617 Translated using Weblate (Chinese (Simplified))
Currently translated at 89.2% (83 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-14 21:29:44 +02:00
Ben Phelps
b154314b79 Translated using Weblate (Russian)
Currently translated at 22.5% (21 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-14 21:29:44 +02:00
Nonoss117
70010d09d6 Translated using Weblate (French)
Currently translated at 100.0% (93 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-14 21:29:44 +02:00
Juan Manuel Bennàssar Carretero
0b24533a13 Translated using Weblate (Spanish)
Currently translated at 100.0% (93 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-14 21:29:44 +02:00
Ángel Fernández Sánchez
be78d063a4 Translated using Weblate (Spanish)
Currently translated at 100.0% (93 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-14 21:29:44 +02:00
Ben Phelps
4cee24bd96 Merge pull request #156 from JazzFisch/add-jackett-widget
Add the Jackett widget
2022-09-14 22:29:39 +03:00
Jason Fischer
0a5cdfc57a Refactor setting cookie header into own method 2022-09-14 11:08:36 -07:00
Jason Fischer
5009f9d3f2 Merge branch 'main' into add-jackett-widget 2022-09-14 10:50:53 -07:00
Jason Fischer
f750876425 Add the Jackett widget
- add the follow-redirect package
- add the tough-cookie package

Jackett API uses a redirect mechanism to set a CSRF token.
This CSRF token is stored in a cookie that is required to
be present or the API won't work.
2022-09-14 10:46:52 -07:00
Ben Phelps
680d488647 Update docker-publish.yml 2022-09-14 19:19:22 +03:00
Ben Phelps
81af23ecb5 revert to previous Dockerfile 2022-09-14 19:19:02 +03:00
Ben Phelps
d4b05b2612 experiment with entrypoint for backwards compat 2022-09-14 19:04:19 +03:00
Ben Phelps
5a284bff26 Update docker-publish.yml 2022-09-14 16:08:32 +03:00
Ben Phelps
f1a9191e84 use linuxserver.io base image 2022-09-14 16:04:00 +03:00
Ben Phelps
d876454638 experimental docker user support 2022-09-14 15:04:40 +03:00
Ben Phelps
06de8dd532 update contributions 2022-09-14 14:43:51 +03:00
Anonymous
70592c2438 Translated using Weblate (Catalan)
Currently translated at 100.0% (0 of 0 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ca/
2022-09-14 09:14:51 +02:00
Juan Manuel Bennàssar Carretero
5acaa31a1f Added translation using Weblate (Catalan) 2022-09-14 09:14:45 +02:00
Ben Phelps
79e5ff2fea fix linting 2022-09-14 09:23:21 +03:00
Ben Phelps
7f91fe59e2 allow setting base and favicon 2022-09-14 09:11:55 +03:00
Ben Phelps
b40dad3d3e remove unused package 2022-09-14 09:11:44 +03:00
Anonymous
f9f816845f Translated using Weblate (Chinese (Traditional))
Currently translated at 9.6% (9 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hant/
2022-09-14 08:10:06 +02:00
Anonymous
193b58d0fc Translated using Weblate (Dutch)
Currently translated at 66.6% (62 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-14 08:10:05 +02:00
Anonymous
b7f490544a Translated using Weblate (Vietnamese)
Currently translated at 35.4% (33 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-14 08:10:05 +02:00
Anonymous
5d85e3c0e2 Translated using Weblate (Norwegian Bokmål)
Currently translated at 84.9% (79 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-14 08:10:05 +02:00
Anonymous
75214c345a Translated using Weblate (Italian)
Currently translated at 74.1% (69 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-14 08:10:04 +02:00
Anonymous
6d55e74ae4 Translated using Weblate (Chinese (Simplified))
Currently translated at 86.0% (80 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-14 08:10:04 +02:00
Anonymous
710f979f94 Translated using Weblate (Russian)
Currently translated at 13.9% (13 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-14 08:10:04 +02:00
Anonymous
c2a036c526 Translated using Weblate (Portuguese)
Currently translated at 94.6% (88 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-14 08:10:04 +02:00
Anonymous
a6c52df4cb Translated using Weblate (French)
Currently translated at 95.6% (89 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-14 08:10:03 +02:00
Anonymous
4d1ad16ea2 Translated using Weblate (Spanish)
Currently translated at 95.6% (89 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-14 08:10:03 +02:00
Anonymous
94c093ea57 Translated using Weblate (German)
Currently translated at 68.8% (64 of 93 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-14 08:10:03 +02:00
Francisco Coelho
acd421c617 Translated using Weblate (Portuguese)
Currently translated at 98.8% (88 of 89 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-14 08:09:57 +02:00
Nonoss117
4d2004c8c9 Translated using Weblate (French)
Currently translated at 100.0% (89 of 89 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-14 08:09:57 +02:00
Ángel Fernández Sánchez
6c5bfa466f Translated using Weblate (Spanish)
Currently translated at 100.0% (89 of 89 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-14 08:09:57 +02:00
Ben Phelps
794938c525 Merge branch 'ItsJustMeChris-main' 2022-09-14 09:09:39 +03:00
Ben Phelps
62188ffdc7 cleanup 2022-09-14 09:09:11 +03:00
Chris McGravey
34f7bd4341 Merge remote-tracking branch 'origin/main' 2022-09-13 17:29:35 -05:00
Chris McGravey
6b45825472 translate 2022-09-13 17:29:02 -05:00
Ben Phelps
b81a5d1e51 Update common.json 2022-09-14 01:15:06 +03:00
Ben Phelps
5d9e90f033 Update common.json 2022-09-14 01:14:42 +03:00
Ben Phelps
55a3e6880b Update common.json 2022-09-14 01:14:20 +03:00
Ben Phelps
beee9ecd84 Update common.json 2022-09-14 01:14:00 +03:00
Ben Phelps
b94d7a4ae8 Update common.json 2022-09-14 01:13:46 +03:00
Ben Phelps
331999c1a4 Update common.json 2022-09-14 01:13:08 +03:00
Ben Phelps
e5db1ec848 Update common.json 2022-09-14 01:12:50 +03:00
Ben Phelps
17d7161374 Update common.json 2022-09-14 01:12:13 +03:00
Ben Phelps
06d4f2b9f3 Update common.json 2022-09-14 01:11:55 +03:00
Ben Phelps
4b69fdefef Update common.json 2022-09-14 01:11:30 +03:00
Ben Phelps
13db31ede0 Update common.json 2022-09-14 01:11:00 +03:00
Ben Phelps
22a073ba1a Update common.json 2022-09-14 01:10:38 +03:00
Ben Phelps
ce9c115f3d Update common.json 2022-09-14 01:10:11 +03:00
Chris McGravey
767aa9b3e1 Update CoinMarketCap widget to have time selector 2022-09-13 15:35:53 -05:00
Ben Phelps
16ddb2461b Update feature_request.md 2022-09-13 21:27:43 +03:00
Ben Phelps
f75827c4c6 Update bug_report.md 2022-09-13 21:27:05 +03:00
Ben Phelps
cf03e60186 Update bug_report.md 2022-09-13 21:26:20 +03:00
Ben Phelps
8ee071769a Update bug_report.md 2022-09-13 21:25:53 +03:00
Ben Phelps
b312183a7b Update issue templates 2022-09-13 21:22:14 +03:00
Ben Phelps
5baaf5faec Create CONTRIBUTING.md 2022-09-13 21:15:55 +03:00
Ben Phelps
d685bfd11d Merge pull request #148 from benphelps/add-code-of-conduct-1
Create CODE_OF_CONDUCT.md
2022-09-13 20:56:17 +03:00
Ben Phelps
cf4b230b7a Create CODE_OF_CONDUCT.md 2022-09-13 20:56:08 +03:00
Ben Phelps
d46f5f4613 reverse status icons for Tautulli 2022-09-13 20:48:08 +03:00
Ben Phelps
945ed854a4 remove experimental tag again 2022-09-13 12:07:20 +03:00
Anonymous
25f0672c18 Translated using Weblate (Chinese (Traditional))
Currently translated at 10.1% (9 of 89 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hant/
2022-09-13 07:08:13 +02:00
Anonymous
6f6c8b2ae0 Translated using Weblate (Dutch)
Currently translated at 69.6% (62 of 89 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-13 07:08:13 +02:00
Anonymous
7e62410f98 Translated using Weblate (Vietnamese)
Currently translated at 37.0% (33 of 89 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-13 07:08:13 +02:00
Anonymous
f49e8486c7 Translated using Weblate (Norwegian Bokmål)
Currently translated at 88.7% (79 of 89 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-13 07:08:12 +02:00
Anonymous
844bc23f8c Translated using Weblate (Italian)
Currently translated at 77.5% (69 of 89 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-13 07:08:12 +02:00
Anonymous
850226b260 Translated using Weblate (Chinese (Simplified))
Currently translated at 89.8% (80 of 89 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-13 07:08:12 +02:00
Anonymous
c5100567d6 Translated using Weblate (Russian)
Currently translated at 14.6% (13 of 89 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-13 07:08:12 +02:00
Anonymous
5344854199 Translated using Weblate (Portuguese)
Currently translated at 29.2% (26 of 89 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-13 07:08:11 +02:00
Anonymous
d790b17507 Translated using Weblate (French)
Currently translated at 95.5% (85 of 89 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-13 07:08:11 +02:00
Anonymous
667d3851ce Translated using Weblate (Spanish)
Currently translated at 88.7% (79 of 89 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-13 07:08:11 +02:00
Anonymous
ba4d345f4f Translated using Weblate (German)
Currently translated at 71.9% (64 of 89 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-13 07:08:10 +02:00
Ben Phelps
52816426fc Merge pull request #141 from JazzFisch/add-transmission-widget
Add transmission widget
2022-09-13 08:08:00 +03:00
nicedc
38a423cf2a Translated using Weblate (Chinese (Simplified))
Currently translated at 94.1% (80 of 85 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-13 06:46:00 +02:00
Anonymous
75ad7eb7e4 Translated using Weblate (Chinese (Traditional))
Currently translated at 100.0% (0 of 0 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hant/
2022-09-13 05:41:06 +02:00
Nonoss117
533c3b7b1b Translated using Weblate (French)
Currently translated at 100.0% (85 of 85 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-13 05:41:05 +02:00
Fallenzone
1c98999994 Added translation using Weblate (Chinese (Traditional)) 2022-09-13 05:41:00 +02:00
Jason Fischer
b19b4f047e Fix linting errors 2022-09-12 20:06:00 -07:00
Jason Fischer
95b6ea0e23 Merge main 2022-09-12 19:38:43 -07:00
Jason Fischer
b3db549a65 Add Transmission widget
- Update http.js to support writing request bodies
- Update http.js to support returning all response headers

resolves: #104
2022-09-12 19:35:47 -07:00
Allan Nordhøy
cd768000e9 Translated using Weblate (Norwegian Bokmål)
Currently translated at 92.9% (79 of 85 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-13 01:11:43 +02:00
Nonoss117
da6099c29d Translated using Weblate (French)
Currently translated at 98.8% (84 of 85 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-13 01:11:43 +02:00
Ben Phelps
d36e569ede Update README.md 2022-09-12 21:29:19 +03:00
Ben Phelps
eca3757af5 update features and attribution 2022-09-12 21:16:42 +03:00
Anonymous
7d8634ce5e Translated using Weblate (Dutch)
Currently translated at 72.9% (62 of 85 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-12 20:14:12 +02:00
Anonymous
d4f6785946 Translated using Weblate (Vietnamese)
Currently translated at 38.8% (33 of 85 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-12 20:14:12 +02:00
Anonymous
b468045039 Translated using Weblate (Norwegian Bokmål)
Currently translated at 75.2% (64 of 85 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-12 20:14:12 +02:00
Anonymous
f3b4f21c2e Translated using Weblate (Italian)
Currently translated at 81.1% (69 of 85 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-12 20:14:12 +02:00
Anonymous
a50ae64397 Translated using Weblate (Chinese (Simplified))
Currently translated at 92.9% (79 of 85 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-12 20:14:11 +02:00
Anonymous
2a5c58e138 Translated using Weblate (Russian)
Currently translated at 15.2% (13 of 85 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-12 20:14:11 +02:00
Anonymous
d21945a6e6 Translated using Weblate (Portuguese)
Currently translated at 30.5% (26 of 85 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-12 20:14:11 +02:00
Anonymous
0c572cb029 Translated using Weblate (French)
Currently translated at 47.0% (40 of 85 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-12 20:14:11 +02:00
Anonymous
9d30b952ee Translated using Weblate (Spanish)
Currently translated at 92.9% (79 of 85 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-12 20:14:11 +02:00
Anonymous
e32876d08d Translated using Weblate (German)
Currently translated at 75.2% (64 of 85 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-12 20:14:10 +02:00
Ben Phelps
340b138962 Add expanded view for resource widgets 2022-09-12 21:13:57 +03:00
Ben Phelps
7ae0ba31cb remove backdrop-blur until it can be made opt-in 2022-09-12 21:13:37 +03:00
Anonymous
f566671975 Translated using Weblate (Dutch)
Currently translated at 73.8% (62 of 84 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-12 20:11:38 +02:00
Anonymous
b7ff123e44 Translated using Weblate (Vietnamese)
Currently translated at 39.2% (33 of 84 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-12 20:11:38 +02:00
Anonymous
e1c34bc489 Translated using Weblate (Norwegian Bokmål)
Currently translated at 76.1% (64 of 84 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-12 20:11:38 +02:00
Anonymous
dedd341e02 Translated using Weblate (Italian)
Currently translated at 82.1% (69 of 84 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-12 20:11:37 +02:00
Anonymous
dc8fc04b57 Translated using Weblate (Chinese (Simplified))
Currently translated at 94.0% (79 of 84 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-12 20:11:37 +02:00
Anonymous
6a85859a35 Translated using Weblate (Russian)
Currently translated at 15.4% (13 of 84 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-12 20:11:37 +02:00
Anonymous
ff1e8d9e8c Translated using Weblate (Portuguese)
Currently translated at 30.9% (26 of 84 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-12 20:11:36 +02:00
Anonymous
16da998452 Translated using Weblate (French)
Currently translated at 47.6% (40 of 84 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-12 20:11:36 +02:00
Anonymous
2fc7c6ab99 Translated using Weblate (Spanish)
Currently translated at 94.0% (79 of 84 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-12 20:11:36 +02:00
Anonymous
834f33e5a5 Translated using Weblate (German)
Currently translated at 76.1% (64 of 84 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-12 20:11:36 +02:00
nicedc
90a13a4e83 Translated using Weblate (Chinese (Simplified))
Currently translated at 100.0% (79 of 79 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-12 20:11:29 +02:00
Ángel Fernández Sánchez
e4343a4f2f Translated using Weblate (Spanish)
Currently translated at 100.0% (79 of 79 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-12 20:11:29 +02:00
Ben Phelps
7852797bab Merge pull request #134 from xicopitz/main
Add Prowlarr widget
2022-09-12 21:11:25 +03:00
Francisco Coelho
4a93d2ba1e remove prowlarr locales 2022-09-12 18:27:34 +01:00
Francisco Coelho
9287d711dc Update prowlarr.jsx 2022-09-12 18:00:53 +01:00
Francisco Coelho
b5538655e0 Add Prowlarr widget 2022-09-12 17:56:04 +01:00
Ben Phelps
406358aae9 package coinmarketcap logo 2022-09-12 18:19:07 +03:00
Ben Phelps
a5d59e7e45 images/future is no longer experimental 2022-09-12 14:30:57 +03:00
Ben Phelps
92a4ad0c5e update packages 2022-09-12 14:29:55 +03:00
Ben Phelps
d963bcd0c4 Update README.md 2022-09-12 13:45:46 +03:00
Ben Phelps
2e4125c81c Update README.md 2022-09-12 13:34:27 +03:00
Ben Phelps
5293ff3580 reorganize contributions in readme 2022-09-12 13:33:55 +03:00
Anonymous
7a1349df83 Translated using Weblate (Dutch)
Currently translated at 78.4% (62 of 79 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-12 11:41:23 +02:00
Anonymous
de8de8f731 Translated using Weblate (Vietnamese)
Currently translated at 41.7% (33 of 79 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-12 11:41:23 +02:00
Anonymous
6d36382436 Translated using Weblate (Norwegian Bokmål)
Currently translated at 81.0% (64 of 79 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-12 11:41:23 +02:00
Anonymous
e31833b649 Translated using Weblate (Italian)
Currently translated at 87.3% (69 of 79 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-12 11:41:23 +02:00
Anonymous
2dce18563d Translated using Weblate (Chinese (Simplified))
Currently translated at 75.9% (60 of 79 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-12 11:41:22 +02:00
Anonymous
aa55c27ab0 Translated using Weblate (Russian)
Currently translated at 16.4% (13 of 79 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-12 11:41:22 +02:00
Anonymous
16e321af54 Translated using Weblate (French)
Currently translated at 50.6% (40 of 79 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-12 11:41:22 +02:00
Anonymous
c4edb29ff3 Translated using Weblate (Spanish)
Currently translated at 87.3% (69 of 79 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-12 11:41:21 +02:00
Anonymous
1d5cc05941 Translated using Weblate (German)
Currently translated at 81.0% (64 of 79 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-12 11:41:21 +02:00
Ben Phelps
9faae7cb67 allow Weblate to handle missing translations 2022-09-12 12:41:03 +03:00
Ben Phelps
ea06fbe666 js linting 2022-09-12 12:39:04 +03:00
Ben Phelps
cc0b4be50c cleanup coinmarketcap widget 2022-09-12 12:38:50 +03:00
Ben Phelps
ea55cde043 Merge pull request #121 from xicopitz/main
Gotify
2022-09-12 12:36:38 +03:00
Francisco Coelho
840c88db89 Update widget.jsx
duplicated widget name
2022-09-12 10:23:44 +01:00
Francisco Coelho
8e8c9755a3 Merge branch 'benphelps:main' into main 2022-09-12 10:07:06 +01:00
Francisco Coelho
ba3b48e8ce Gotify 2022-09-12 10:06:47 +01:00
Ben Phelps
d3806f7d5b better handle non-clickable service tiles 2022-09-12 11:55:01 +03:00
Francisco Coelho
0c9c1c599f Merge branch 'main' of https://github.com/xicopitz/homepage 2022-09-12 09:37:42 +01:00
Francisco Coelho
af02440c40 Revert "Update credentialed.js"
This reverts commit eeac1200e7.
2022-09-12 09:31:44 +01:00
Ben Phelps
cd53440eff fix search and weather widget spacing 2022-09-12 11:00:15 +03:00
Ben Phelps
3660140539 consolidate api handlers 2022-09-12 10:59:56 +03:00
Anonymous
7bf1bf5369 Translated using Weblate (Dutch)
Currently translated at 81.5% (62 of 76 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-12 09:41:25 +02:00
Anonymous
898e30d6de Translated using Weblate (Vietnamese)
Currently translated at 43.4% (33 of 76 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-12 09:41:25 +02:00
Anonymous
a792d213e9 Translated using Weblate (Norwegian Bokmål)
Currently translated at 84.2% (64 of 76 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-12 09:41:25 +02:00
Anonymous
ebee953ebc Translated using Weblate (Italian)
Currently translated at 90.7% (69 of 76 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-12 09:41:25 +02:00
Anonymous
200ab220e8 Translated using Weblate (Chinese (Simplified))
Currently translated at 78.9% (60 of 76 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-12 09:41:24 +02:00
Anonymous
2499d25ce6 Translated using Weblate (Russian)
Currently translated at 17.1% (13 of 76 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-12 09:41:24 +02:00
Anonymous
42356166c0 Translated using Weblate (Portuguese)
Currently translated at 30.2% (23 of 76 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-12 09:41:24 +02:00
Anonymous
80a31c8427 Translated using Weblate (French)
Currently translated at 52.6% (40 of 76 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-12 09:41:24 +02:00
Anonymous
867c6f9e97 Translated using Weblate (Spanish)
Currently translated at 90.7% (69 of 76 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-12 09:41:24 +02:00
Anonymous
ee9194fce1 Translated using Weblate (German)
Currently translated at 84.2% (64 of 76 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-12 09:41:23 +02:00
Ben Phelps
f6322077a4 Merge pull request #118 from ItsJustMeChris/main
Add coin market cap module
2022-09-12 10:41:17 +03:00
Ben Phelps
15a0e6cc54 Merge branch 'main' into main 2022-09-12 10:40:56 +03:00
Anonymous
5ee5adbb1e Translated using Weblate (Dutch)
Currently translated at 82.6% (62 of 75 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-12 09:33:05 +02:00
Anonymous
1d4b3eee9b Translated using Weblate (Vietnamese)
Currently translated at 44.0% (33 of 75 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-12 09:33:05 +02:00
Anonymous
fe971d23f8 Translated using Weblate (Norwegian Bokmål)
Currently translated at 85.3% (64 of 75 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-12 09:33:04 +02:00
Anonymous
34bf49845f Translated using Weblate (Italian)
Currently translated at 92.0% (69 of 75 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-12 09:33:04 +02:00
Anonymous
34468e5bb0 Translated using Weblate (Chinese (Simplified))
Currently translated at 80.0% (60 of 75 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-12 09:33:04 +02:00
Anonymous
d0dd52c5c2 Translated using Weblate (Russian)
Currently translated at 17.3% (13 of 75 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-12 09:33:04 +02:00
Anonymous
98cca4ca8b Translated using Weblate (Portuguese)
Currently translated at 30.6% (23 of 75 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-12 09:33:03 +02:00
Anonymous
b88463a785 Translated using Weblate (French)
Currently translated at 53.3% (40 of 75 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-12 09:33:03 +02:00
Anonymous
6409188de8 Translated using Weblate (Spanish)
Currently translated at 92.0% (69 of 75 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-12 09:33:03 +02:00
Anonymous
510973c761 Translated using Weblate (German)
Currently translated at 85.3% (64 of 75 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-12 09:33:02 +02:00
Ben Phelps
4480c26910 allow weblate to apply new strings 2022-09-12 10:32:40 +03:00
Ben Phelps
e778595296 Merge branch 'main' of github.com:benphelps/homepage
# Conflicts:
#	public/locales/it/common.json
2022-09-12 10:32:22 +03:00
Ben Phelps
f84ff7cedc allow weblate to apply new strings 2022-09-12 10:26:03 +03:00
Luca Pellegrino
04f98ae7a9 Translated using Weblate (Italian)
Currently translated at 100.0% (69 of 69 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-12 09:23:53 +02:00
Nonoss117
8ef3d7c20e Translated using Weblate (French)
Currently translated at 53.6% (37 of 69 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-12 09:23:53 +02:00
Ángel Fernández Sánchez
428fd6cbba Translated using Weblate (Spanish)
Currently translated at 100.0% (69 of 69 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-12 09:23:53 +02:00
Ben Phelps
ee79335eff Merge pull request #116 from JazzFisch/additional-widgets
Add Readarr and SABnzbd widgets
2022-09-12 10:23:49 +03:00
Ben Phelps
83d7100dd1 normalize media streaming widget padding 2022-09-12 09:41:44 +03:00
Chris McGravey
ccd9049806 Merge branch 'main' of https://github.com/ItsJustMeChris/homepage 2022-09-12 01:38:43 -05:00
Chris McGravey
769f36fa8e - Change block to return configure translation text 2022-09-12 01:38:29 -05:00
Chris
ffe89b02e9 Merge branch 'benphelps:main' into main 2022-09-12 01:32:09 -05:00
Chris McGravey
1c158f743c - Add CoinMarketCap widget 2022-09-12 01:30:42 -05:00
Ben Phelps
4531985032 fix standalone docker widget 2022-09-12 06:18:51 +03:00
Jason Fischer
f8aa1ba391 Add Readarr and SABnzbd widgets 2022-09-11 19:49:18 -07:00
Francisco Coelho
9d790894d5 Sabnzbd Support 2022-09-12 02:22:39 +01:00
Francisco Coelho
eeac1200e7 Update credentialed.js 2022-09-11 22:11:14 +01:00
Francisco Coelho
a304d87b8a Merge branch 'main' of https://github.com/xicopitz/homepage 2022-09-11 22:08:11 +01:00
Ben Phelps
ffbb1f5f0b tweak widget layouts for mobile 2022-09-11 21:02:33 +03:00
Ben Phelps
ad53119088 fix theme selector on mobile 2022-09-11 19:11:58 +03:00
Anonymous
fe1c525fb7 Translated using Weblate (Dutch)
Currently translated at 88.4% (61 of 69 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-11 16:24:48 +02:00
Anonymous
323375e8e4 Translated using Weblate (Vietnamese)
Currently translated at 46.3% (32 of 69 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-11 16:24:48 +02:00
Anonymous
8af27ea86d Translated using Weblate (Norwegian Bokmål)
Currently translated at 92.7% (64 of 69 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-11 16:24:48 +02:00
Anonymous
9335be0049 Translated using Weblate (Italian)
Currently translated at 13.0% (9 of 69 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-11 16:24:47 +02:00
Anonymous
8e0f265080 Translated using Weblate (Chinese (Simplified))
Currently translated at 86.9% (60 of 69 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-11 16:24:47 +02:00
Anonymous
ae357159ef Translated using Weblate (Russian)
Currently translated at 14.4% (10 of 69 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-11 16:24:47 +02:00
Anonymous
387d40910f Translated using Weblate (Portuguese)
Currently translated at 30.4% (21 of 69 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-11 16:24:47 +02:00
Anonymous
5344485a4f Translated using Weblate (French)
Currently translated at 26.0% (18 of 69 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-11 16:24:46 +02:00
Anonymous
21f2f2a215 Translated using Weblate (Spanish)
Currently translated at 92.7% (64 of 69 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-11 16:24:46 +02:00
Anonymous
9586fac665 Translated using Weblate (German)
Currently translated at 92.7% (64 of 69 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-11 16:24:46 +02:00
Ben Phelps
4aedda7ba2 add Overseerr widget 2022-09-11 17:24:33 +03:00
Ben Phelps
f79213c9d3 update language attributions 2022-09-11 17:24:12 +03:00
Anonymous
eeddcb26a0 Translated using Weblate (Dutch)
Currently translated at 92.4% (61 of 66 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-11 16:02:46 +02:00
Anonymous
725922db78 Translated using Weblate (Vietnamese)
Currently translated at 48.4% (32 of 66 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-11 16:02:46 +02:00
Anonymous
1846dcaba9 Translated using Weblate (Norwegian Bokmål)
Currently translated at 96.9% (64 of 66 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-11 16:02:45 +02:00
Anonymous
ab96d88ebe Translated using Weblate (Italian)
Currently translated at 13.6% (9 of 66 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-11 16:02:45 +02:00
Anonymous
a3bf28915d Translated using Weblate (Chinese (Simplified))
Currently translated at 90.9% (60 of 66 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-11 16:02:45 +02:00
Anonymous
47920a5f7a Translated using Weblate (Russian)
Currently translated at 15.1% (10 of 66 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-11 16:02:45 +02:00
Anonymous
1c10903823 Translated using Weblate (Portuguese)
Currently translated at 31.8% (21 of 66 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-11 16:02:45 +02:00
Anonymous
96e4133517 Translated using Weblate (French)
Currently translated at 27.2% (18 of 66 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-11 16:02:44 +02:00
Anonymous
8b5167a911 Translated using Weblate (Spanish)
Currently translated at 96.9% (64 of 66 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-11 16:02:44 +02:00
Anonymous
45edab5d88 Translated using Weblate (German)
Currently translated at 96.9% (64 of 66 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-11 16:02:44 +02:00
desolaris
b4375fb6fc Translated using Weblate (Russian)
Currently translated at 15.6% (10 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-11 16:02:39 +02:00
Ben Phelps
bd2b28a7ac redesigned media streaming widgets 2022-09-11 17:01:51 +03:00
Ben Phelps
53149df5f1 handle proxy methods other than GET 2022-09-11 14:30:28 +03:00
Ben Phelps
bc2025b3ba handle 204 and 304 proxy responses 2022-09-11 14:30:14 +03:00
Ben Phelps
236450f6f1 add error logging to services fetching 2022-09-11 14:28:29 +03:00
Ben Phelps
fb9e03b31d attempt to fix layout shift on resource widgets 2022-09-11 14:28:12 +03:00
Ben Phelps
31ccb9c933 fix no disk case 2022-09-11 14:21:16 +03:00
Ben Phelps
6e01a743df support array of disks, for disk resource widget 2022-09-11 14:13:58 +03:00
Ben Phelps
ed65c89516 blur backdrops for better background image support 2022-09-11 13:46:01 +03:00
Ben Phelps
b8b8dad9fb Update README.md 2022-09-11 11:35:00 +03:00
Ben Phelps
690d17e132 Merge branch 'main' of github.com:benphelps/homepage 2022-09-11 11:34:00 +03:00
Ben Phelps
a1e9912b36 update readme 2022-09-11 11:33:36 +03:00
deffcolony
26914bfb09 Translated using Weblate (Dutch)
Currently translated at 95.3% (61 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-11 10:23:22 +02:00
J. Lavoie
079fdb3011 Translated using Weblate (French)
Currently translated at 28.1% (18 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-11 10:23:22 +02:00
Ángel Fernández Sánchez
102cdbd53a Translated using Weblate (Spanish)
Currently translated at 100.0% (64 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-11 10:23:22 +02:00
Ben Phelps
d861264ecf fix error case cause failure to load anything 2022-09-11 11:13:54 +03:00
Francisco Coelho
9831df1427 Update proxy.js 2022-09-11 04:39:40 +01:00
Francisco Coelho
5e6312fe93 Add Gotify Service 2022-09-11 04:11:02 +01:00
Ben Phelps
e3237b9022 fix text alignment 2022-09-10 21:43:14 +03:00
Ben Phelps
3882dd4f5a fix cases where configurations are empty 2022-09-09 22:01:01 +03:00
Ben Phelps
d66326b41d implement docker service discovery via labels 2022-09-09 21:53:05 +03:00
Anonymous
ef1c5dbcc9 Translated using Weblate (Dutch)
Currently translated at 100.0% (0 of 0 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nl/
2022-09-09 14:59:59 +02:00
Allan Nordhøy
c45c8e93de Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (64 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-09 14:59:58 +02:00
Francisco Coelho
1e93bf3ec4 Translated using Weblate (Portuguese)
Currently translated at 32.8% (21 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-09 14:59:58 +02:00
Bernhard Großer
4bff209bd7 Translated using Weblate (German)
Currently translated at 100.0% (64 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-09 14:59:58 +02:00
Ben Phelps
e5ee937c38 Added translation using Weblate (Dutch) 2022-09-09 14:59:54 +02:00
Ben Phelps
c418efe007 fix fallback to / in disk resource widget 2022-09-09 15:27:42 +03:00
Ben Phelps
5677254b46 add new weather feature to readme 2022-09-09 13:07:20 +03:00
Ben Phelps
cb76a8165d pre-create settings.yaml for build process 2022-09-09 13:07:09 +03:00
Ben Phelps
a7a1eca0cd attempt to fix weird race condition in builds? 2022-09-09 12:59:43 +03:00
Ben Phelps
85bc078c46 always attempt location fetch
if it fails, then we just fallback to user interaction
2022-09-09 12:57:15 +03:00
Anonymous
5c347d9427 Translated using Weblate (Vietnamese)
Currently translated at 50.0% (32 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-09 11:44:50 +02:00
Anonymous
6c17efc2ab Translated using Weblate (Norwegian Bokmål)
Currently translated at 93.7% (60 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-09 11:44:50 +02:00
Anonymous
a6e929ba86 Translated using Weblate (Italian)
Currently translated at 14.0% (9 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-09 11:44:50 +02:00
Anonymous
f9886f7c63 Translated using Weblate (Chinese (Simplified))
Currently translated at 93.7% (60 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/zh_Hans/
2022-09-09 11:44:49 +02:00
Anonymous
ec937f6212 Translated using Weblate (Russian)
Currently translated at 14.0% (9 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-09 11:44:49 +02:00
Anonymous
b7427c3409 Translated using Weblate (Portuguese)
Currently translated at 14.0% (9 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-09 11:44:49 +02:00
Anonymous
5bd9cf46ea Translated using Weblate (French)
Currently translated at 14.0% (9 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-09 11:44:49 +02:00
Anonymous
c340c42ef3 Translated using Weblate (Spanish)
Currently translated at 93.7% (60 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-09 11:44:48 +02:00
Anonymous
27c5b4227d Translated using Weblate (German)
Currently translated at 93.7% (60 of 64 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/de/
2022-09-09 11:44:48 +02:00
Trung Le
914e869778 Translated using Weblate (Vietnamese)
Currently translated at 53.3% (32 of 60 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-09 11:44:42 +02:00
Ben Phelps
e4ea30becc implement weather geolocation 2022-09-09 12:44:34 +03:00
Ben Phelps
61f91f0e45 remove logging 2022-09-09 11:51:36 +03:00
Ben Phelps
c6d8668e69 fix jellyfin integration 2022-09-09 11:42:08 +03:00
Anonymous
3c73b000df Translated using Weblate (Vietnamese)
Currently translated at 100.0% (0 of 0 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/vi/
2022-09-09 08:11:36 +02:00
Trung Le
ed5a5ae86f Added translation using Weblate (Vietnamese) 2022-09-09 08:11:33 +02:00
Ben Phelps
036fbb0f49 fix build 2022-09-09 08:27:25 +03:00
Ben Phelps
13779c5618 update skeleton files 2022-09-09 07:10:45 +03:00
Ben Phelps
6802fd0c1d update readme 2022-09-09 07:10:39 +03:00
Ben Phelps
7b523501ad fix linting 2022-09-09 07:10:33 +03:00
Ben Phelps
0c8bbdf02b background images, document title 2022-09-09 06:45:43 +03:00
Ben Phelps
0b43f83daa cleanup bitrate/byterate i18n formatter 2022-09-08 20:17:58 +03:00
Ben Phelps
0f2f552e87 normalize resource widget styling 2022-09-08 20:17:39 +03:00
Ben Phelps
b3bedc7c31 update readme, contributors and formatting 2022-09-08 18:57:27 +03:00
Ben Phelps
32a2a3f484 Translated using Weblate (French)
Currently translated at 0.0% (0 of 60 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/fr/
2022-09-08 17:29:15 +02:00
Ángel Fernández Sánchez
27de7d1c84 Translated using Weblate (Spanish)
Currently translated at 100.0% (60 of 60 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/es/
2022-09-08 17:28:22 +02:00
Ben Phelps
c31c2a4c84 Translated using Weblate (Portuguese)
Currently translated at 0.0% (0 of 60 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/pt/
2022-09-08 13:41:33 +02:00
Ben Phelps
9fb88eb325 fix to BCP style language folder 2022-09-08 14:41:26 +03:00
Ben Phelps
7cdc2fa89a add Norwegian attribution to readme 2022-09-08 14:19:22 +03:00
Allan Nordhøy
c06dbddcea Translated using Weblate (Norwegian Bokmål)
Currently translated at 91.6% (55 of 60 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-08 13:13:17 +02:00
Ben Phelps
a4b17d9a8f remove readonly i18n keys from other languages 2022-09-08 14:00:53 +03:00
Anonymous
7ffea76b9e Translated using Weblate (Norwegian Bokmål)
Currently translated at 100.0% (0 of 0 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/nb_NO/
2022-09-08 12:55:38 +02:00
Allan Nordhøy
6a6db91dc9 Added translation using Weblate (Norwegian Bokmål) 2022-09-08 12:55:24 +02:00
Anonymous
9078fd2302 Translated using Weblate (Italian)
Currently translated at 15.0% (9 of 60 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/it/
2022-09-08 12:36:08 +02:00
Ben Phelps
39786c5dd4 Translated using Weblate (Russian)
Currently translated at 0.0% (0 of 60 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/ru/
2022-09-08 12:36:07 +02:00
Ben Phelps
7c35a88483 Merge branch 'main' of github.com:benphelps/homepage 2022-09-08 13:20:38 +03:00
Ben Phelps
1b885cb189 fix incorrect i18n keys 2022-09-08 13:19:49 +03:00
Ben Phelps
183bbbe6e7 Added translation using Weblate (Italian) 2022-09-08 12:13:31 +02:00
Ben Phelps
562318f2d3 Deleted translation using Weblate (Italian) 2022-09-08 12:13:09 +02:00
Ben Phelps
797401a7de Added translation using Weblate (Italian) 2022-09-08 12:08:29 +02:00
Ben Phelps
d4dbfebe72 fix english 2022-09-08 12:54:05 +03:00
Ben Phelps
575d233078 add translation info to readme 2022-09-08 12:52:28 +03:00
Ben Phelps
04a78c07a7 use ellipsis 2022-09-08 12:52:04 +03:00
Ben Phelps
59856bc753 Translated using Weblate (English)
Currently translated at 100.0% (60 of 60 strings)

Translation: Homepage/Homepage
Translate-URL: https://hosted.weblate.org/projects/homepage/homepage/en/
2022-09-08 11:48:12 +02:00
Ben Phelps
a8e7a5f912 add machine translated locales for
de, es, fr, pt, ru and zh-CN
2022-09-08 11:48:59 +03:00
Ben Phelps
c08d4b7b9c implement i18n 2022-09-08 11:48:16 +03:00
Ben Phelps
d25148c8ae revert to array key indexes, it’s the only option 2022-09-08 11:47:21 +03:00
Ben Phelps
b0e640fd03 remove unused component 2022-09-08 11:45:59 +03:00
Ben Phelps
7ae07cb1ee add Tautulli to list of services 2022-09-08 08:29:08 +03:00
Ben Phelps
c0b34faa79 Delete linter.yml 2022-09-07 17:47:19 +03:00
Ben Phelps
81e3b0bd1e cleanup resource widget design 2022-09-07 17:17:01 +03:00
Ben Phelps
f74e8b9d32 linting and cleanup 2022-09-07 16:53:24 +03:00
Ben Phelps
7f041e8303 Update linter.yml 2022-09-07 16:23:18 +03:00
Ben Phelps
db05a66f3a Create linter.yml 2022-09-07 16:18:52 +03:00
Ben Phelps
efc6e86991 add build attribution to readme 2022-09-07 12:29:02 +03:00
Ben Phelps
1af867d4b3 forcefully disable next-swc 2022-09-07 12:14:06 +03:00
Ben Phelps
43da60595c add @swc/core & cli packages
continued attempts to solve the SWC build step on arm platforms
2022-09-07 12:02:34 +03:00
Ben Phelps
c2849744b8 revert back to alpine 2022-09-07 12:01:53 +03:00
Ben Phelps
9bef2a8fcb trial run on non-alpine images
this is to test and see the size differences and if it’ll fix the SWC errors given by Next
2022-09-07 11:52:17 +03:00
Ben Phelps
6ec73362f2 fix docker, s/latest/current/ 2022-09-07 11:32:54 +03:00
Ben Phelps
f5bef651d8 bump node:alpine to latest 2022-09-07 11:31:31 +03:00
Ben Phelps
aa77a274c3 attempt to skip cache restore step 2022-09-07 11:22:12 +03:00
Ben Phelps
4e90bd8e46 remove apk cache as it seems to have issues 2022-09-07 11:10:56 +03:00
Ben Phelps
6a238948c2 Merge pull request #62 from modem7/dockerfile-optimise
Update Dockerfile
2022-09-07 11:09:56 +03:00
Alex
8e2bebcfd9 Updated EXPOSE to variable 2022-09-06 21:41:53 +01:00
Alex
b023801fe4 Update Dockerfile to include cache mounts + update healthcheck to new endpoint 2022-09-06 21:39:31 +01:00
modem7
516b812b2b Merge branch 'benphelps:main' into dockerfile-optimise 2022-09-06 21:25:19 +01:00
Ben Phelps
8373057758 add simple healthcheck endpoint 2022-09-06 09:13:48 +03:00
Ben Phelps
939f5d7c20 fix path.join import 2022-09-06 08:39:25 +03:00
Alex
36d1a9c738 Update healthcheck to work with PORT variable 2022-09-05 22:55:14 +01:00
Alex
fb845c3e03 Update Dockerfile and add healthcheck 2022-09-05 22:17:58 +01:00
Alex
78c52861c7 Update Dockerfile for --link 2022-09-05 19:44:58 +01:00
Ben Phelps
cf39395924 add documentation link 2022-09-05 20:20:34 +03:00
Ben Phelps
6061d9ec65 cleanup imports 2022-09-05 20:19:08 +03:00
Ben Phelps
5a8defb478 allow weather apis to use hidden api keys 2022-09-05 20:14:14 +03:00
Alex
a265038bf6 Update Dockerfile 2022-09-05 16:42:10 +01:00
223 changed files with 9674 additions and 3968 deletions

3
.babelrc Normal file
View File

@@ -0,0 +1,3 @@
{
"presets": ["next/babel"]
}

View File

@@ -1,3 +1,25 @@
{
"extends": "next/core-web-vitals"
"extends": ["airbnb", "next/core-web-vitals", "prettier"],
"plugins": ["prettier"],
"rules": {
"import/no-cycle": [
"error",
{
"maxDepth": 1
}
],
"import/order": [
"error",
{
"newlines-between": "always"
}
]
},
"settings": {
"import/resolver": {
"node": {
"paths": ["src"]
}
}
}
}

3
.github/FUNDING.yml vendored Normal file
View File

@@ -0,0 +1,3 @@
github: benphelps
ko_fi: benphelps
custom: ["https://paypal.me/phelpsben"]

30
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@@ -0,0 +1,30 @@
---
name: Bug report
about: Create a report to help us improve
title: "[Bug] "
labels: ''
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Configuration**
If applicable,
```yaml
# Please provide your service, widget or otherwise related configuration here
```
**Additional context**
Add any other context about the problem here. This includes things like:
- Service version or API version
- Docker version
- Deployment method
- Sample YAML configurations

View File

@@ -0,0 +1,17 @@
---
name: Feature request
about: Suggest an idea for this project
title: "[Feature Request] "
labels: ''
assignees: ''
---
**Is your feature request related to a service? Please describe.**
A clear and concise description of what you would like to see from this service.
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I would like it if [...]
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@@ -54,13 +54,15 @@ jobs:
- name: Setup Docker buildx
uses: docker/setup-buildx-action@v2
- name: Cache Docker layers
uses: actions/cache@v3
with:
path: /tmp/.buildx-cache
key: ${{ runner.os }}-buildx-${{ github.sha }}
restore-keys: |
${{ runner.os }}-buildx-
# This step is being disabled because the runner is on a self-hosted machine
# where the cache will stick between runs.
# - name: Cache Docker layers
# uses: actions/cache@v3
# with:
# path: /tmp/.buildx-cache
# key: ${{ runner.os }}-buildx-${{ github.sha }}
# restore-keys: |
# ${{ runner.os }}-buildx-
# Login against a Docker registry except on PR
# https://github.com/docker/login-action
@@ -92,9 +94,13 @@ jobs:
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
build-args: |
BUILDTIME=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.created'] }}
VERSION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.version'] }}
REVISION=${{ fromJSON(steps.meta.outputs.json).labels['org.opencontainers.image.revision'] }}
# https://github.com/docker/setup-qemu-action#about
# platforms: linux/amd64,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6
platforms: linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7
platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6
cache-from: type=local,src=/tmp/.buildx-cache
cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max

4
.gitignore vendored
View File

@@ -19,6 +19,10 @@
.DS_Store
*.pem
# log files
error.log
homepage.log
# debug
npm-debug.log*
yarn-debug.log*

19
.vscode/launch.json vendored Normal file
View File

@@ -0,0 +1,19 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "Next.js: debug full stack",
"type": "node",
"request": "launch",
"runtimeExecutable": "${workspaceFolder}/node_modules/.bin/next",
"serverReadyAction": {
"pattern": "started server on .+, url: (https?://.+)",
"uriFormat": "%s",
"action": "debugWithChrome"
}
}
]
}

128
CODE_OF_CONDUCT.md Normal file
View File

@@ -0,0 +1,128 @@
# Contributor Covenant Code of Conduct
## Our Pledge
We as members, contributors, and leaders pledge to make participation in our
community a harassment-free experience for everyone, regardless of age, body
size, visible or invisible disability, ethnicity, sex characteristics, gender
identity and expression, level of experience, education, socio-economic status,
nationality, personal appearance, race, religion, or sexual identity
and orientation.
We pledge to act and interact in ways that contribute to an open, welcoming,
diverse, inclusive, and healthy community.
## Our Standards
Examples of behavior that contributes to a positive environment for our
community include:
* Demonstrating empathy and kindness toward other people
* Being respectful of differing opinions, viewpoints, and experiences
* Giving and gracefully accepting constructive feedback
* Accepting responsibility and apologizing to those affected by our mistakes,
and learning from the experience
* Focusing on what is best not just for us as individuals, but for the
overall community
Examples of unacceptable behavior include:
* The use of sexualized language or imagery, and sexual attention or
advances of any kind
* Trolling, insulting or derogatory comments, and personal or political attacks
* Public or private harassment
* Publishing others' private information, such as a physical or email
address, without their explicit permission
* Other conduct which could reasonably be considered inappropriate in a
professional setting
## Enforcement Responsibilities
Community leaders are responsible for clarifying and enforcing our standards of
acceptable behavior and will take appropriate and fair corrective action in
response to any behavior that they deem inappropriate, threatening, offensive,
or harmful.
Community leaders have the right and responsibility to remove, edit, or reject
comments, commits, code, wiki edits, issues, and other contributions that are
not aligned to this Code of Conduct, and will communicate reasons for moderation
decisions when appropriate.
## Scope
This Code of Conduct applies within all community spaces, and also applies when
an individual is officially representing the community in public spaces.
Examples of representing our community include using an official e-mail address,
posting via an official social media account, or acting as an appointed
representative at an online or offline event.
## Enforcement
Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported to the community leaders responsible for enforcement at
ben@phelps.io.
All complaints will be reviewed and investigated promptly and fairly.
All community leaders are obligated to respect the privacy and security of the
reporter of any incident.
## Enforcement Guidelines
Community leaders will follow these Community Impact Guidelines in determining
the consequences for any action they deem in violation of this Code of Conduct:
### 1. Correction
**Community Impact**: Use of inappropriate language or other behavior deemed
unprofessional or unwelcome in the community.
**Consequence**: A private, written warning from community leaders, providing
clarity around the nature of the violation and an explanation of why the
behavior was inappropriate. A public apology may be requested.
### 2. Warning
**Community Impact**: A violation through a single incident or series
of actions.
**Consequence**: A warning with consequences for continued behavior. No
interaction with the people involved, including unsolicited interaction with
those enforcing the Code of Conduct, for a specified period of time. This
includes avoiding interactions in community spaces as well as external channels
like social media. Violating these terms may lead to a temporary or
permanent ban.
### 3. Temporary Ban
**Community Impact**: A serious violation of community standards, including
sustained inappropriate behavior.
**Consequence**: A temporary ban from any sort of interaction or public
communication with the community for a specified period of time. No public or
private interaction with the people involved, including unsolicited interaction
with those enforcing the Code of Conduct, is allowed during this period.
Violating these terms may lead to a permanent ban.
### 4. Permanent Ban
**Community Impact**: Demonstrating a pattern of violation of community
standards, including sustained inappropriate behavior, harassment of an
individual, or aggression toward or disparagement of classes of individuals.
**Consequence**: A permanent ban from any sort of public interaction within
the community.
## Attribution
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
version 2.0, available at
https://www.contributor-covenant.org/version/2/0/code_of_conduct.html.
Community Impact Guidelines were inspired by [Mozilla's code of conduct
enforcement ladder](https://github.com/mozilla/diversity).
[homepage]: https://www.contributor-covenant.org
For answers to common questions about this code of conduct, see the FAQ at
https://www.contributor-covenant.org/faq. Translations are available at
https://www.contributor-covenant.org/translations.

41
CONTRIBUTING.md Normal file
View File

@@ -0,0 +1,41 @@
# Contributing to Homepage
We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's:
- Reporting a bug
- Discussing the current state of the project
- Submitting a fix
- Proposing new features
- Becoming a maintainer
## We Develop with Github
We use github to host code, to track issues and feature requests, as well as accept pull requests.
## Any contributions you make will be under the GNU General Public License v3.0
In short, when you submit code changes, your submissions are understood to be under the same [GNU General Public License v3.0](https://choosealicense.com/licenses/gpl-3.0/) that covers the project. Feel free to contact the maintainers if that's a concern.
## Report bugs using Github's [issues](https://github.com/benphelps/homepage/issues)
We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/benphelps/homepage/issues/new); it's that easy!
## Write bug reports with detail, background, and sample configurations
Homepage includes a lot of configuration options and is often deploying in larger systems. Please include as much information (configurations, deployment method, Docker & API versions, etc) as you can when reporting an issue.
**Great Bug Reports** tend to have:
- A quick summary and/or background
- Steps to reproduce
- Be specific!
- Give example configurations if you can.
- What you expected would happen
- What actually happens
- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work)
People *love* thorough bug reports. I'm not even kidding.
## Use a Consistent Coding Style
This project follows the [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript), please follow it when submitting pull requests.
## License
By contributing, you agree that your contributions will be licensed under its GNU General Public License.
## References
This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/main/CONTRIBUTING.md)

View File

@@ -1,4 +1,43 @@
FROM node:16-alpine AS base
# syntax = docker/dockerfile:latest
# Install dependencies only when needed
FROM node:current-alpine AS deps
WORKDIR /app
COPY --link package.json pnpm-lock.yaml* ./
RUN <<EOF
set -xe
apk add libc6-compat
apk add --virtual .gyp python3 make g++
yarn global add pnpm
EOF
RUN --mount=type=cache,id=pnpm-store,target=/root/.local/share/pnpm/store pnpm fetch | grep -v "cross-device link not permitted\|Falling back to copying packages from store"
RUN --mount=type=cache,id=pnpm-store,target=/root/.local/share/pnpm/store pnpm install -r --offline
# Rebuild the source code only when needed
FROM node:current-alpine AS builder
WORKDIR /app
ARG BUILDTIME
ARG VERSION
ARG REVISION
COPY --link --from=deps /app/node_modules ./node_modules/
COPY . .
RUN <<EOF
set -xe
yarn next telemetry disable
mkdir config && echo '-' > config/settings.yaml
NEXT_PUBLIC_BUILDTIME=$BUILDTIME NEXT_PUBLIC_VERSION=$VERSION NEXT_PUBLIC_REVISION=$REVISION npm run build
EOF
# Production image, copy all the files and run next
FROM node:current-alpine AS runner
LABEL org.opencontainers.image.title "Homepage"
LABEL org.opencontainers.image.description "A self-hosted services landing page, with docker and service integrations."
LABEL org.opencontainers.image.url="https://github.com/benphelps/homepage"
@@ -6,33 +45,22 @@ LABEL org.opencontainers.image.documentation='https://github.com/benphelps/homep
LABEL org.opencontainers.image.source='https://github.com/benphelps/homepage'
LABEL org.opencontainers.image.licenses='Apache-2.0'
# Install dependencies only when needed
FROM node:16-alpine AS deps
RUN apk add --no-cache libc6-compat
RUN apk add --no-cache --virtual .gyp python3 make g++
WORKDIR /app
COPY package.json pnpm-lock.yaml* ./
RUN yarn global add pnpm
RUN pnpm install
RUN apk del .gyp
# Rebuild the source code only when needed
FROM node:16-alpine AS builder
WORKDIR /app
COPY --from=deps /app/node_modules ./node_modules
COPY . .
RUN npm run build
# Production image, copy all the files and run next
FROM node:16-alpine AS runner
WORKDIR /app
ENV NODE_ENV production
COPY --from=builder /app/next.config.js ./
COPY --from=builder /app/public ./public
COPY --from=builder /app/package.json ./package.json
COPY --from=builder /app/.next/standalone ./
COPY --from=builder /app/.next/static ./.next/static
EXPOSE 3000
WORKDIR /app
# Copy files from context (this allows the files to copy before the builder stage is done).
COPY --link package.json next.config.js ./
COPY --link /public ./public
# Copy files from builder
COPY --link --from=builder /app/.next/standalone ./
COPY --link --from=builder /app/.next/static/ ./.next/static/
ENV PORT 3000
EXPOSE $PORT
HEALTHCHECK --interval=10s --timeout=3s --start-period=20s \
CMD wget --no-verbose --tries=1 --spider --no-check-certificate http://localhost:$PORT/api/healthcheck || exit 1
CMD ["node", "server.js"]

117
README.md
View File

@@ -1,22 +1,55 @@
![Homepage Preview](/images/preview.png)
<p align="center">
<br>
<picture>
<source media="(prefers-color-scheme: dark)" srcset="images/homepage-dark.png">
<img src="images/homepage-light.png" width="65%">
</picture>
<br><br>
<img src="images/1.png" />
<br>
<img src="images/2.png" width="19%" />
<img src="images/3.png" width="19%" />
<img src="images/4.png" width="19%" />
<img src="images/5.png" width="19%" />
<img src="images/6.png" width="19%" />
</p>
[![Docker](https://github.com/benphelps/homepage/actions/workflows/docker-publish.yml/badge.svg)](https://github.com/benphelps/homepage/actions/workflows/docker-publish.yml)
<p align="center">
<a href="https://discord.gg/k4ruYNrudu"><img src="https://img.shields.io/badge/Discord - Chat-blue?logo=discord&logoColor=white" /></a>
<a href="https://paypal.me/phelpsben" title="Donate"><img src="https://img.shields.io/badge/PayPal - Donate-blue?logo=paypal&logoColor=white" alt="Linkedin - phelpsben"></a>
</p>
<p align="center">
<a href="https://github.com/benphelps/homepage/actions/workflows/docker-publish.yml"><img src="https://github.com/benphelps/homepage/actions/workflows/docker-publish.yml/badge.svg" alt="Docker"></a>
<a href="https://hosted.weblate.org/engage/homepage/"><img src="https://hosted.weblate.org/widgets/homepage/-/homepage/svg-badge.svg" alt="Weblate"></a>
</p>
## Features
* Web Bookmarks
* Service Bookmarks
- Docker Integration
- Status light + CPU, Memory & Network Reporting *(click on the status light)*
- Service Integration
- Currently supports Sonarr, Radarr, Ombi, Emby, Jellyfin, Jellyseerr ([by ilusi0n](https://github.com/benphelps/homepage/pull/34)), NZBGet, ruTorrent
- Portainer, Traefik, Speedtest Tracker, PiHole, Nginx Proxy Manager ([by aidenpwnz](https://github.com/benphelps/homepage/pull/45))
* Homepage Widgets
- System Stats (Disk, CPU, Memory)
- Weather via WeatherAPI.com or OpenWeatherMap ([by AlexFullmoon](https://github.com/benphelps/homepage/pull/25))
- Search Bar ([by aidenpwnz](https://github.com/benphelps/homepage/pull/45))
* Customizable
- 21 theme colors with light and dark mode support
- Fast! The entire site is statically generated at build time, so you can expect instant load times
- Images built for AMD64 (x86_64), ARM64, ARMv7 and ARMv6
- Supports all Raspberry Pi's, most SBCs & Apple Silicon
- Full i18n support with automatic language detection
- Translations for Chinese, Dutch, French, German, Hebrew, Hungarian, Norwegian Bokmål, Polish, Portuguese, Russian, Spanish and Swedish
- Want to help translate? [Join the Weblate project](https://hosted.weblate.org/engage/homepage/)
- Service & Web Bookmarks
- Docker Integration
- Container status (Running / Stopped) & statistics (CPU, Memory, Network)
- Automatic service discovery (via labels)
- Service Integration
- Sonarr, Radarr, Readarr, Prowlarr, Bazarr, Lidarr, Emby, Jellyfin, Tautulli (Plex)
- Ombi, Overseerr, Jellyseerr, Jackett, NZBGet, SABnzbd, ruTorrent, Transmission, qBittorrent
- Portainer, Traefik, Speedtest Tracker, PiHole, AdGuard Home, Nginx Proxy Manager, Gotify, Syncthing Relay Server
- Information Providers
- Coin Market Cap, Mastodon
- Information & Utility Widgets
- System Stats (Disk, CPU, Memory)
- Weather via WeatherAPI.com or OpenWeatherMap
- Automatic location detection (with HTTPS), or manual location selection
- Search Bar
- Customizable
- 21 theme colors with light and dark mode support
- Background image support
## Support & Suggestions
@@ -33,16 +66,16 @@ For configuration options, examples and more, [please check out the Wiki](https:
Using docker compose:
```yaml
version: '3.3'
version: "3.3"
services:
homepage:
image: ghcr.io/benphelps/homepage:latest
container_name: homepage
ports:
- 3000:3000
volumes:
- /path/to/config:/app/config
- /var/run/docker.sock:/var/run/docker.sock # (optional) For docker integrations
homepage:
image: ghcr.io/benphelps/homepage:latest
container_name: homepage
ports:
- 3000:3000
volumes:
- /path/to/config:/app/config # Make sure your local config directory exists
- /var/run/docker.sock:/var/run/docker.sock # (optional) For docker integrations
```
or docker run:
@@ -66,6 +99,8 @@ pnpm install
pnpm build
```
If this is your first time starting, copy the `src/skeleton` directory to `config/` to populate initial example config files.
Finally, run the server:
```bash
@@ -76,9 +111,11 @@ pnpm start
Configuration files will be genereted and placed on the first request.
Configuration is done in the /config directory using .yaml files. Refer to each config for
Configuration is done in the /config directory using .yaml files. Refer to each config for
the specific configuration options.
You may also check [the wiki](https://github.com/benphelps/homepage/wiki) for detailed configuration instructions, examples and more.
## Development
Install NPM packages, this project uses [pnpm](https://pnpm.io/) (and so should you!):
@@ -96,3 +133,33 @@ pnpm dev
Open [http://localhost:3000](http://localhost:3000) to start.
This is a [Next.js](https://nextjs.org/) application, see their doucmentation for more information:
## Contributors
Huge thanks to the all the contributors who have helped make this project what it is today! In alphabetical order:
- [aidenpwnz](https://github.com/benphelps/homepage/commits?author=aidenpwnz) - Nginx Proxy Manager, Search Bar Widget
- [AlexFullmoon](https://github.com/benphelps/homepage/commits?author=AlexFullmoon) - OpenWeatherMap Widget
- [AmadeusGraves](https://github.com/benphelps/homepage/commits?author=AmadeusGraves) - Spanish Translation
- [andrii-kryvoviaz](https://github.com/benphelps/homepage/commits?author=andrii-kryvoviaz) - Background opacity option
- [boerniee](https://github.com/benphelps/homepage/commits?author=boerniee) - German Translation
- [comradekingu](https://github.com/benphelps/homepage/commits?author=comradekingu) - Norwegian Bokmål Translation
- Daniel Varga - German & Hungarian Translation
- [deffcolony](https://github.com/benphelps/homepage/commits?author=deffcolony) - Dutch Translation
- [desolaris](https://github.com/benphelps/homepage/commits?author=desolaris) - Russian Translation
- [DevPGSV](https://github.com/benphelps/homepage/commits?author=DevPGSV) - Syncthing Relay Server & Mastodon widgets
- [ilusi0n](https://github.com/benphelps/homepage/commits?author=ilusi0n) - Jellyseerr Integration
- [ItsJustMeChris](https://github.com/benphelps/homepage/commits?author=ItsJustMeChris) - Coin Market Cap Widget
- [jackblk](https://github.com/benphelps/homepage/commits?author=jackblk) - Vietnamese Translation
- [JazzFisch](https://github.com/benphelps/homepage/commits?author=JazzFisch) - Readarr, Bazarr, Lidarr, SABnzbd, Transmission & qBittorrent Integrations
- [juanmanuelbc](https://github.com/benphelps/homepage/commits?author=juanmanuelbc) - Spanish and Catalan Translations
- [modem7](https://github.com/benphelps/homepage/commits?author=modem7) - Impvoed Docker Image
- [nicedc](https://github.com/benphelps/homepage/commits?author=nicedc) - Chinese Translation
- [Nonoss117](https://github.com/benphelps/homepage/commits?author=Nonoss117) - French Translation
- [pacoculebras](https://github.com/benphelps/homepage/commits?author=pacoculebras) - Catalan Translation
- [psychodracon](https://github.com/benphelps/homepage/commits?author=psychodracon) - Polish Translation
- [quod](https://github.com/benphelps/homepage/commits?author=quod) - Fixed Typos
- [schklom](https://github.com/benphelps/homepage/commits?author=schklom) - ARM64, ARMv7 and ARMv6
- [ShlomiPorush](https://github.com/benphelps/homepage/commits?author=ShlomiPorush) - Hebrew Translation
- [SuperDOS](https://github.com/benphelps/homepage/commits?author=SuperDOS) - Swedish Translation
- [xicopitz](https://github.com/benphelps/homepage/commits?author=xicopitz) - Gotify & Prowlarr Integration

9
docker-entrypoint.sh Executable file
View File

@@ -0,0 +1,9 @@
#!/bin/sh
set -e
# This is in attempt to preserve the original behavior of the Dockerfile,
# while also supporting the lscr.io /config directory
[ ! -d "/app/config" ] && ln -s /config /app/config
node server.js

BIN
images/1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 345 KiB

BIN
images/2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 237 KiB

BIN
images/3.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 279 KiB

BIN
images/4.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 129 KiB

BIN
images/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 423 KiB

BIN
images/6.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 533 KiB

BIN
images/homepage-dark.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
images/homepage-light.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 777 KiB

124
next-i18next.config.js Normal file
View File

@@ -0,0 +1,124 @@
// prettyBytes taken from https://github.com/sindresorhus/pretty-bytes
/* eslint-disable no-param-reassign */
const BYTE_UNITS = ["B", "kB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];
const BIBYTE_UNITS = ["B", "kiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB"];
const BIT_UNITS = ["b", "kbit", "Mbit", "Gbit", "Tbit", "Pbit", "Ebit", "Zbit", "Ybit"];
const BIBIT_UNITS = ["b", "kibit", "Mibit", "Gibit", "Tibit", "Pibit", "Eibit", "Zibit", "Yibit"];
/*
Formats the given number using `Number#toLocaleString`.
- If locale is a string, the value is expected to be a locale-key (for example: `de`).
- If locale is true, the system default locale is used for translation.
- If no value for locale is specified, the number is returned unmodified.
*/
const toLocaleString = (number, locale, options) => {
let result = number;
if (typeof locale === "string" || Array.isArray(locale)) {
result = number.toLocaleString(locale, options);
} else if (locale === true || options !== undefined) {
result = number.toLocaleString(undefined, options);
}
return result;
};
function prettyBytes(number, options) {
if (!Number.isFinite(number)) {
throw new TypeError(`Expected a finite number, got ${typeof number}: ${number}`);
}
options = {
bits: false,
binary: false,
...options,
};
// eslint-disable-next-line no-nested-ternary
const UNITS = options.bits ? (options.binary ? BIBIT_UNITS : BIT_UNITS) : options.binary ? BIBYTE_UNITS : BYTE_UNITS;
if (options.signed && number === 0) {
return ` 0 ${UNITS[0]}`;
}
const isNegative = number < 0;
// eslint-disable-next-line no-nested-ternary
const prefix = isNegative ? "-" : options.signed ? "+" : "";
if (isNegative) {
number = -number;
}
let localeOptions;
if (options.minimumFractionDigits !== undefined) {
localeOptions = { minimumFractionDigits: options.minimumFractionDigits };
}
if (options.maximumFractionDigits !== undefined) {
localeOptions = { maximumFractionDigits: options.maximumFractionDigits, ...localeOptions };
}
if (number < 1) {
const numberString = toLocaleString(number, options.locale, localeOptions);
return `${prefix + numberString} ${UNITS[0]}`;
}
const exponent = Math.min(
Math.floor(options.binary ? Math.log(number) / Math.log(1024) : Math.log10(number) / 3),
UNITS.length - 1
);
number /= (options.binary ? 1024 : 1000) ** exponent;
if (!localeOptions) {
number = number.toPrecision(3);
}
const numberString = toLocaleString(Number(number), options.locale, localeOptions);
const unit = UNITS[exponent];
return `${prefix + numberString} ${unit}`;
}
module.exports = {
i18n: {
defaultLocale: "en",
locales: ["en"],
},
serializeConfig: false,
use: [
{
init: (i18next) => {
i18next.services.formatter.add("bytes", (value, lng, options) =>
prettyBytes(parseFloat(value), { locale: lng, ...options })
);
i18next.services.formatter.add("rate", (value, lng, options) => {
if (value === 0) return "0 Bps";
const bits = options.bits ? value : value / 8;
const k = 1024;
const dm = options.decimals ? options.decimals : 0;
const sizes = ["Bps", "Kbps", "Mbps", "Gbps", "Tbps", "Pbps", "Ebps", "Zbps", "Ybps"];
const i = Math.floor(Math.log(bits) / Math.log(k));
const formatted = new Intl.NumberFormat(lng, { maximumFractionDigits: dm, minimumFractionDigits: dm }).format(
parseFloat(bits / k ** i)
);
return `${formatted} ${sizes[i]}`;
});
i18next.services.formatter.add("percent", (value, lng, options) =>
new Intl.NumberFormat(lng, { style: "percent", ...options }).format(parseFloat(value) / 100.0)
);
},
type: "3rdParty",
},
],
};

View File

@@ -1,12 +1,15 @@
const { i18n } = require("./next-i18next.config");
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
output: "standalone",
swcMinify: false,
experimental: { images: { allowFutureImage: true, unoptimized: true } },
images: {
domains: ["cdn.jsdelivr.net"],
unoptimized: true,
},
i18n,
};
module.exports = nextConfig;

View File

@@ -6,30 +6,50 @@
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
"lint": "next lint",
"telemetry": "next telemetry disable"
},
"dependencies": {
"@headlessui/react": "^1.6.6",
"@tailwindcss/forms": "^0.5.3",
"@headlessui/react": "^1.7.2",
"classnames": "^2.3.2",
"compare-versions": "^5.0.1",
"dockerode": "^3.3.4",
"follow-redirects": "^1.15.2",
"i18next": "^21.9.2",
"js-yaml": "^4.1.0",
"json-rpc-2.0": "^1.4.1",
"memory-cache": "^0.2.0",
"next": "12.2.5",
"next": "^12.3.1",
"next-i18next": "^12.0.1",
"node-os-utils": "^1.3.7",
"pretty-bytes": "^6.0.0",
"raw-body": "^2.5.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-i18next": "^11.18.6",
"react-icons": "^4.4.0",
"rutorrent-promise": "^2.0.0",
"swr": "^1.3.0"
"shvl": "^3.0.0",
"swr": "^1.3.0",
"tough-cookie": "^4.1.2",
"winston": "^3.8.2"
},
"devDependencies": {
"autoprefixer": "^10.4.8",
"eslint": "8.22.0",
"eslint-config-next": "12.2.5",
"@tailwindcss/forms": "^0.5.3",
"autoprefixer": "^10.4.12",
"eslint": "^8.24.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-config-next": "^12.3.1",
"eslint-config-prettier": "^8.5.0",
"eslint-plugin-import": "^2.26.0",
"eslint-plugin-jsx-a11y": "^6.6.1",
"eslint-plugin-prettier": "^4.2.1",
"eslint-plugin-react": "^7.31.8",
"eslint-plugin-react-hooks": "^4.6.0",
"postcss": "^8.4.16",
"prettier": "^2.7.1",
"tailwind-scrollbar": "^2.0.1",
"tailwindcss": "^3.1.8",
"typescript": "^4.8.2"
"typescript": "^4.8.3"
}
}

973
pnpm-lock.yaml generated

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,177 @@
{
"widget": {
"missing_type": "Falta el tipus de widget: {{type}}",
"api_error": "Error d'API",
"status": "Estat"
},
"weather": {
"allow": "Feu clic per permetre",
"updating": "Actualitzant",
"wait": "Si us plau, espereu",
"current": "Localització actual"
},
"search": {
"placeholder": "Cercar…"
},
"transmission": {
"seed": "Llavors",
"download": "Descàrrega",
"upload": "Càrrega",
"leech": "Companys"
},
"sonarr": {
"wanted": "Volgut",
"queued": "En cua",
"series": "Sèries"
},
"speedtest": {
"ping": "Ping",
"upload": "Càrrega",
"download": "Descàrrega"
},
"resources": {
"total": "Total",
"free": "Lliure",
"used": "Usat",
"load": "Càrrega"
},
"docker": {
"rx": "RX",
"tx": "TX",
"mem": "MEM",
"cpu": "CPU",
"offline": "Fora de línia"
},
"emby": {
"playing": "Reproduint",
"transcoding": "Transcodificant",
"bitrate": "Taxa de bits",
"no_active": "Sense transmissions actives"
},
"tautulli": {
"playing": "Reproduint",
"transcoding": "Transcodificant",
"bitrate": "Taxa de bits",
"no_active": "Sense transmissions actives"
},
"nzbget": {
"rate": "Taxa",
"remaining": "Restant",
"downloaded": "Descarregat"
},
"sabnzbd": {
"rate": "Taxa",
"queue": "Cua",
"timeleft": "Temps restant"
},
"rutorrent": {
"active": "Actiu",
"upload": "Càrrega",
"download": "Descàrrega"
},
"radarr": {
"wanted": "Volgut",
"queued": "En cua",
"movies": "Pel·lícules"
},
"readarr": {
"wanted": "Volgut",
"queued": "En cua",
"books": "Llibres"
},
"ombi": {
"pending": "Pendent",
"approved": "Aprovat",
"available": "Disponible"
},
"jellyseerr": {
"pending": "Pendent",
"approved": "Aprovat",
"available": "Disponible"
},
"overseerr": {
"pending": "Pendent",
"approved": "Aprovat",
"available": "Disponible"
},
"pihole": {
"queries": "Consultes",
"blocked": "Bloquejat",
"gravity": "Gravity"
},
"portainer": {
"running": "Executant",
"stopped": "Aturat",
"total": "Total"
},
"traefik": {
"routers": "Encaminadors",
"services": "Serveis",
"middleware": "Middleware"
},
"npm": {
"total": "Total",
"enabled": "Activat",
"disabled": "Desactivat"
},
"coinmarketcap": {
"configure": "Configura una o més criptomonedes per fer el seguiment",
"1hour": "1 Hora",
"1day": "1 Dia",
"7days": "7 Dies",
"30days": "30 Dies"
},
"gotify": {
"apps": "Aplicacions",
"clients": "Clients",
"messages": "Missatges"
},
"prowlarr": {
"enableIndexers": "Indexadors",
"numberOfGrabs": "Captures",
"numberOfQueries": "Consultes",
"numberOfFailGrabs": "Captures fallides",
"numberOfFailQueries": "Consultes fallides"
},
"jackett": {
"configured": "Configurat",
"errored": "Amb errors"
},
"bazarr": {
"missingEpisodes": "Episodis que falten",
"missingMovies": "Pel·lícules que falten"
},
"lidarr": {
"wanted": "Volgut",
"queued": "En cua",
"albums": "Àlbums"
},
"adguard": {
"queries": "Consultes",
"blocked": "Bloquejat",
"filtered": "Filtrat",
"latency": "Latència"
},
"qbittorrent": {
"download": "Descàrrega",
"upload": "Càrrega",
"leech": "Companys",
"seed": "Llavors"
},
"mastodon": {
"user_count": "Usuaris",
"status_count": "Publicacions",
"domain_count": "Dominis"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
"numConnections": "Connexions",
"dataRelayed": "Transmès",
"transferRate": "Velocitat"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"widget": {
"missing_type": "Fehlender Widget-Typ: {{type}}",
"api_error": "API-Fehler",
"status": "Status"
},
"search": {
"placeholder": "Suche…"
},
"resources": {
"total": "Gesamt",
"free": "Frei",
"used": "Gebraucht",
"load": "Belastung"
},
"docker": {
"rx": "Rx",
"tx": "Tx",
"mem": "Mem",
"cpu": "Prozessor",
"offline": "Offline"
},
"emby": {
"playing": "Spielen",
"transcoding": "Transcodierung",
"bitrate": "Bitrate",
"no_active": "Keine aktive Streams"
},
"tautulli": {
"playing": "Spielen",
"transcoding": "Transcodierung",
"bitrate": "Bitrate",
"no_active": "Keine aktiven streamen"
},
"rutorrent": {
"active": "Aktiv",
"upload": "Hochladen",
"download": "Download"
},
"sonarr": {
"wanted": "Gesucht",
"queued": "In Warteschlange",
"series": "Serie"
},
"radarr": {
"wanted": "Gesucht",
"queued": "In Warteschlange",
"movies": "Filme"
},
"readarr": {
"wanted": "Gesucht",
"queued": "In Warteschlange",
"books": "Bücher"
},
"ombi": {
"pending": "Ausstehend",
"approved": "Genehmigt",
"available": "Verfügbar"
},
"jellyseerr": {
"pending": "Ausstehend",
"approved": "Genehmigt",
"available": "Verfügbar"
},
"pihole": {
"queries": "Abfragen",
"blocked": "Blockiert",
"gravity": "Gravity"
},
"speedtest": {
"upload": "Upload",
"download": "Download",
"ping": "Ping"
},
"portainer": {
"running": "Betrieb",
"stopped": "Gestoppt",
"total": "Gesamt"
},
"traefik": {
"routers": "Router",
"services": "Dienste",
"middleware": "Zwischenanwendung"
},
"npm": {
"enabled": "Aktiviert",
"disabled": "Deaktiviert",
"total": "Gesamt"
},
"weather": {
"current": "Aktueller Standort",
"allow": "Zum Zulassen anklicken",
"updating": "Aktualisieren",
"wait": "Bitte warten"
},
"overseerr": {
"pending": "Ausstehend",
"approved": "Genehmigt",
"available": "Verfügbar"
},
"sabnzbd": {
"rate": "Geschwindigkeit",
"queue": "Warteschlange",
"timeleft": "Verbleibende Zeit"
},
"nzbget": {
"rate": "Geschwindigkeit",
"remaining": "Verbleibend",
"downloaded": "Heruntergeladen"
},
"coinmarketcap": {
"configure": "Konfiguriere eine oder mehrere Kryptowährungen zur Verfolgung",
"1hour": "1 Stunde",
"1day": "1 Tag",
"7days": "7 Tage",
"30days": "30 Tage"
},
"gotify": {
"apps": "Programme",
"clients": "Benutzer",
"messages": "Nachrichten"
},
"prowlarr": {
"enableIndexers": "Indexer",
"numberOfGrabs": "Abrufungen",
"numberOfQueries": "Anfragen",
"numberOfFailGrabs": "Fehlgeschlagene Abrufungen",
"numberOfFailQueries": "Fehlgeschlagene Anfragen"
},
"transmission": {
"download": "Herunterladen",
"upload": "Hochladen",
"leech": "Leech",
"seed": "Seed"
},
"jackett": {
"configured": "Konfiguriert",
"errored": "Fehlerhaft"
},
"bazarr": {
"missingEpisodes": "Fehlende Episoden",
"missingMovies": "Fehlende Filme"
},
"lidarr": {
"wanted": "Gesucht",
"queued": "In Warteschlange",
"albums": "Alben"
},
"adguard": {
"queries": "Anfragen",
"blocked": "Blockiert",
"filtered": "Gefiltert",
"latency": "Latenz"
},
"qbittorrent": {
"download": "Herunterladen",
"upload": "Hochladen",
"leech": "Leech",
"seed": "Seed"
},
"mastodon": {
"user_count": "Nutzer",
"status_count": "Beiträge",
"domain_count": "Domänen"
},
"strelaysrv": {
"numActiveSessions": "Sitzungen",
"numConnections": "Verbindungen",
"dataRelayed": "Weitergeleitet",
"transferRate": "Bewerten"
},
"authentik": {
"users": "Benutzer",
"loginsLast24H": "Anmeldungen (24h)",
"failedLoginsLast24H": "fehlerhafte Anmeldungen (24h)"
}
}

View File

@@ -0,0 +1,188 @@
{
"common": {
"bytes": "{{value, bytes}}",
"bits": "{{value, bytes(bits: true)}}",
"bbytes": "{{value, bytes(binary: true)}}",
"bbits": "{{value, bytes(bits: true, binary: true)}}",
"byterate": "{{value, rate}}",
"bitrate": "{{value, rate(bits: true)}}",
"percent": "{{value, percent}}",
"number": "{{value, number}}",
"ms": "{{value, number}}"
},
"widget": {
"missing_type": "Missing Widget Type: {{type}}",
"api_error": "API Error",
"status": "Status"
},
"weather": {
"current": "Current Location",
"allow": "Click to allow",
"updating": "Updating",
"wait": "Please wait"
},
"search": {
"placeholder": "Search…"
},
"resources": {
"total": "Total",
"free": "Free",
"used": "Used",
"load": "Load"
},
"docker": {
"rx": "RX",
"tx": "TX",
"mem": "MEM",
"cpu": "CPU",
"offline": "Offline"
},
"emby": {
"playing": "Playing",
"transcoding": "Transcoding",
"bitrate": "Bitrate",
"no_active": "No Active Streams"
},
"tautulli": {
"playing": "Playing",
"transcoding": "Transcoding",
"bitrate": "Bitrate",
"no_active": "No Active Streams"
},
"nzbget": {
"rate": "Rate",
"remaining": "Remaining",
"downloaded": "Downloaded"
},
"sabnzbd": {
"rate": "Rate",
"queue": "Queue",
"timeleft": "Time Left"
},
"rutorrent": {
"active": "Active",
"upload": "Upload",
"download": "Download"
},
"transmission": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"qbittorrent": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"sonarr": {
"wanted": "Wanted",
"queued": "Queued",
"series": "Series"
},
"radarr": {
"wanted": "Wanted",
"queued": "Queued",
"movies": "Movies"
},
"lidarr": {
"wanted": "Wanted",
"queued": "Queued",
"albums": "Albums"
},
"readarr": {
"wanted": "Wanted",
"queued": "Queued",
"books": "Books"
},
"bazarr": {
"missingEpisodes": "Missing Episodes",
"missingMovies": "Missing Movies"
},
"ombi": {
"pending": "Pending",
"approved": "Approved",
"available": "Available"
},
"jellyseerr": {
"pending": "Pending",
"approved": "Approved",
"available": "Available"
},
"overseerr": {
"pending": "Pending",
"approved": "Approved",
"available": "Available"
},
"pihole": {
"queries": "Queries",
"blocked": "Blocked",
"gravity": "Gravity"
},
"adguard": {
"queries": "Queries",
"blocked": "Blocked",
"filtered": "Filtered",
"latency": "Latency"
},
"speedtest": {
"upload": "Upload",
"download": "Download",
"ping": "Ping"
},
"portainer": {
"running": "Running",
"stopped": "Stopped",
"total": "Total"
},
"traefik": {
"routers": "Routers",
"services": "Services",
"middleware": "Middleware"
},
"npm": {
"enabled": "Enabled",
"disabled": "Disabled",
"total": "Total"
},
"coinmarketcap": {
"configure": "Configure one or more crypto currencies to track",
"1hour": "1 Hour",
"1day": "1 Day",
"7days": "7 Days",
"30days": "30 Days"
},
"gotify": {
"apps": "Applications",
"clients": "Clients",
"messages": "Messages"
},
"prowlarr":{
"enableIndexers": "Indexers",
"numberOfGrabs": "Grabs",
"numberOfQueries": "Queries",
"numberOfFailGrabs": "Fail Grabs",
"numberOfFailQueries": "Fail Queries"
},
"jackett": {
"configured": "Configured",
"errored": "Errored"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
"numConnections": "Connections",
"dataRelayed": "Relayed",
"transferRate": "Rate"
},
"mastodon": {
"user_count": "Users",
"status_count": "Posts",
"domain_count": "Domains"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"widget": {
"missing_type": "Falta el tipo de widget: {{type}}",
"api_error": "Error de API",
"status": "Estado"
},
"search": {
"placeholder": "Buscar…"
},
"resources": {
"total": "Total",
"free": "Libre",
"used": "Usado",
"load": "Carga"
},
"docker": {
"rx": "RX",
"tx": "TX",
"mem": "MEM",
"cpu": "CPU",
"offline": "Desconectado"
},
"emby": {
"playing": "Reproduciendo",
"transcoding": "Transcodificando",
"bitrate": "Tasa de bits",
"no_active": "Sin transmisiones activas"
},
"tautulli": {
"playing": "Reproduciendo",
"transcoding": "Transcodificando",
"bitrate": "Tasa de bits",
"no_active": "Sin transmisiones activas"
},
"rutorrent": {
"active": "Activo",
"upload": "Subida",
"download": "Bajada"
},
"sonarr": {
"wanted": "Buscando",
"queued": "En cola",
"series": "Series"
},
"radarr": {
"wanted": "Buscando",
"queued": "En cola",
"movies": "Películas"
},
"readarr": {
"wanted": "Buscando",
"queued": "En cola",
"books": "Libros"
},
"ombi": {
"pending": "Pendiente",
"approved": "Aprobado",
"available": "Disponible"
},
"jellyseerr": {
"pending": "Pendiente",
"approved": "Aprobado",
"available": "Disponible"
},
"pihole": {
"queries": "Consultas",
"blocked": "Bloqueado",
"gravity": "Gravedad"
},
"speedtest": {
"upload": "Subida",
"download": "Bajada",
"ping": "Ping"
},
"portainer": {
"running": "En ejecución",
"stopped": "Detenido",
"total": "Total"
},
"traefik": {
"routers": "Enrutadores",
"services": "Servicios",
"middleware": "Middleware"
},
"npm": {
"enabled": "Activado",
"disabled": "Desactivado",
"total": "Total"
},
"weather": {
"current": "Ubicación actual",
"allow": "Clic para permitir",
"updating": "Actualizando",
"wait": "Espere, por favor"
},
"overseerr": {
"pending": "Pendiente",
"approved": "Aprobado",
"available": "Disponible"
},
"sabnzbd": {
"rate": "Tasa",
"queue": "En cola",
"timeleft": "Tiempo restante"
},
"nzbget": {
"rate": "Tasa",
"remaining": "Restante",
"downloaded": "Descargado"
},
"coinmarketcap": {
"configure": "Configurar una o más criptomonedas para rastrear",
"1hour": "1 Hora",
"1day": "1 Día",
"7days": "7 Días",
"30days": "30 Días"
},
"gotify": {
"apps": "Aplicaciones",
"clients": "Clientes",
"messages": "Mensajes"
},
"prowlarr": {
"enableIndexers": "Indexadores",
"numberOfGrabs": "Capturas",
"numberOfQueries": "Consultas",
"numberOfFailGrabs": "Capturas fallidas",
"numberOfFailQueries": "Consultas fallidas"
},
"transmission": {
"download": "Bajada",
"upload": "Subida",
"leech": "Compañeros",
"seed": "Semillas"
},
"jackett": {
"configured": "Configurado",
"errored": "Con errores"
},
"bazarr": {
"missingEpisodes": "Episodios perdidos",
"missingMovies": "Películas perdidas"
},
"lidarr": {
"queued": "En cola",
"wanted": "Buscando",
"albums": "Álbumes"
},
"adguard": {
"queries": "Consultas",
"blocked": "Bloqueado",
"filtered": "Filtrado",
"latency": "Latencia"
},
"qbittorrent": {
"download": "Bajada",
"upload": "Subida",
"leech": "Compañeros",
"seed": "Semillas"
},
"mastodon": {
"user_count": "Usuarios",
"status_count": "Publicaciones",
"domain_count": "Dominios"
},
"strelaysrv": {
"numActiveSessions": "Sesiones",
"numConnections": "Conexiones",
"dataRelayed": "Retransmitido",
"transferRate": "Velocidad"
},
"authentik": {
"users": "Usuarios",
"loginsLast24H": "Accesos (24h)",
"failedLoginsLast24H": "Accesos Fallidos (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"widget": {
"missing_type": "Type de widget manquant: {{type}}",
"api_error": "Erreur de l'API",
"status": "Statut"
},
"search": {
"placeholder": "Recherche…"
},
"resources": {
"total": "Total",
"free": "Libre",
"used": "Utilisé",
"load": "Charge"
},
"docker": {
"rx": "Rx",
"tx": "Tx",
"mem": "Mém",
"cpu": "Cpu",
"offline": "Hors ligne"
},
"emby": {
"playing": "En lecture",
"transcoding": "Transcodage",
"bitrate": "Débit",
"no_active": "Aucun flux actif"
},
"tautulli": {
"playing": "En lecture",
"transcoding": "Transcodage",
"bitrate": "Débit",
"no_active": "Aucun flux actif"
},
"rutorrent": {
"active": "Actif",
"upload": "Envoi",
"download": "Réception"
},
"sonarr": {
"wanted": "Demande",
"queued": "En attente",
"series": "Séries"
},
"radarr": {
"wanted": "Demande",
"queued": "En attente",
"movies": "Films"
},
"readarr": {
"wanted": "Demande",
"queued": "Attente",
"books": "Livres"
},
"ombi": {
"pending": "En attente",
"approved": "Validé",
"available": "Disponible"
},
"jellyseerr": {
"pending": "En attente",
"approved": "Validé",
"available": "Disponible"
},
"pihole": {
"queries": "Requêtes",
"blocked": "Bloqué",
"gravity": "Listes dom. bloqués"
},
"speedtest": {
"upload": "Envoi",
"download": "Récep.",
"ping": "Ping"
},
"portainer": {
"running": "Démarré",
"stopped": "Arrêté",
"total": "Total"
},
"traefik": {
"routers": "Routeurs",
"services": "Services",
"middleware": "Middleware"
},
"npm": {
"enabled": "Activé",
"disabled": "Désactivé",
"total": "Total"
},
"weather": {
"current": "Localisation actuelle",
"allow": "Cliquez pour autoriser",
"updating": "Mise à jour",
"wait": "Veuillez patienter"
},
"overseerr": {
"pending": "En attente",
"approved": "Demande",
"available": "Disponible"
},
"sabnzbd": {
"rate": "Débit",
"queue": "Queue",
"timeleft": "Temps restant"
},
"nzbget": {
"remaining": "Restant",
"downloaded": "Téléchargé",
"rate": "Débit"
},
"coinmarketcap": {
"configure": "Configurer une ou plusieurs crypto-monnaies à suivre",
"1hour": "1 Heure",
"1day": "1 Jour",
"7days": "7 Jours",
"30days": "30 Jours"
},
"gotify": {
"apps": "Applis",
"clients": "Clients",
"messages": "Msg"
},
"prowlarr": {
"enableIndexers": "Indexeur",
"numberOfGrabs": "Capture",
"numberOfQueries": "Demande",
"numberOfFailGrabs": "Capt. échouée",
"numberOfFailQueries": "Dem. échouée"
},
"transmission": {
"download": "Réception",
"upload": "Envoi",
"leech": "Leech",
"seed": "Seed"
},
"jackett": {
"configured": "Configuré",
"errored": "En erreur"
},
"bazarr": {
"missingEpisodes": "Épisodes manquants",
"missingMovies": "Films manquants"
},
"lidarr": {
"wanted": "Demandé",
"queued": "En queue",
"albums": "Albums"
},
"adguard": {
"queries": "Requêtes",
"blocked": "Bloquées",
"filtered": "Filtrées",
"latency": "Latence"
},
"qbittorrent": {
"download": "Récep.",
"upload": "Envoi",
"leech": "Leech",
"seed": "Seed"
},
"mastodon": {
"user_count": "Utilisateurs",
"status_count": "Messages",
"domain_count": "Domaines"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
"numConnections": "Cnx",
"dataRelayed": "Relayé",
"transferRate": "Débit"
},
"authentik": {
"users": "Utilisateurs",
"loginsLast24H": "Cnx. (24h)",
"failedLoginsLast24H": "Cnx. échouées (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"widget": {
"missing_type": "סוג ווידג'ט חסר: {{type}}",
"api_error": "שגיאת API",
"status": "סטטוס"
},
"weather": {
"current": "מיקום נוכחי",
"allow": "יש ללחוץ כדי לאשר",
"updating": "מעדכן",
"wait": "המתן בבקשה"
},
"search": {
"placeholder": "חיפוש…"
},
"resources": {
"total": "סה\"כ",
"free": "פנוי",
"used": "בשימוש",
"load": "עומס"
},
"docker": {
"rx": "RX",
"tx": "TX",
"mem": "זיכרון",
"cpu": "מעבד",
"offline": "כבוי"
},
"emby": {
"playing": "מנגן",
"transcoding": "מקודד",
"bitrate": "סיביות",
"no_active": "אין הזרמות פעילות"
},
"tautulli": {
"playing": "מנגן",
"transcoding": "מקודד",
"bitrate": "סיביות",
"no_active": "אין הזרמות פעילות"
},
"nzbget": {
"rate": "יחס",
"remaining": "נותר",
"downloaded": "הורד"
},
"sabnzbd": {
"rate": "יחס",
"queue": "תור",
"timeleft": "זמן שנותר"
},
"rutorrent": {
"active": "פעיל",
"upload": "העלאה",
"download": "הורדה"
},
"transmission": {
"download": "הורדה",
"upload": "העלאה",
"leech": "בהורדה",
"seed": "בשיתוף"
},
"qbittorrent": {
"download": "הורדה",
"upload": "העלאה",
"leech": "בהורדה",
"seed": "בשיתוף"
},
"sonarr": {
"wanted": "מבוקש",
"queued": "בתור",
"series": "סדרות"
},
"radarr": {
"wanted": "מבוקש",
"queued": "בתור",
"movies": "סרטים"
},
"lidarr": {
"wanted": "מבוקש",
"queued": "בתור",
"albums": "אלבומים"
},
"readarr": {
"wanted": "מבוקש",
"queued": "בתור",
"books": "ספרים"
},
"bazarr": {
"missingEpisodes": "פרקים חסרים",
"missingMovies": "סרטים חסרים"
},
"ombi": {
"pending": "ממתין",
"approved": "מאושר",
"available": "זמין"
},
"jellyseerr": {
"pending": "ממתין",
"approved": "מאושר",
"available": "זמין"
},
"overseerr": {
"pending": "ממתין",
"approved": "מאושר",
"available": "זמין"
},
"pihole": {
"queries": "שאילתות",
"blocked": "נחסם",
"gravity": "Gravity"
},
"adguard": {
"queries": "שאילתות",
"blocked": "נחסם",
"filtered": "מסונן",
"latency": "השהיה"
},
"speedtest": {
"upload": "העלאה",
"download": "הורדה",
"ping": "פינג"
},
"portainer": {
"running": "פעיל",
"stopped": "נעצר",
"total": "סה\"כ"
},
"traefik": {
"routers": "ניתובים",
"services": "שירותים",
"middleware": "מתווך"
},
"npm": {
"enabled": "מופעל",
"disabled": "מבוטל",
"total": "סה\"כ"
},
"coinmarketcap": {
"configure": "קבע את התצורה של מטבע קריפטו אחד או יותר למעקב",
"1hour": "שעה אחת",
"1day": "יום 1",
"7days": "7 יום",
"30days": "30 יום"
},
"gotify": {
"apps": "אפליקציות",
"clients": "לקוחות",
"messages": "הודעות"
},
"prowlarr": {
"enableIndexers": "אינדקסים",
"numberOfGrabs": "Grabs",
"numberOfQueries": "שאילתות",
"numberOfFailGrabs": "Fail Grabs",
"numberOfFailQueries": "Fail Queries"
},
"jackett": {
"configured": "מוגדר",
"errored": "שגיאה"
},
"mastodon": {
"user_count": "Users",
"status_count": "Posts",
"domain_count": "Domains"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
"numConnections": "Connections",
"dataRelayed": "Relayed",
"transferRate": "Rate"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"weather": {
"current": "Tranutačna lokacija",
"allow": "Pritisni za dozvoljavanje",
"updating": "Aktualiziranje",
"wait": "Pričekaj"
},
"search": {
"placeholder": "Traži …"
},
"resources": {
"total": "Ukupno",
"free": "Slobodno",
"used": "Korišteno",
"load": "Opterećenje"
},
"sabnzbd": {
"rate": "Stopa",
"queue": "Red",
"timeleft": "Preostalo vrijeme"
},
"overseerr": {
"available": "Dostupno",
"pending": "Predstoji",
"approved": "Odobreno"
},
"pihole": {
"queries": "Upiti",
"blocked": "Blokirano",
"gravity": "Ozbiljnost"
},
"adguard": {
"latency": "Kašnjenje",
"queries": "Upiti",
"blocked": "Blokirano",
"filtered": "Filtrirano"
},
"npm": {
"total": "Ukupno",
"enabled": "Aktivirano",
"disabled": "Deaktivirano"
},
"coinmarketcap": {
"configure": "Konfiguriraj jednu ili više kripto valuta za praćenje",
"1hour": "1 sat",
"1day": "1 dan",
"7days": "7 dana",
"30days": "30 dana"
},
"prowlarr": {
"enableIndexers": "Indeksatori",
"numberOfGrabs": "Dohvaćanja",
"numberOfQueries": "Upiti",
"numberOfFailGrabs": "Neuspjela dohvaćanja",
"numberOfFailQueries": "Neuspjeli upiti"
},
"widget": {
"missing_type": "Nedostajuća vrsta widgeta: {{type}}",
"api_error": "API greška",
"status": "Stanje"
},
"docker": {
"rx": "RX",
"tx": "TX",
"mem": "MEM",
"cpu": "CPU",
"offline": "Odspojen"
},
"emby": {
"playing": "Reprodukcija",
"transcoding": "Prekodiranje",
"bitrate": "Brzina prijenosa",
"no_active": "Nema aktivnih prijenosa"
},
"tautulli": {
"playing": "Reprodukcija",
"transcoding": "Prekodiranje",
"bitrate": "Brzina prijenosa",
"no_active": "Nema aktivnih prijenosa"
},
"nzbget": {
"rate": "Stopa",
"remaining": "Preostalo",
"downloaded": "Preuzeto"
},
"rutorrent": {
"upload": "Prijenos",
"download": "Preuzimanje",
"active": "Aktivno"
},
"transmission": {
"download": "Preuzimanje",
"upload": "Prijenos",
"leech": "Krvopija",
"seed": "Prijenos preuzetog sadržaja"
},
"sonarr": {
"wanted": "Željeno",
"queued": "U redu čekanja",
"series": "Serije"
},
"radarr": {
"wanted": "Željeno",
"queued": "U redu čekanja",
"movies": "Filmovi"
},
"lidarr": {
"wanted": "Željeno",
"queued": "U redu čekanja",
"albums": "Albumi"
},
"readarr": {
"wanted": "Željeno",
"queued": "U redu čekanja",
"books": "Knjige"
},
"bazarr": {
"missingEpisodes": "Nedostajuće epizode",
"missingMovies": "Nedostajući filmovi"
},
"ombi": {
"pending": "Predstoji",
"approved": "Odobreno",
"available": "Dostupno"
},
"jellyseerr": {
"pending": "Predstoji",
"approved": "Odobreno",
"available": "Dostupno"
},
"speedtest": {
"upload": "Prijenos",
"download": "Preuzimanje",
"ping": "Ping"
},
"portainer": {
"running": "Pokrenuto",
"stopped": "Prekinuto",
"total": "Ukupno"
},
"traefik": {
"routers": "Ruteri",
"services": "Usluge",
"middleware": "Middleware"
},
"gotify": {
"clients": "Klijenti",
"messages": "Poruke",
"apps": "Programi"
},
"jackett": {
"configured": "Konfigurirano",
"errored": "S greškom"
},
"qbittorrent": {
"download": "Preuzimanje",
"upload": "Prijenos",
"leech": "Krvopija",
"seed": "Prijenos preuzetog sadržaja"
},
"mastodon": {
"user_count": "Korisnici",
"status_count": "Objave",
"domain_count": "Domene"
},
"strelaysrv": {
"numActiveSessions": "Sesije",
"numConnections": "Veze",
"dataRelayed": "Proslijeđeno",
"transferRate": "Stopa"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"resources": {
"total": "Összes",
"free": "Szabad",
"used": "Használt",
"load": "Terhelés"
},
"docker": {
"rx": "RX",
"tx": "TX",
"mem": "MEM",
"cpu": "CPU",
"offline": "Offline"
},
"lidarr": {
"albums": "Albumok",
"wanted": "Keresett",
"queued": "Sorban áll"
},
"readarr": {
"wanted": "Keresett",
"queued": "Sorban áll",
"books": "Könyvek"
},
"bazarr": {
"missingEpisodes": "Hiányzó epizódok",
"missingMovies": "Hiányzó filmek"
},
"widget": {
"missing_type": "Hiányzó Widget Típus: {{type}}",
"api_error": "API Hiba",
"status": "Státusz"
},
"weather": {
"current": "Aktuális hely",
"allow": "Kattints az engedélyezéshez",
"updating": "Frissítés",
"wait": "Kérlek várj"
},
"search": {
"placeholder": "Keresés…"
},
"emby": {
"playing": "Lejátszás",
"transcoding": "Átkódolás",
"bitrate": "Bitráta",
"no_active": "Nincs aktív lejátszás"
},
"tautulli": {
"playing": "Lejátszás folyamatban",
"transcoding": "Átkódolás",
"bitrate": "Bitráta",
"no_active": "Nincs aktív lejátszás"
},
"nzbget": {
"rate": "Ráta",
"remaining": "Hátralévő",
"downloaded": "Letöltött"
},
"sabnzbd": {
"rate": "Ráta",
"queue": "Sor",
"timeleft": "Hátralévő idő"
},
"rutorrent": {
"active": "Aktív",
"upload": "Feltöltés",
"download": "Letöltés"
},
"transmission": {
"leech": "Leechelés",
"seed": "Seedelés",
"download": "Letöltés",
"upload": "Feltöltés"
},
"qbittorrent": {
"download": "Letöltés",
"upload": "Feltöltés",
"leech": "Leechelés",
"seed": "Seedelés"
},
"sonarr": {
"wanted": "Keresett",
"queued": "Sorban áll",
"series": "Sorozat"
},
"radarr": {
"wanted": "Keresett",
"queued": "Sorban áll",
"movies": "Filmek"
},
"ombi": {
"pending": "Függőben",
"approved": "Engedélyezett",
"available": "Elérhető"
},
"jellyseerr": {
"pending": "Függőben",
"approved": "Engedélyezett",
"available": "Elérhető"
},
"overseerr": {
"pending": "Függőben",
"approved": "Engedélyezett",
"available": "Elérhető"
},
"pihole": {
"queries": "Lekérdezések",
"blocked": "Blokkolt",
"gravity": "Gravitáció"
},
"adguard": {
"queries": "Lekérdezések",
"blocked": "Blokkolt",
"filtered": "Szűrt",
"latency": "Késleltetés"
},
"speedtest": {
"upload": "Feltöltés",
"download": "Letöltés",
"ping": "Ping"
},
"portainer": {
"running": "Futó",
"stopped": "Megállított",
"total": "Összes"
},
"traefik": {
"routers": "Routerek",
"services": "Folyamatok",
"middleware": "Közvetítő"
},
"npm": {
"enabled": "Bekapcsolva",
"disabled": "Kikapcsolva",
"total": "Összes"
},
"coinmarketcap": {
"configure": "Állíts be egy vagy több Cryptovalutát a követéshez",
"1hour": "1 Óra",
"1day": "1 Nap",
"7days": "7 Nap",
"30days": "30 Nap"
},
"gotify": {
"apps": "Applikációk",
"clients": "Kliensek",
"messages": "Üzenetek"
},
"prowlarr": {
"enableIndexers": "Indexerek",
"numberOfGrabs": "Fogott",
"numberOfFailGrabs": "Hibás fogások",
"numberOfQueries": "Lekérdezések",
"numberOfFailQueries": "Hibás lekérdezések"
},
"jackett": {
"configured": "Beállított",
"errored": "Hibás"
},
"mastodon": {
"user_count": "Users",
"status_count": "Posts",
"domain_count": "Domains"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
"numConnections": "Connections",
"dataRelayed": "Relayed",
"transferRate": "Rate"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"docker": {
"tx": "TX",
"mem": "MEM",
"cpu": "CPU",
"offline": "Offline",
"rx": "RX"
},
"emby": {
"playing": "In riproduzione",
"transcoding": "Transcoding",
"bitrate": "Bitrate",
"no_active": "Nessuno Stream Attivo"
},
"tautulli": {
"playing": "In riproduzione",
"transcoding": "Transcoding",
"bitrate": "Bitrate",
"no_active": "Nessuno Stream Attivo"
},
"speedtest": {
"upload": "Upload",
"download": "Download",
"ping": "Ping"
},
"portainer": {
"running": "In esecuzione",
"stopped": "Fermati",
"total": "Totali"
},
"traefik": {
"routers": "Routers",
"services": "Servizi",
"middleware": "Middleware"
},
"widget": {
"missing_type": "Missing Widget Type: {{type}}",
"api_error": "Errore API",
"status": "Stato"
},
"search": {
"placeholder": "Cerca…"
},
"resources": {
"total": "Totale",
"free": "Libero",
"used": "In utilizzo",
"load": "Load"
},
"rutorrent": {
"active": "Attivo",
"upload": "Upload",
"download": "Download"
},
"sonarr": {
"series": "Serie",
"wanted": "Rchiesti",
"queued": "In coda"
},
"radarr": {
"wanted": "Richiesti",
"queued": "In coda",
"movies": "Film"
},
"readarr": {
"wanted": "Wanted",
"queued": "Queued",
"books": "Books"
},
"ombi": {
"pending": "In attesa",
"approved": "Approvati",
"available": "Disponibili"
},
"jellyseerr": {
"pending": "In attesa",
"approved": "Approvati",
"available": "Disponibili"
},
"pihole": {
"queries": "Richieste",
"blocked": "Bloccati",
"gravity": "Severità"
},
"npm": {
"enabled": "Attivi",
"disabled": "Disabilitati",
"total": "Totali"
},
"weather": {
"current": "Posizione Attuale",
"allow": "Clicca per consentire",
"updating": "Aggiornamento in corso",
"wait": "Attendi per favore"
},
"overseerr": {
"pending": "In attesa",
"approved": "Approvati",
"available": "Disponibili"
},
"sabnzbd": {
"rate": "Rapporto",
"queue": "Coda",
"timeleft": "Tempo Rimanente"
},
"nzbget": {
"rate": "Rapporto",
"remaining": "Rimanente",
"downloaded": "Scaricato"
},
"coinmarketcap": {
"configure": "Configure one or more crypto currencies to track",
"1day": "1 Day",
"7days": "7 Days",
"1hour": "1 Hour",
"30days": "30 Days"
},
"gotify": {
"apps": "Applicazioni",
"clients": "Clients",
"messages": "Messaggi"
},
"prowlarr": {
"enableIndexers": "Indexers",
"numberOfGrabs": "Grabs",
"numberOfQueries": "Queries",
"numberOfFailGrabs": "Fail Grabs",
"numberOfFailQueries": "Fail Queries"
},
"transmission": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"jackett": {
"configured": "Configured",
"errored": "Errored"
},
"bazarr": {
"missingEpisodes": "Missing Episodes",
"missingMovies": "Missing Movies"
},
"lidarr": {
"wanted": "Wanted",
"queued": "Queued",
"albums": "Albums"
},
"adguard": {
"queries": "Queries",
"blocked": "Blocked",
"filtered": "Filtered",
"latency": "Latency"
},
"qbittorrent": {
"download": "Download",
"leech": "Leech",
"upload": "Upload",
"seed": "Seed"
},
"mastodon": {
"user_count": "Users",
"status_count": "Posts",
"domain_count": "Domains"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
"numConnections": "Connections",
"dataRelayed": "Relayed",
"transferRate": "Rate"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"widget": {
"missing_type": "Manglende miniprogramstype: {{type}}",
"api_error": "API-feil",
"status": "Status"
},
"search": {
"placeholder": "Søk …"
},
"resources": {
"total": "Totalt",
"free": "Ledig",
"used": "Brukt",
"load": "Last inn"
},
"docker": {
"rx": "Mottatt",
"tx": "Sendt",
"mem": "Minne",
"cpu": "Prosessor",
"offline": "Frakoblet"
},
"emby": {
"playing": "Spiller",
"transcoding": "Transkoding",
"bitrate": "Bitrate",
"no_active": "Ingen aktive strømmer"
},
"tautulli": {
"playing": "Spiller",
"transcoding": "Transkoding",
"bitrate": "Bitrate",
"no_active": "Ingen aktive strømmer"
},
"rutorrent": {
"active": "Aktiv",
"upload": "Opplasting",
"download": "Nedlasting"
},
"sonarr": {
"wanted": "Ønsket",
"queued": "I kø",
"series": "Serie"
},
"radarr": {
"wanted": "Ønsket",
"queued": "I kø",
"movies": "Filmer"
},
"readarr": {
"wanted": "Wanted",
"queued": "Queued",
"books": "Books"
},
"ombi": {
"pending": "Venter",
"approved": "Godkjent",
"available": "Tilgjengelig"
},
"jellyseerr": {
"pending": "Venter",
"approved": "Godkjent",
"available": "Tilgjengelig"
},
"pihole": {
"queries": "Spørringer",
"blocked": "Blokkert",
"gravity": "Gravitet"
},
"speedtest": {
"upload": "Opplasting",
"download": "Nedlasting",
"ping": "Ekkoforespørsel"
},
"portainer": {
"running": "Kjører",
"stopped": "Stoppet",
"total": "Totalt"
},
"traefik": {
"routers": "Rutere",
"services": "Tjenester",
"middleware": "Midtvare"
},
"npm": {
"enabled": "Påskrudd",
"disabled": "Avskrudd",
"total": "Totalt"
},
"weather": {
"allow": "Klikk for å tillate",
"updating": "Oppdaterer …",
"wait": "Vent litt …",
"current": "Nåværende posisjon"
},
"overseerr": {
"pending": "Venter",
"approved": "Godkjent",
"available": "Tilgjengelig"
},
"sabnzbd": {
"rate": "Takt",
"queue": "Kø",
"timeleft": "Gjenstående tid"
},
"nzbget": {
"rate": "Takt",
"downloaded": "Nedlastet",
"remaining": "Gjenstående"
},
"coinmarketcap": {
"configure": "Sett opp én eller flere kryptovalutaer å holde øye med",
"1hour": "1 Hour",
"1day": "1 Day",
"7days": "7 Days",
"30days": "30 Days"
},
"gotify": {
"apps": "Programmer",
"clients": "Klienter",
"messages": "Meldinger"
},
"prowlarr": {
"enableIndexers": "Indekserere",
"numberOfGrabs": "Hentninger",
"numberOfQueries": "Spørringer",
"numberOfFailGrabs": "Mislykkede hentinger",
"numberOfFailQueries": "Mislykkede spørringer"
},
"transmission": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"jackett": {
"configured": "Configured",
"errored": "Errored"
},
"bazarr": {
"missingEpisodes": "Missing Episodes",
"missingMovies": "Missing Movies"
},
"lidarr": {
"wanted": "Wanted",
"queued": "Queued",
"albums": "Albums"
},
"adguard": {
"queries": "Queries",
"blocked": "Blocked",
"filtered": "Filtered",
"latency": "Latency"
},
"qbittorrent": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"mastodon": {
"user_count": "Users",
"status_count": "Posts",
"domain_count": "Domains"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
"numConnections": "Connections",
"dataRelayed": "Relayed",
"transferRate": "Rate"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"widget": {
"missing_type": "Missing Widget Type: {{type}}",
"api_error": "API Error",
"status": "Status"
},
"resources": {
"total": "Totaal",
"free": "Vrij",
"used": "Gebruikt",
"load": "Load"
},
"docker": {
"rx": "RX",
"tx": "TX",
"mem": "MEM",
"cpu": "CPU",
"offline": "Offline"
},
"speedtest": {
"upload": "Upload",
"download": "Download",
"ping": "Ping"
},
"portainer": {
"running": "Draaiend",
"stopped": "Gestopt",
"total": "Totaal"
},
"weather": {
"updating": "Updaten",
"wait": "Even geduld",
"current": "Huidige Locatie",
"allow": "Klik om toe te staan"
},
"search": {
"placeholder": "Zoeken…"
},
"emby": {
"playing": "Afspelen",
"transcoding": "Transcodering",
"bitrate": "Bitsnelheid",
"no_active": "Geen Actieve Steams"
},
"tautulli": {
"playing": "Afspelen",
"transcoding": "Transcodering",
"bitrate": "Bitsnelheid",
"no_active": "No Active Streams"
},
"rutorrent": {
"active": "Actief",
"upload": "Upload",
"download": "Download"
},
"sonarr": {
"wanted": "Gezocht",
"queued": "In de wachtrij",
"series": "Series"
},
"radarr": {
"movies": "Films",
"wanted": "Gezocht",
"queued": "In de wachtrij"
},
"readarr": {
"wanted": "Wanted",
"queued": "Queued",
"books": "Books"
},
"ombi": {
"pending": "In afwachting",
"approved": "Goedgekeurd",
"available": "Beschikbaar"
},
"jellyseerr": {
"pending": "In afwachting",
"approved": "Goedgekeurd",
"available": "Beschikbaar"
},
"pihole": {
"queries": "Queries",
"blocked": "Geblokkeerd",
"gravity": "Gravity"
},
"traefik": {
"routers": "Routers",
"services": "Services",
"middleware": "Middleware"
},
"npm": {
"enabled": "Ingeschakeld",
"disabled": "Uitgeschakeld",
"total": "Totaal"
},
"overseerr": {
"pending": "Pending",
"approved": "Approved",
"available": "Available"
},
"sabnzbd": {
"rate": "Rate",
"queue": "Queue",
"timeleft": "Time Left"
},
"nzbget": {
"rate": "Rate",
"remaining": "Remaining",
"downloaded": "Downloaded"
},
"coinmarketcap": {
"configure": "Configure one or more crypto currencies to track",
"1hour": "1 Hour",
"7days": "7 Days",
"1day": "1 Day",
"30days": "30 Days"
},
"gotify": {
"apps": "Applications",
"clients": "Clients",
"messages": "Messages"
},
"prowlarr": {
"enableIndexers": "Indexers",
"numberOfGrabs": "Grabs",
"numberOfQueries": "Queries",
"numberOfFailGrabs": "Fail Grabs",
"numberOfFailQueries": "Fail Queries"
},
"transmission": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"jackett": {
"configured": "Configured",
"errored": "Errored"
},
"bazarr": {
"missingEpisodes": "Missing Episodes",
"missingMovies": "Missing Movies"
},
"lidarr": {
"wanted": "Wanted",
"queued": "Queued",
"albums": "Albums"
},
"adguard": {
"queries": "Queries",
"blocked": "Blocked",
"filtered": "Filtered",
"latency": "Latency"
},
"qbittorrent": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"mastodon": {
"user_count": "Users",
"status_count": "Posts",
"domain_count": "Domains"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
"numConnections": "Connections",
"dataRelayed": "Relayed",
"transferRate": "Rate"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"weather": {
"allow": "Kliknij, aby zezwolić",
"updating": "Aktualizacja",
"wait": "Proszę czekać",
"current": "Aktualna lokalizacja"
},
"search": {
"placeholder": "Szukaj…"
},
"resources": {
"used": "Użyte",
"load": "Obciążenie",
"total": "Całkowite",
"free": "Wolne"
},
"emby": {
"no_active": "Brak aktywnych strumieni",
"playing": "Odtwarzanie",
"transcoding": "Transkodowanie",
"bitrate": "Bitrate"
},
"tautulli": {
"playing": "Odtwarzanie",
"transcoding": "Transkodowanie",
"bitrate": "Bitrate",
"no_active": "Brak aktywnych strumieni"
},
"speedtest": {
"download": "Pobieranie",
"ping": "Ping",
"upload": "Wysyłanie"
},
"portainer": {
"running": "Działające",
"stopped": "Zatrzymane",
"total": "Ogólnie"
},
"coinmarketcap": {
"1day": "1 dzień",
"7days": "7 dni",
"30days": "30 dni",
"1hour": "1 godzina",
"configure": "Wybierz jedną lub więcej kryptowalut do śledzenia"
},
"gotify": {
"apps": "Aplikacje",
"clients": "Klienci",
"messages": "Wiadomości"
},
"widget": {
"missing_type": "Brakujący typ widżetu: {{type}}",
"api_error": "Błąd API",
"status": "Stan"
},
"docker": {
"rx": "RX",
"tx": "TX",
"mem": "MEM",
"cpu": "CPU",
"offline": "Offline"
},
"nzbget": {
"rate": "Szybkość",
"remaining": "Pozostało",
"downloaded": "Pobrano"
},
"sabnzbd": {
"rate": "Szybkość",
"queue": "Kolejka",
"timeleft": "Pozostało"
},
"rutorrent": {
"active": "Aktywny",
"upload": "Wysyłanie",
"download": "Pobieranie"
},
"transmission": {
"download": "Pobieranie",
"upload": "Wysyłanie",
"leech": "Leech",
"seed": "Seed"
},
"sonarr": {
"wanted": "Poszukiwane",
"queued": "W kolejce",
"series": "Seriale"
},
"radarr": {
"wanted": "Poszukiwane",
"queued": "W kolejce",
"movies": "Filmy"
},
"lidarr": {
"wanted": "Poszukiwane",
"queued": "W kolejce",
"albums": "Albumy"
},
"readarr": {
"wanted": "Poszukiwane",
"queued": "W kolejce",
"books": "Książki"
},
"bazarr": {
"missingEpisodes": "Brakujące odcinki",
"missingMovies": "Brakujące filmy"
},
"ombi": {
"pending": "Oczekiwane",
"approved": "Zaakceptowane",
"available": "Dostępne"
},
"jellyseerr": {
"pending": "Oczekiwane",
"approved": "Zaakceptowane",
"available": "Dostępne"
},
"overseerr": {
"pending": "Oczekiwane",
"approved": "Zaakceptowane",
"available": "Dostępne"
},
"pihole": {
"queries": "Zapytania",
"blocked": "Zablokowane",
"gravity": "Gravity"
},
"traefik": {
"routers": "Routery",
"services": "Serwisy",
"middleware": "Pośrednicy"
},
"npm": {
"enabled": "Włączone",
"disabled": "Wyłączone",
"total": "Ogólnie"
},
"prowlarr": {
"enableIndexers": "Indeksery",
"numberOfGrabs": "Pochwycenia",
"numberOfQueries": "Zapytania",
"numberOfFailGrabs": "Nieudane pochwycenia",
"numberOfFailQueries": "Nieudane zapytania"
},
"jackett": {
"configured": "Skonfigurowane",
"errored": "Błędne"
},
"adguard": {
"queries": "Queries",
"blocked": "Blocked",
"filtered": "Filtered",
"latency": "Latency"
},
"qbittorrent": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"mastodon": {
"user_count": "Users",
"status_count": "Posts",
"domain_count": "Domains"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
"numConnections": "Connections",
"dataRelayed": "Relayed",
"transferRate": "Rate"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"sabnzbd": {
"timeleft": "Tempo restante",
"rate": "Taxa",
"queue": "Fila"
},
"rutorrent": {
"active": "Ativo",
"upload": "Envio",
"download": "Download"
},
"portainer": {
"total": "Total",
"running": "Funcionando",
"stopped": "Parado"
},
"coinmarketcap": {
"7days": "7 Dias",
"configure": "Configure uma ou mais criptomoedas para rastrear",
"1hour": "1 Hora",
"1day": "1 Dia",
"30days": "30 Dias"
},
"strelaysrv": {
"numConnections": "Conexões",
"numActiveSessions": "Sessões",
"dataRelayed": "Retransmitido",
"transferRate": "Taxa"
},
"widget": {
"missing_type": "Tipo de Widget ausente: {{type}}",
"api_error": "Erro da API",
"status": "Status"
},
"weather": {
"current": "Localização atual",
"allow": "Clique para permitir",
"updating": "Atualizando",
"wait": "Aguarde, por favor"
},
"search": {
"placeholder": "Buscar…"
},
"resources": {
"total": "Total",
"free": "Livre",
"used": "Usado",
"load": "Carregamento"
},
"docker": {
"rx": "Rx",
"tx": "Tx",
"mem": "Mem",
"cpu": "CPU",
"offline": "Desligado"
},
"emby": {
"playing": "Reproduzindo",
"transcoding": "Transcodificando",
"bitrate": "Taxa de bits",
"no_active": "Sem transmissões ativas"
},
"tautulli": {
"playing": "Reproduzindo",
"transcoding": "Transcodificando",
"bitrate": "Taxa de bits",
"no_active": "Sem transmissões ativas"
},
"nzbget": {
"rate": "Taxa",
"remaining": "Restando",
"downloaded": "Baixado"
},
"transmission": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"qbittorrent": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"sonarr": {
"wanted": "Desejado",
"queued": "Na fila",
"series": "Séries"
},
"radarr": {
"wanted": "Desejado",
"queued": "Na fila",
"movies": "Filmes"
},
"lidarr": {
"wanted": "Desejado",
"queued": "Na fila",
"albums": "Álbuns"
},
"readarr": {
"wanted": "Desejado",
"queued": "Na fila",
"books": "Livros"
},
"bazarr": {
"missingEpisodes": "Episódios Ausentes",
"missingMovies": "Filmes Ausentes"
},
"ombi": {
"pending": "Pendente",
"approved": "Aprovado",
"available": "Disponível"
},
"jellyseerr": {
"pending": "Pendente",
"approved": "Aprovado",
"available": "Disponível"
},
"overseerr": {
"pending": "Pendente",
"approved": "Aprovado",
"available": "Disponível"
},
"pihole": {
"queries": "Consultas",
"blocked": "Bloquado",
"gravity": "Gravity"
},
"adguard": {
"queries": "Consultas",
"blocked": "Bloqueado",
"filtered": "Filtrado",
"latency": "Latência"
},
"speedtest": {
"upload": "Envio",
"download": "Receber",
"ping": "Ping"
},
"traefik": {
"routers": "Rotas",
"services": "Serviços",
"middleware": "Middleware"
},
"npm": {
"enabled": "Habilitado",
"disabled": "Desabilitado",
"total": "Total"
},
"gotify": {
"apps": "Aplicações",
"clients": "Clientes",
"messages": "Mensagens"
},
"prowlarr": {
"enableIndexers": "Indexadores",
"numberOfGrabs": "Grabs",
"numberOfQueries": "Queries",
"numberOfFailGrabs": "Fail Grabs",
"numberOfFailQueries": "Fail Queries"
},
"jackett": {
"configured": "Configurado",
"errored": "Erro"
},
"mastodon": {
"user_count": "Usuários",
"status_count": "Postagens",
"domain_count": "Domínios"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
}
}

View File

@@ -0,0 +1,188 @@
{
"widget": {
"missing_type": "Widget ausente: {{type}}",
"api_error": "Erro da API",
"status": "Status"
},
"search": {
"placeholder": "Pesquisar…"
},
"resources": {
"total": "Total",
"free": "Livre",
"used": "Usado",
"load": "Carregar"
},
"docker": {
"rx": "Rx",
"tx": "Tx",
"mem": "Mem",
"cpu": "CPU",
"offline": "Desligado"
},
"emby": {
"playing": "A reproduzir",
"transcoding": "Transcodificação",
"bitrate": "Taxa de bits",
"no_active": "Sem streams ativas"
},
"tautulli": {
"playing": "Reproduzindo",
"transcoding": "Transcodificação",
"bitrate": "Taxa de bits",
"no_active": "Sem streams ativas"
},
"rutorrent": {
"active": "Ativo",
"upload": "Enviando",
"download": "Baixando"
},
"sonarr": {
"wanted": "Desejada",
"queued": "Em fila",
"series": "Séries"
},
"radarr": {
"wanted": "Desejado",
"queued": "Fila",
"movies": "Filmes"
},
"readarr": {
"wanted": "Desejados",
"queued": "Em fila",
"books": "Livros"
},
"ombi": {
"pending": "Pendente",
"approved": "Aprovada",
"available": "Disponível"
},
"jellyseerr": {
"pending": "Pendente",
"approved": "Aprovada",
"available": "Disponível"
},
"pihole": {
"queries": "Consultas",
"blocked": "Bloqueado",
"gravity": "Gravidade"
},
"speedtest": {
"upload": "Envio",
"download": "Download",
"ping": "Ping"
},
"portainer": {
"running": "A correr",
"stopped": "Parado",
"total": "Total"
},
"traefik": {
"routers": "Roteadores",
"services": "Serviços",
"middleware": "Middleware"
},
"npm": {
"enabled": "Ativo",
"disabled": "Desabilitado",
"total": "Total"
},
"common": {
"bytes": "{{value, bytes}}",
"bbytes": "{{value, bytes(binary: true)}}",
"bits": "{{value, bytes(bits: true)}}",
"bbits": "{{value, bytes(bits: true, binary: true)}}",
"number": "{{value, number}}",
"byterate": "{{value, bytes}}",
"ms": "{{value, number}}",
"bitrate": "{{value, bytes(bits: true)}}",
"percent": "{{value, percent}}"
},
"weather": {
"current": "Localização atual",
"allow": "Clicar para permitir",
"updating": "A atualizar",
"wait": "Por favor aguarde"
},
"overseerr": {
"pending": "Pendente",
"approved": "Aprovado",
"available": "Disponível"
},
"sabnzbd": {
"rate": "Taxa",
"queue": "Fila",
"timeleft": "Tempo restante"
},
"nzbget": {
"rate": "Taxa",
"remaining": "Restante",
"downloaded": "Baixado"
},
"coinmarketcap": {
"configure": "Configurar uma ou mais moedas",
"1hour": "1 Hora",
"1day": "1 Dia",
"7days": "7 Dias",
"30days": "30 Dias"
},
"gotify": {
"apps": "Aplicações",
"clients": "Clientes",
"messages": "Mensagens"
},
"prowlarr": {
"enableIndexers": "Indexadores",
"numberOfGrabs": "Agarrados",
"numberOfQueries": "Consultas",
"numberOfFailGrabs": "Falhados",
"numberOfFailQueries": "Pesquisas falhadas"
},
"transmission": {
"download": "Baixando",
"upload": "Enviando",
"leech": "Sanguessugas",
"seed": "Semeadores"
},
"jackett": {
"configured": "Configurado",
"errored": "Errado"
},
"bazarr": {
"missingEpisodes": "Episódios Faltantes",
"missingMovies": "Filmes Faltantes"
},
"lidarr": {
"queued": "Enfileirado",
"wanted": "Desejado",
"albums": "Álbuns"
},
"adguard": {
"queries": "Consultas",
"blocked": "Bloqueado",
"filtered": "Filtrado",
"latency": "Latência"
},
"qbittorrent": {
"download": "Baixando",
"upload": "Enviando",
"leech": "Sanguessugas",
"seed": "Semeadores"
},
"mastodon": {
"user_count": "Usuários",
"status_count": "Postagens",
"domain_count": "Domínios"
},
"strelaysrv": {
"numActiveSessions": "Sessões",
"numConnections": "Conexões",
"dataRelayed": "Retransmitido",
"transferRate": "Taxa"
},
"authentik": {
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)",
"users": "Users"
}
}

View File

@@ -0,0 +1,177 @@
{
"resources": {
"used": "Utilizați",
"load": "Sarcină",
"total": "Total",
"free": "Disponibili"
},
"docker": {
"rx": "RX",
"tx": "TX",
"mem": "MEM",
"cpu": "CPU",
"offline": "Offline"
},
"jellyseerr": {
"approved": "Aprobate",
"available": "Disponibile",
"pending": "În așteptare"
},
"overseerr": {
"pending": "În așteptare",
"approved": "Aprobate",
"available": "Disponibile"
},
"pihole": {
"queries": "Cereri",
"blocked": "Blocate",
"gravity": "Gravity"
},
"adguard": {
"blocked": "Blocate",
"filtered": "Filtrate",
"queries": "Cereri",
"latency": "Latentă"
},
"traefik": {
"services": "Servicii",
"middleware": "Middleware",
"routers": "Routere"
},
"npm": {
"enabled": "Activat",
"disabled": "Dezactivat",
"total": "Total"
},
"coinmarketcap": {
"configure": "Configurați una sau mai multe criptomonede pe care să le urmăriți",
"1hour": "1 Oră",
"1day": "1 Zi",
"7days": "7 Zile",
"30days": "30 Zile"
},
"weather": {
"allow": "Click pentru a permite",
"updating": "Se actualizează",
"current": "Locația Curentă",
"wait": "Va rugăm așteptați"
},
"widget": {
"missing_type": "Lipsește Tipul de Widget: {{type}}",
"api_error": "Eroare API",
"status": "Status"
},
"search": {
"placeholder": "Caută…"
},
"tautulli": {
"no_active": "Niciun stream activ",
"playing": "Activ",
"transcoding": "Transcodare",
"bitrate": "Bitrate"
},
"nzbget": {
"rate": "Rată",
"remaining": "Rămas",
"downloaded": "Descărcat"
},
"emby": {
"playing": "Activ",
"transcoding": "Transcodare",
"bitrate": "Bitrate",
"no_active": "Niciun stream activ"
},
"sabnzbd": {
"rate": "Rată",
"queue": "Coadă",
"timeleft": "Timp rămas"
},
"transmission": {
"leech": "Leech",
"seed": "Seed",
"download": "Descarcă",
"upload": "Încarcă"
},
"rutorrent": {
"active": "Activ",
"upload": "Încarcă",
"download": "Descarcă"
},
"qbittorrent": {
"download": "Descarcă",
"upload": "Încarcă",
"leech": "Leech",
"seed": "Seed"
},
"sonarr": {
"wanted": "Dorite",
"queued": "În coadă",
"series": "Seriale"
},
"radarr": {
"queued": "În coadă",
"wanted": "Dorite",
"movies": "Filme"
},
"lidarr": {
"wanted": "Dorite",
"queued": "În coadă",
"albums": "Albume"
},
"readarr": {
"wanted": "Dorite",
"queued": "În coadă",
"books": "Cărți"
},
"bazarr": {
"missingEpisodes": "Episoade lipsă",
"missingMovies": "Filme lipsă"
},
"ombi": {
"pending": "În așteptare",
"approved": "Aprobate",
"available": "Disponibile"
},
"speedtest": {
"upload": "Încarcă",
"download": "Descarcă",
"ping": "Ping"
},
"portainer": {
"running": "Activ",
"stopped": "Oprit",
"total": "Total"
},
"gotify": {
"apps": "Aplicații",
"clients": "Clienți",
"messages": "Mesaje"
},
"prowlarr": {
"numberOfFailGrabs": "Descărcări eșuate",
"numberOfFailQueries": "Cereri eșuate",
"enableIndexers": "Indexatori",
"numberOfGrabs": "Descărcate",
"numberOfQueries": "Cereri"
},
"jackett": {
"configured": "Configurat",
"errored": "Cu erori"
},
"strelaysrv": {
"numActiveSessions": "Sesiuni",
"numConnections": "Conexiuni",
"dataRelayed": "Retransmise",
"transferRate": "Rată"
},
"mastodon": {
"user_count": "Utilizatori",
"status_count": "Postări",
"domain_count": "Domenii"
},
"authentik": {
"users": "Utilizatori",
"loginsLast24H": "Autentificări (24h)",
"failedLoginsLast24H": "Conectări eșuate (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"widget": {
"missing_type": "Отсутствует тип виджета: {{type}}",
"api_error": "Ошибка API",
"status": "Статус"
},
"search": {
"placeholder": "Поиск…"
},
"resources": {
"total": "Всего",
"free": "Свободно",
"used": "Использовано",
"load": "Load"
},
"docker": {
"rx": "Rx",
"tx": "Тx",
"mem": "Память",
"cpu": "Процессор",
"offline": "Не в сети"
},
"emby": {
"playing": "Воспроизведение",
"transcoding": "Транскодирование",
"bitrate": "Битрейт",
"no_active": "No Active Streams"
},
"tautulli": {
"playing": "Воспроизведение",
"transcoding": "Транскодирование",
"bitrate": "Битрейт",
"no_active": "No Active Streams"
},
"rutorrent": {
"active": "Активный",
"upload": "Загрузить",
"download": "Скачать"
},
"sonarr": {
"wanted": "Хотел",
"queued": "В очереди",
"series": "Серии"
},
"radarr": {
"wanted": "Хотел",
"queued": "В очереди",
"movies": "Фильмы"
},
"readarr": {
"wanted": "Wanted",
"queued": "Queued",
"books": "Books"
},
"ombi": {
"pending": "Ожидание",
"approved": "Одобрено",
"available": "Доступно"
},
"jellyseerr": {
"pending": "Ожидание",
"approved": "Одобрено",
"available": "Доступно"
},
"pihole": {
"queries": "Запросы",
"blocked": "Заблокировано",
"gravity": "Сила тяжести"
},
"speedtest": {
"upload": "Загрузка",
"download": "Скачать",
"ping": "пинг"
},
"portainer": {
"running": "Запущено",
"stopped": "Остановлено",
"total": "Всего"
},
"traefik": {
"routers": "Маршрутизаторы",
"services": "Сервисы",
"middleware": "Промежуточное программное обеспечение"
},
"npm": {
"enabled": "Включено",
"disabled": "Отключено",
"total": "Всего"
},
"weather": {
"wait": "Пожалуйста подождите",
"current": "Текущая локация",
"allow": "Нажмите, чтобы разрешить",
"updating": "Обновление"
},
"overseerr": {
"pending": "Pending",
"approved": "Approved",
"available": "Available"
},
"sabnzbd": {
"rate": "Rate",
"queue": "Queue",
"timeleft": "Time Left"
},
"nzbget": {
"rate": "Rate",
"remaining": "Remaining",
"downloaded": "Downloaded"
},
"coinmarketcap": {
"configure": "Configure one or more crypto currencies to track",
"1hour": "1 Hour",
"1day": "1 Day",
"7days": "7 Days",
"30days": "30 Дней"
},
"gotify": {
"apps": "Applications",
"clients": "Clients",
"messages": "Messages"
},
"prowlarr": {
"enableIndexers": "Indexers",
"numberOfGrabs": "Grabs",
"numberOfQueries": "Queries",
"numberOfFailGrabs": "Fail Grabs",
"numberOfFailQueries": "Fail Queries"
},
"transmission": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"jackett": {
"configured": "Configured",
"errored": "Errored"
},
"bazarr": {
"missingEpisodes": "Missing Episodes",
"missingMovies": "Missing Movies"
},
"lidarr": {
"wanted": "Wanted",
"queued": "Queued",
"albums": "Albums"
},
"adguard": {
"queries": "Queries",
"blocked": "Blocked",
"filtered": "Filtered",
"latency": "Latency"
},
"qbittorrent": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"mastodon": {
"user_count": "Users",
"status_count": "Posts",
"domain_count": "Domains"
},
"strelaysrv": {
"numConnections": "Connections",
"dataRelayed": "Relayed",
"transferRate": "Rate",
"numActiveSessions": "Sessions"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"widget": {
"missing_type": "Saknar Widget-typ: {{type}}",
"api_error": "API-fel",
"status": "Status"
},
"weather": {
"current": "Nuvarande plats",
"allow": "Klicka för att tillåta",
"updating": "Uppdaterar",
"wait": "Vänligen vänta"
},
"resources": {
"load": "Laddar",
"total": "Total",
"free": "Ledigt",
"used": "Använt"
},
"docker": {
"rx": "RX",
"tx": "TX",
"mem": "MEM",
"cpu": "CPU",
"offline": "Offline"
},
"search": {
"placeholder": "Sök…"
},
"emby": {
"playing": "Spelar",
"transcoding": "Omkodning",
"bitrate": "Bitrate",
"no_active": "Inga aktiva strömmar"
},
"tautulli": {
"playing": "Spelar",
"transcoding": "Omkodning",
"bitrate": "Bitrate",
"no_active": "Inga aktiva strömmar"
},
"nzbget": {
"rate": "Hastighet",
"remaining": "Återstående",
"downloaded": "Nedladdat"
},
"sabnzbd": {
"rate": "Hastighet",
"queue": "Kö",
"timeleft": "Tid kvar"
},
"rutorrent": {
"active": "Aktiva",
"upload": "Uppladdning",
"download": "Nedladdning"
},
"transmission": {
"download": "Nedladdning",
"upload": "Uppladdning",
"leech": "Leech",
"seed": "Seed"
},
"sonarr": {
"wanted": "Eftersöker",
"queued": "I kö",
"series": "Serier"
},
"radarr": {
"wanted": "Eftersöker",
"queued": "I kö",
"movies": "Filmer"
},
"lidarr": {
"wanted": "Eftersöker",
"queued": "I kö",
"albums": "Album"
},
"readarr": {
"wanted": "Eftersökt",
"queued": "I kö",
"books": "Böcker"
},
"bazarr": {
"missingEpisodes": "Saknade program",
"missingMovies": "Saknade filmer"
},
"ombi": {
"pending": "Avvaktar",
"approved": "Godkända",
"available": "Tillgänglig"
},
"jellyseerr": {
"pending": "Avvaktar",
"approved": "Godkända",
"available": "Tillgänglig"
},
"overseerr": {
"pending": "Avvaktar",
"approved": "Godkända",
"available": "Tillgänglig"
},
"pihole": {
"blocked": "Blockerad",
"queries": "Förfrågningar",
"gravity": "Gravity"
},
"speedtest": {
"upload": "Uppladdning",
"download": "Nedladdning",
"ping": "Svarstid"
},
"portainer": {
"running": "Körs",
"stopped": "Stoppade",
"total": "Totalt"
},
"traefik": {
"routers": "Routers",
"services": "Tjänster",
"middleware": "Middleware"
},
"npm": {
"enabled": "Aktiverad",
"disabled": "Inaktiverad",
"total": "Totalt"
},
"coinmarketcap": {
"configure": "Konfigurera en eller flera kryptovalutor att följa",
"1hour": "1 timme",
"1day": "1 dag",
"7days": "7 dagar",
"30days": "30 dagar"
},
"gotify": {
"apps": "Program",
"clients": "Klienter",
"messages": "Meddelande"
},
"prowlarr": {
"enableIndexers": "Indexerare",
"numberOfGrabs": "Hämtningar",
"numberOfQueries": "Hämtningar",
"numberOfFailGrabs": "Misslyckade hämtningar",
"numberOfFailQueries": "Misslyckade hämtningar"
},
"jackett": {
"configured": "Konfigurerade",
"errored": "Felaktiga"
},
"adguard": {
"queries": "Förfrågningar",
"blocked": "Blockerad",
"filtered": "Filtrerad",
"latency": "Svarstid"
},
"qbittorrent": {
"download": "Nedladdning",
"upload": "Uppladdning",
"leech": "Leech",
"seed": "Seed"
},
"mastodon": {
"user_count": "Användare",
"status_count": "Posts",
"domain_count": "Domains"
},
"strelaysrv": {
"numActiveSessions": "Sessioner",
"numConnections": "Anslutningar",
"dataRelayed": "Relayed",
"transferRate": "Rate"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"widget": {
"missing_type": "Thiếu loại Widget: {{type}}",
"api_error": "Lỗi API",
"status": "Trạng thái"
},
"search": {
"placeholder": "Tìm kiếm…"
},
"resources": {
"total": "Tổng",
"free": "Dư",
"used": "Đã dùng",
"load": "Load"
},
"docker": {
"rx": "RX",
"tx": "TX",
"mem": "BỘ NHỚ",
"cpu": "CPU",
"offline": "Ngoại tuyến"
},
"emby": {
"playing": "Đang chơi",
"transcoding": "Chuyển định dạng",
"bitrate": "Bitrate",
"no_active": "No Active Streams"
},
"tautulli": {
"playing": "Đang chơi",
"transcoding": "Chuyển định dạng",
"bitrate": "Bitrate",
"no_active": "No Active Streams"
},
"rutorrent": {
"active": "Hoạt động",
"upload": "Tải lên",
"download": "Tải xuống"
},
"sonarr": {
"wanted": "Wanted",
"queued": "Queued",
"series": "Series"
},
"radarr": {
"wanted": "Wanted",
"queued": "Queued",
"movies": "Phim"
},
"readarr": {
"wanted": "Đang tìm",
"queued": "Đang chờ",
"books": "Sách"
},
"ombi": {
"pending": "Đang xử lý",
"approved": "Đã duyệt",
"available": "Available"
},
"jellyseerr": {
"pending": "Pending",
"approved": "Approved",
"available": "Available"
},
"pihole": {
"queries": "Queries",
"blocked": "Blocked",
"gravity": "Gravity"
},
"speedtest": {
"upload": "Upload",
"download": "Download",
"ping": "Ping"
},
"portainer": {
"running": "Running",
"stopped": "Stopped",
"total": "Total"
},
"traefik": {
"routers": "Routers",
"services": "Services",
"middleware": "Middleware"
},
"npm": {
"enabled": "Enabled",
"disabled": "Disabled",
"total": "Total"
},
"weather": {
"current": "Vị trí hiện tại",
"allow": "Bấm để đồng ý",
"updating": "Đang cập nhật",
"wait": "Vui lòng chờ"
},
"overseerr": {
"pending": "Pending",
"approved": "Đã duyệt",
"available": "Available"
},
"sabnzbd": {
"rate": "Rate",
"queue": "Hàng chờ",
"timeleft": "Thời gian còn lại"
},
"nzbget": {
"rate": "Rate",
"remaining": "Remaining",
"downloaded": "Đã tải"
},
"coinmarketcap": {
"configure": "Configure one or more crypto currencies to track",
"1hour": "1 Hour",
"1day": "1 Day",
"7days": "7 Days",
"30days": "30 Days"
},
"gotify": {
"apps": "Applications",
"clients": "Clients",
"messages": "Messages"
},
"prowlarr": {
"numberOfFailGrabs": "Fail Grabs",
"enableIndexers": "Indexers",
"numberOfGrabs": "Grabs",
"numberOfQueries": "Queries",
"numberOfFailQueries": "Fail Queries"
},
"transmission": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"jackett": {
"configured": "Configured",
"errored": "Errored"
},
"bazarr": {
"missingEpisodes": "Missing Episodes",
"missingMovies": "Missing Movies"
},
"lidarr": {
"wanted": "Wanted",
"queued": "Queued",
"albums": "Albums"
},
"adguard": {
"queries": "Queries",
"blocked": "Blocked",
"filtered": "Filtered",
"latency": "Latency"
},
"qbittorrent": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"mastodon": {
"user_count": "Users",
"status_count": "Posts",
"domain_count": "Domains"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
"numConnections": "Connections",
"dataRelayed": "Relayed",
"transferRate": "Rate"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"emby": {
"transcoding": "轉碼緊",
"bitrate": "比特率",
"playing": "播放緊",
"no_active": "無任何活動"
},
"tautulli": {
"playing": "播放緊",
"no_active": "無任何活動",
"transcoding": "轉碼緊",
"bitrate": "比特率"
},
"transmission": {
"download": "下載速度",
"upload": "上傳速度",
"leech": "下載緊",
"seed": "做種緊"
},
"widget": {
"missing_type": "缺少小部件類型:{{type}}",
"api_error": "API 錯誤",
"status": "狀況"
},
"weather": {
"current": "依家位置",
"allow": "點擊允許",
"updating": "更新緊",
"wait": "請稍後"
},
"search": {
"placeholder": "搜索緊…"
},
"resources": {
"total": "全部",
"free": "剩餘",
"used": "用咗",
"load": "負荷"
},
"docker": {
"rx": "接收",
"tx": "發送",
"mem": "內存",
"cpu": "處理器",
"offline": "離線"
},
"nzbget": {
"rate": "速度",
"remaining": "剩餘",
"downloaded": "下載咗"
},
"sabnzbd": {
"rate": "速度",
"queue": "隊列",
"timeleft": "用時"
},
"rutorrent": {
"active": "激活",
"upload": "上傳",
"download": "下載"
},
"qbittorrent": {
"download": "下載速度",
"upload": "上傳速度",
"leech": "下載緊",
"seed": "做種緊"
},
"sonarr": {
"wanted": "想睇",
"queued": "排緊隊",
"series": "電視劇"
},
"radarr": {
"wanted": "想睇",
"queued": "排緊隊",
"movies": "電影"
},
"lidarr": {
"wanted": "想睇",
"queued": "排緊隊",
"albums": "專輯"
},
"readarr": {
"wanted": "想睇",
"queued": "排緊隊",
"books": "書"
},
"bazarr": {
"missingEpisodes": "缺少嘅劇集",
"missingMovies": "缺少電影"
},
"ombi": {
"pending": "待定",
"approved": "批准",
"available": "可用"
},
"jellyseerr": {
"pending": "提交咗",
"approved": "批准咗",
"available": "可睇嘅總量"
},
"overseerr": {
"pending": "待定",
"approved": "批准",
"available": "可用"
},
"pihole": {
"queries": "查詢",
"blocked": "封鎖",
"gravity": "重力"
},
"adguard": {
"queries": "查詢",
"blocked": "封鎖",
"filtered": "過濾",
"latency": "延遲"
},
"speedtest": {
"upload": "上傳速率",
"download": "下載速率",
"ping": "Ping值"
},
"portainer": {
"running": "運行緊",
"stopped": "暫停",
"total": "全部"
},
"traefik": {
"routers": "路由器",
"services": "服務項",
"middleware": "中間件"
},
"coinmarketcap": {
"1day": "1 日",
"configure": "配置一個或多個加密貨幣以進行跟蹤",
"1hour": "1 個鐘",
"7days": "7 日",
"30days": "30日"
},
"npm": {
"enabled": "啟用",
"disabled": "停用咗",
"total": "全部"
},
"gotify": {
"apps": "應用",
"clients": "客戶端",
"messages": "消息"
},
"prowlarr": {
"enableIndexers": "索引",
"numberOfGrabs": "抓住",
"numberOfQueries": "查詢",
"numberOfFailGrabs": "失敗抓取",
"numberOfFailQueries": "查詢失敗"
},
"jackett": {
"configured": "配置",
"errored": "已錯誤"
},
"strelaysrv": {
"numActiveSessions": "會話",
"numConnections": "連接",
"dataRelayed": "傳遞",
"transferRate": "速度"
},
"mastodon": {
"user_count": "用戶",
"status_count": "職位",
"domain_count": "域"
},
"authentik": {
"users": "用戶",
"loginsLast24H": "登錄( 24小时",
"failedLoginsLast24H": "登錄失敗( 24鐘頭"
}
}

View File

@@ -0,0 +1,177 @@
{
"widget": {
"missing_type": "缺少小部件类型:{{type}}",
"api_error": "API错误",
"status": "状态"
},
"search": {
"placeholder": "搜索…"
},
"resources": {
"total": "共",
"free": "空闲",
"used": "已用",
"load": "负载"
},
"docker": {
"rx": "接收",
"tx": "发送",
"mem": "内存",
"cpu": "处理器",
"offline": "离线"
},
"emby": {
"playing": "播放中",
"transcoding": "转码",
"bitrate": "比特率",
"no_active": "暂无播放"
},
"tautulli": {
"playing": "播放中",
"transcoding": "转码",
"bitrate": "比特率",
"no_active": "暂无播放"
},
"rutorrent": {
"active": "活动中",
"upload": "上传",
"download": "下载"
},
"sonarr": {
"wanted": "想看",
"queued": "排队",
"series": "系列"
},
"radarr": {
"wanted": "想看",
"queued": "队列",
"movies": "电影"
},
"readarr": {
"wanted": "订阅",
"queued": "队列",
"books": "书籍"
},
"ombi": {
"pending": "待办的",
"approved": "已批准",
"available": "可用的"
},
"jellyseerr": {
"pending": "待办的",
"approved": "得到正式认可的",
"available": "可用的"
},
"pihole": {
"queries": "查询",
"blocked": "阻止",
"gravity": "重力"
},
"speedtest": {
"upload": "上传",
"download": "下载",
"ping": "ping"
},
"portainer": {
"running": "运行中",
"stopped": "停止",
"total": "总计"
},
"traefik": {
"routers": "路由器",
"services": "服务",
"middleware": "中间件"
},
"npm": {
"enabled": "已启用",
"disabled": "禁用",
"total": "全部的"
},
"weather": {
"current": "当前定位",
"allow": "点击并允许",
"updating": "更新中",
"wait": "请稍后"
},
"overseerr": {
"pending": "待办",
"approved": "已批准",
"available": "可用"
},
"sabnzbd": {
"rate": "速率",
"queue": "队列",
"timeleft": "剩余时间"
},
"nzbget": {
"rate": "速率",
"remaining": "剩余",
"downloaded": "下载"
},
"coinmarketcap": {
"configure": "配置一个或多个需要追踪的加密",
"1hour": "1小时",
"1day": "1天",
"7days": "7天",
"30days": "30天"
},
"gotify": {
"apps": "应用",
"clients": "客户端",
"messages": "信息"
},
"prowlarr": {
"enableIndexers": "索引器",
"numberOfGrabs": "抓取",
"numberOfQueries": "查询",
"numberOfFailGrabs": "抓取失败",
"numberOfFailQueries": "查询失败"
},
"transmission": {
"download": "下载",
"upload": "上传",
"leech": "下载中",
"seed": "做种"
},
"jackett": {
"configured": "已配置",
"errored": "出错了"
},
"bazarr": {
"missingEpisodes": "缺少的剧集",
"missingMovies": "缺少的电影"
},
"lidarr": {
"wanted": "订阅",
"queued": "队列",
"albums": "相册"
},
"adguard": {
"queries": "查询",
"blocked": "阻止",
"filtered": "过滤",
"latency": "延迟"
},
"qbittorrent": {
"download": "下载",
"upload": "上传",
"leech": "下载中",
"seed": "做种"
},
"mastodon": {
"user_count": "用户",
"status_count": "Posts",
"domain_count": "Domains"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
"dataRelayed": "Relayed",
"numConnections": "Connections",
"transferRate": "Rate"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
}
}

View File

@@ -0,0 +1,177 @@
{
"widget": {
"missing_type": "Missing Widget Type: {{type}}",
"api_error": "API Error",
"status": "Status"
},
"weather": {
"current": "Current Location",
"allow": "Click to allow",
"updating": "Updating",
"wait": "Please wait"
},
"docker": {
"rx": "RX",
"offline": "Offline",
"tx": "TX",
"mem": "MEM",
"cpu": "CPU"
},
"emby": {
"playing": "Playing",
"transcoding": "Transcoding",
"bitrate": "Bitrate",
"no_active": "No Active Streams"
},
"tautulli": {
"playing": "Playing",
"transcoding": "Transcoding",
"bitrate": "Bitrate",
"no_active": "No Active Streams"
},
"jellyseerr": {
"pending": "Pending",
"approved": "Approved",
"available": "Available"
},
"search": {
"placeholder": "Search…"
},
"resources": {
"total": "Total",
"free": "Free",
"used": "Used",
"load": "Load"
},
"nzbget": {
"rate": "Rate",
"remaining": "Remaining",
"downloaded": "Downloaded"
},
"sabnzbd": {
"rate": "Rate",
"queue": "Queue",
"timeleft": "Time Left"
},
"rutorrent": {
"active": "Active",
"upload": "Upload",
"download": "Download"
},
"radarr": {
"movies": "Movies",
"wanted": "Wanted",
"queued": "Queued"
},
"sonarr": {
"wanted": "Wanted",
"queued": "Queued",
"series": "Series"
},
"readarr": {
"wanted": "Wanted",
"queued": "Queued",
"books": "Books"
},
"ombi": {
"pending": "Pending",
"approved": "Approved",
"available": "Available"
},
"overseerr": {
"pending": "Pending",
"approved": "Approved",
"available": "Available"
},
"pihole": {
"queries": "Queries",
"blocked": "Blocked",
"gravity": "Gravity"
},
"speedtest": {
"upload": "Upload",
"download": "Download",
"ping": "Ping"
},
"portainer": {
"running": "Running",
"stopped": "Stopped",
"total": "Total"
},
"traefik": {
"routers": "Routers",
"services": "Services",
"middleware": "Middleware"
},
"gotify": {
"clients": "Clients",
"apps": "Applications",
"messages": "Messages"
},
"npm": {
"enabled": "Enabled",
"disabled": "Disabled",
"total": "Total"
},
"coinmarketcap": {
"configure": "Configure one or more crypto currencies to track",
"1hour": "1 Hour",
"1day": "1 Day",
"7days": "7 Days",
"30days": "30 Days"
},
"prowlarr": {
"enableIndexers": "Indexers",
"numberOfGrabs": "Grabs",
"numberOfQueries": "Queries",
"numberOfFailGrabs": "Fail Grabs",
"numberOfFailQueries": "Fail Queries"
},
"transmission": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"jackett": {
"configured": "Configured",
"errored": "Errored"
},
"bazarr": {
"missingEpisodes": "Missing Episodes",
"missingMovies": "Missing Movies"
},
"lidarr": {
"wanted": "Wanted",
"queued": "Queued",
"albums": "Albums"
},
"adguard": {
"queries": "Queries",
"blocked": "Blocked",
"filtered": "Filtered",
"latency": "Latency"
},
"qbittorrent": {
"download": "Download",
"upload": "Upload",
"leech": "Leech",
"seed": "Seed"
},
"mastodon": {
"user_count": "Users",
"status_count": "Posts",
"domain_count": "Domains"
},
"strelaysrv": {
"numActiveSessions": "Sessions",
"numConnections": "Connections",
"dataRelayed": "Relayed",
"transferRate": "Rate"
},
"authentik": {
"users": "Users",
"loginsLast24H": "Logins (24h)",
"failedLoginsLast24H": "Failed Logins (24h)"
}
}

View File

@@ -2,13 +2,8 @@ import List from "components/bookmarks/list";
export default function BookmarksGroup({ group }) {
return (
<div
key={group.name}
className="basis-full md:basis-1/2 lg:basis-1/3 xl:basis-1/4 flex-1 p-1"
>
<h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium">
{group.name}
</h2>
<div key={group.name} className="basis-full md:basis-1/2 lg:basis-1/3 xl:basis-1/4 flex-1 p-1">
<h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium">{group.name}</h2>
<List bookmarks={group.bookmarks} />
</div>
);

View File

@@ -1,21 +1,29 @@
import { useContext } from "react";
import { SettingsContext } from "utils/contexts/settings";
export default function Item({ bookmark }) {
const { hostname } = new URL(bookmark.href);
const { settings } = useContext(SettingsContext);
return (
<li
onClick={() => {
window.open(bookmark.href, "_blank").focus();
}}
key={bookmark.name}
className="mb-3 cursor-pointer flex rounded-md font-medium text-theme-700 hover:text-theme-800 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/50 bg-white/50 hover:bg-theme-300/10 dark:bg-white/5 dark:hover:bg-white/10"
>
<div className="flex-shrink-0 flex items-center justify-center w-11 bg-theme-500/10 dark:bg-theme-900/50 text-theme-700 dark:text-theme-200 text-sm font-medium rounded-l-md">
{bookmark.abbr}
</div>
<div className="flex-1 flex items-center justify-between rounded-r-md ">
<div className="flex-1 grow pl-3 py-2 text-xs">{bookmark.name}</div>
<div className="px-2 py-2 truncate text-theme-500 dark:text-theme-400 opacity-50 text-xs">{hostname}</div>
</div>
<li key={bookmark.name}>
<a
href={bookmark.href}
title={bookmark.name}
target={settings.target ?? "_blank"}
className="block w-full text-left cursor-pointer transition-all h-15 mb-3 rounded-md font-medium text-theme-700 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 hover:bg-theme-300/20 dark:bg-white/5 dark:hover:bg-white/10"
>
<div className="flex">
<div className="flex-shrink-0 flex items-center justify-center w-11 bg-theme-500/10 dark:bg-theme-900/50 text-theme-700 hover:text-theme-700 dark:text-theme-200 text-sm font-medium rounded-l-md">
{bookmark.abbr}
</div>
<div className="flex-1 flex items-center justify-between rounded-r-md ">
<div className="flex-1 grow pl-3 py-2 text-xs">{bookmark.name}</div>
<div className="px-2 py-2 truncate text-theme-500 dark:text-theme-300 text-xs">{hostname}</div>
</div>
</div>
</a>
</li>
);
}

View File

@@ -2,7 +2,7 @@ import Item from "components/bookmarks/item";
export default function List({ bookmarks }) {
return (
<ul role="list" className="mt-3 flex flex-col">
<ul className="mt-3 flex flex-col">
{bookmarks.map((bookmark) => (
<Item key={bookmark.name} bookmark={bookmark} />
))}

View File

@@ -1,81 +0,0 @@
import { useContext } from "react";
import { IoColorPalette } from "react-icons/io5";
import { Popover, Transition } from "@headlessui/react";
import { Fragment } from "react";
import { ColorContext } from "utils/color-context";
const colors = [
"slate",
"gray",
"zinc",
"neutral",
"stone",
"amber",
"yellow",
"lime",
"green",
"emerald",
"teal",
"cyan",
"sky",
"blue",
"indigo",
"violet",
"purple",
"fuchsia",
"pink",
"rose",
"red",
];
export default function ColorToggle() {
const { color: active, setColor } = useContext(ColorContext);
if (!active) {
return null;
}
return (
<div className="w-full self-center">
<Popover className="relative flex items-center">
{({ open }) => (
<>
<Popover.Button className="outline-none">
<IoColorPalette
className="h-5 w-5 text-theme-800 dark:text-theme-200 transition duration-150 ease-in-out"
aria-hidden="true"
/>
</Popover.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute -top-[75px] left-0">
<div className="rounded-md shadow-lg ring-1 ring-black ring-opacity-5">
<div className="relative grid gap-2 p-2 grid-cols-11 shadow-theme-900/10 dark:shadow-theme-900 rounded-md shadow-md">
{colors.map((color) => (
<button role="button" onClick={() => setColor(color)} key={color}>
<div
className={
(active == color ? "border-2" : "border-0") +
` rounded-md w-5 h-5 border-black/50 dark:border-white/50 theme-${color} bg-theme-500`
}
/>
</button>
))}
</div>
</div>
</Popover.Panel>
</Transition>
</>
)}
</Popover>
</div>
);
}

View File

@@ -1,20 +0,0 @@
export default function Greeting() {
const name = process.env.NEXT_PUBLIC_DISPLAY_NAME;
const hour = new Date().getHours();
let day = "day";
if (hour < 12) {
day = "morning";
} else if (hour < 17) {
day = "afternoon";
} else {
day = "evening";
}
return (
<div className="self-end grow text-2xl font-thin text-theme-800 dark:text-theme-200">
Good {day}
</div>
);
}

View File

@@ -1,68 +0,0 @@
import { Fragment, useRef, useState, Children } from "react";
import { Dialog, Transition } from "@headlessui/react";
function classNames(...classes) {
return classes.filter(Boolean).join(" ");
}
const Modal = ({ Toggle, Content }) => {
const [open, setOpen] = useState(false);
const cancelButtonRef = useRef(null);
return (
<>
<Toggle open={open} setOpen={setOpen} />
<Transition.Root show={open} as={Fragment}>
<Dialog
as="div"
className="relative z-10"
initialFocus={cancelButtonRef}
onClose={setOpen}
>
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0"
enterTo="opacity-100"
leave="ease-in duration-200"
leaveFrom="opacity-100"
leaveTo="opacity-0"
>
<div className="fixed inset-0 bg-theme-900/90 transition-opacity" />
</Transition.Child>
<div className="fixed z-10 inset-0 overflow-y-auto">
<div className="flex items-center justify-center min-h-full">
<Transition.Child
as={Fragment}
enter="ease-out duration-300"
enterFrom="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
enterTo="opacity-100 translate-y-0 sm:scale-100"
leave="ease-in duration-200"
leaveFrom="opacity-100 translate-y-0 sm:scale-100"
leaveTo="opacity-0 translate-y-4 sm:translate-y-0 sm:scale-95"
>
<Dialog.Panel className="relative rounded-lg shadow-xl transform transition-all my-8 max-w-lg w-full">
<Content open={open} setOpen={setOpen} />
</Dialog.Panel>
</Transition.Child>
</div>
</div>
</Dialog>
</Transition.Root>
</>
);
};
const ModalToggle = ({ open, setOpen, children }) => (
<div onClick={() => setOpen(!open)}>{children}</div>
);
const ModalContent = ({ open, setOpen, children }) => (
<div className="body">{children}</div>
);
Modal.Toggle = ModalToggle;
Modal.Content = ModalContent;
export default Modal;

View File

@@ -0,0 +1,48 @@
import { Fragment } from "react";
import { Menu, Transition } from "@headlessui/react";
import { BiCog } from "react-icons/bi";
import classNames from "classnames";
export default function Dropdown({ options, value, setValue }) {
return (
<Menu as="div" className="relative inline-block text-left">
<div>
<Menu.Button className="text-xs inline-flex w-full items-center rounded bg-theme-200/50 dark:bg-theme-900/20 px-3 py-1.5">
{options.find((option) => option.value === value).label}
<BiCog className="-mr-1 ml-2 h-4 w-4" aria-hidden="true" />
</Menu.Button>
</div>
<Transition
as={Fragment}
enter="transition ease-out duration-100"
enterFrom="transform opacity-0 scale-95"
enterTo="transform opacity-100 scale-100"
leave="transition ease-in duration-75"
leaveFrom="transform opacity-100 scale-100"
leaveTo="transform opacity-0 scale-95"
>
<Menu.Items className="absolute right-0 z-10 mt-2 w-56 origin-top-right rounded-md bg-theme-200/50 dark:bg-theme-900/50 backdrop-blur shadow-md focus:outline-none text-theme-700 dark:text-theme-200">
<div className="py-1">
{options.map((option) => (
<Menu.Item key={option.value} as={Fragment}>
<button
onClick={() => {
setValue(option.value);
}}
type="button"
className={classNames(
value === option.value ? "bg-theme-300/40 dark:bg-theme-900/40" : "",
"w-full block px-3 py-1.5 text-sm hover:bg-theme-300/70 hover:dark:bg-theme-900/70 text-left"
)}
>
{option.label}
</button>
</Menu.Item>
))}
</div>
</Menu.Items>
</Transition>
</Menu>
);
}

View File

@@ -1,15 +1,18 @@
import classNames from "classnames";
import List from "components/services/list";
export default function ServicesGroup({ services }) {
export default function ServicesGroup({ services, layout }) {
return (
<div
key={services.name}
className="basis-full md:basis-1/2 lg:basis-1/3 xl:basis-1/4 flex-1 p-1"
className={classNames(
layout?.style === "row" ? "basis-full" : "basis-full md:basis-1/2 lg:basis-1/3 xl:basis-1/4",
"flex-1 p-1"
)}
>
<h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium">
{services.name}
</h2>
<List services={services.services} />
<h2 className="text-theme-800 dark:text-theme-300 text-xl font-medium">{services.name}</h2>
<List services={services.services} layout={layout} />
</div>
);
}

View File

@@ -1,75 +1,116 @@
import Image from "next/future/image";
import { Disclosure } from "@headlessui/react";
import classNames from "classnames";
import { useContext, useState } from "react";
import Status from "./status";
import Widget from "./widget";
import Docker from "./widgets/service/docker";
import Docker from "widgets/docker/component";
import { SettingsContext } from "utils/contexts/settings";
function resolveIcon(icon) {
if (icon.startsWith("http")) {
return `/api/proxy?url=${encodeURIComponent(icon)}`;
} else if (icon.startsWith("/")) {
return icon;
} else {
if (icon.endsWith(".png")) {
return `https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/${icon}`;
} else {
return `https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/${icon}.png`;
}
}
if (icon.startsWith("/")) {
return icon;
}
if (icon.endsWith(".png")) {
return `https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/${icon}`;
}
return `https://cdn.jsdelivr.net/gh/walkxcode/dashboard-icons/png/${icon}.png`;
}
export default function Item({ service }) {
const hasLink = service.href && service.href !== "#";
const { settings } = useContext(SettingsContext);
const [statsOpen, setStatsOpen] = useState(false);
const [statsClosing, setStatsClosing] = useState(false);
// set stats to closed after 300ms
const closeStats = () => {
if (statsOpen) {
setStatsClosing(true);
setTimeout(() => {
setStatsOpen(false);
setStatsClosing(false);
}, 300);
}
};
return (
<li key={service.name}>
<Disclosure>
<div className={
(service.href && service.href !== "#" ? 'cursor-pointer ' : 'cursor-default ') +
'transition-all h-15 overflow-hidden mb-3 p-1 rounded-md font-medium text-theme-700 hover:text-theme-800 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/40 bg-white/50 hover:bg-theme-300/10 dark:bg-white/5 dark:hover:bg-white/10'
}>
<div className="flex">
{service.icon && (
<div
onClick={() => {
if (service.href && service.href !== "#") {
window.open(service.href, "_blank").focus();
}
}}
<div
className={`${
hasLink ? "cursor-pointer " : " "
}transition-all h-15 mb-3 p-1 rounded-md font-medium text-theme-700 dark:text-theme-200 dark:hover:text-theme-300 shadow-md shadow-theme-900/10 dark:shadow-theme-900/20 bg-theme-100/20 hover:bg-theme-300/20 dark:bg-white/5 dark:hover:bg-white/10`}
>
<div className="flex select-none">
{service.icon &&
(hasLink ? (
<a
href={service.href}
target={settings.target ?? "_blank"}
rel="noreferrer"
className="flex-shrink-0 flex items-center justify-center w-12 "
>
<Image src={resolveIcon(service.icon)} width={32} height={32} alt="logo" />
</a>
) : (
<div className="flex-shrink-0 flex items-center justify-center w-12 ">
<Image src={resolveIcon(service.icon)} width={32} height={32} alt="logo" />
</div>
)}
))}
<div
onClick={() => {
if (service.href && service.href !== "#") {
window.open(service.href, "_blank").focus();
}
}}
{hasLink ? (
<a
href={service.href}
target={settings.target ?? "_blank"}
rel="noreferrer"
className="flex-1 flex items-center justify-between rounded-r-md "
>
<div className="flex-1 px-2 py-2 text-sm">
<div className="flex-1 px-2 py-2 text-sm text-left">
{service.name}
<p className="text-theme-500 dark:text-theme-400 text-xs font-extralight">{service.description}</p>
<p className="text-theme-500 dark:text-theme-300 text-xs font-light">{service.description}</p>
</div>
</a>
) : (
<div className="flex-1 flex items-center justify-between rounded-r-md ">
<div className="flex-1 px-2 py-2 text-sm text-left">
{service.name}
<p className="text-theme-500 dark:text-theme-300 text-xs font-light">{service.description}</p>
</div>
</div>
{service.container && (
<Disclosure.Button as="div" className="flex-shrink-0 flex items-center justify-center w-12 cursor-pointer">
<Status service={service} />
</Disclosure.Button>
)}
</div>
)}
<Disclosure.Panel>
<div className="w-full">
<Docker service={{ widget: { container: service.container, server: service.server } }} />
</div>
</Disclosure.Panel>
{service.widget && <Widget service={service} />}
{service.container && (
<button
type="button"
onClick={() => (statsOpen ? closeStats() : setStatsOpen(true))}
className="flex-shrink-0 flex items-center justify-center w-12 cursor-pointer"
>
<Status service={service} />
<span className="sr-only">View container stats</span>
</button>
)}
</div>
</Disclosure>
{service.container && service.server && (
<div
className={classNames(
statsOpen && !statsClosing ? "max-h-[55px] opacity-100" : " max-h-[0] opacity-0",
"w-full overflow-hidden transition-all duration-300 ease-in-out"
)}
>
{statsOpen && <Docker service={{ widget: { container: service.container, server: service.server } }} />}
</div>
)}
{service.widget && <Widget service={service} />}
</div>
</li>
);
}

View File

@@ -1,8 +1,27 @@
import classNames from "classnames";
import Item from "components/services/item";
export default function List({ services }) {
const columnMap = [
"grid-cols-1 md:grid-cols-1 lg:grid-cols-1",
"grid-cols-1 md:grid-cols-1 lg:grid-cols-1",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-2",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-3",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-4",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-5",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-6",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-7",
"grid-cols-1 md:grid-cols-2 lg:grid-cols-8",
];
export default function List({ services, layout }) {
return (
<ul role="list" className="mt-3 flex flex-col">
<ul
className={classNames(
layout?.style === "row" ? `grid ${columnMap[layout?.columns]} gap-x-2` : "flex flex-col",
"mt-3"
)}
>
{services.map((service) => (
<Item key={service.name} service={service} />
))}

View File

@@ -1,28 +1,18 @@
import useSWR from "swr";
export default function Status({ service }) {
const { data, error } = useSWR(
`/api/docker/status/${service.container}/${service.server || ""}`
);
const { data, error } = useSWR(`/api/docker/status/${service.container}/${service.server || ""}`);
if (error) {
return (
<div className="w-3 h-3 bg-rose-300 dark:bg-rose-500 rounded-full" />
);
return <div className="w-3 h-3 bg-rose-300 dark:bg-rose-500 rounded-full" />;
}
if (data && data.status === "running") {
return (
<div className="w-3 h-3 bg-emerald-300 dark:bg-emerald-500 rounded-full" />
);
return <div className="w-3 h-3 bg-emerald-300 dark:bg-emerald-500 rounded-full" />;
}
if (data && data.status === "not found") {
return (
<>
<div className="h-2.5 w-2.5 bg-orange-400/50 dark:bg-yellow-200/40 -rotate-45"></div>
</>
);
return <div className="h-2.5 w-2.5 bg-orange-400/50 dark:bg-yellow-200/40 -rotate-45" />;
}
return <div className="w-3 h-3 bg-black/20 dark:bg-white/40 rounded-full" />;

View File

@@ -1,39 +1,11 @@
import Sonarr from "./widgets/service/sonarr";
import Radarr from "./widgets/service/radarr";
import Ombi from "./widgets/service/ombi";
import Portainer from "./widgets/service/portainer";
import Emby from "./widgets/service/emby";
import Nzbget from "./widgets/service/nzbget";
import Docker from "./widgets/service/docker";
import Pihole from "./widgets/service/pihole";
import Rutorrent from "./widgets/service/rutorrent";
import Jellyfin from "./widgets/service/jellyfin";
import Speedtest from "./widgets/service/speedtest";
import Traefik from "./widgets/service/traefik";
import Jellyseerr from "./widgets/service/jellyseerr";
import Npm from "./widgets/service/npm";
import Tautulli from "./widgets/service/tautulli";
import { useTranslation } from "next-i18next";
const widgetMappings = {
docker: Docker,
sonarr: Sonarr,
radarr: Radarr,
ombi: Ombi,
portainer: Portainer,
emby: Emby,
jellyfin: Jellyfin,
nzbget: Nzbget,
pihole: Pihole,
rutorrent: Rutorrent,
speedtest: Speedtest,
traefik: Traefik,
jellyseerr: Jellyseerr,
npm: Npm,
tautulli: Tautulli,
};
import components from "widgets/components";
export default function Widget({ service }) {
const ServiceWidget = widgetMappings[service.widget.type];
const { t } = useTranslation("common");
const ServiceWidget = components[service.widget.type];
if (ServiceWidget) {
return <ServiceWidget service={service} />;
@@ -41,9 +13,7 @@ export default function Widget({ service }) {
return (
<div className="bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-col items-center justify-center p-1">
<div className="font-thin text-sm">
Missing Widget Type: <strong>{service.widget.type}</strong>
</div>
<div className="font-thin text-sm">{t("widget.missing_type", { type: service.widget.type })}</div>
</div>
);
}

View File

@@ -0,0 +1,18 @@
import { useTranslation } from "next-i18next";
import classNames from "classnames";
export default function Block({ value, label }) {
const { t } = useTranslation();
return (
<div
className={classNames(
"bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-col items-center justify-center p-1",
value === undefined ? "animate-pulse" : ""
)}
>
<div className="font-thin text-sm">{value === undefined || value === null ? "-" : value}</div>
<div className="font-bold text-xs uppercase">{t(label)}</div>
</div>
);
}

View File

@@ -0,0 +1,18 @@
export default function Container({ error = false, children, service }) {
if (error) {
return (
<div className="bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-col items-center justify-center p-1">
<div className="font-thin text-sm">{error}</div>
</div>
);
}
let visibleChildren = children;
const fields = service?.widget?.fields;
const type = service?.widget?.type;
if (fields && type) {
visibleChildren = children.filter(child => fields.some(field => `${type}.${field}` === child.props?.label));
}
return <div className="relative flex flex-row w-full">{visibleChildren}</div>;
}

View File

@@ -1,8 +0,0 @@
export default function Block({ value, label }) {
return (
<div className="bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-col items-center justify-center p-1">
<div className="font-thin text-sm">{value === undefined || value === null ? "-" : value}</div>
<div className="font-bold text-xs uppercase">{label}</div>
</div>
);
}

View File

@@ -1,60 +0,0 @@
import useSWR from "swr";
import Widget from "../widget";
import Block from "../block";
import { calculateCPUPercent, formatBytes } from "utils/stats-helpers";
export default function Docker({ service }) {
const config = service.widget;
const { data: statusData, error: statusError } = useSWR(
`/api/docker/status/${config.container}/${config.server || ""}`,
{
refreshInterval: 5000,
}
);
const { data: statsData, error: statsError } = useSWR(
`/api/docker/stats/${config.container}/${config.server || ""}`,
{
refreshInterval: 5000,
}
);
if (statsError || statusError) {
return <Widget error="Error Fetching Data" />;
}
if (statusData && statusData.status !== "running") {
return (
<Widget>
<Block label="Status" value="Offline" />
</Widget>
);
}
if (!statsData || !statusData) {
return (
<Widget>
<Block label="CPU" />
<Block label="MEM" />
<Block label="RX" />
<Block label="TX" />
</Widget>
);
}
return (
<Widget>
<Block label="CPU" value={`${calculateCPUPercent(statsData.stats)}%`} />
<Block label="MEM" value={formatBytes(statsData.stats.memory_stats.usage, 0)} />
{statsData.stats.networks && (
<>
<Block label="RX" value={formatBytes(statsData.stats.networks.eth0.rx_bytes, 0)} />
<Block label="TX" value={formatBytes(statsData.stats.networks.eth0.tx_bytes, 0)} />
</>
)}
</Widget>
);
}

View File

@@ -1,40 +0,0 @@
import useSWR from "swr";
import Widget from "../widget";
import Block from "../block";
import { formatApiUrl } from "utils/api-helpers";
export default function Emby({ service, title = "Emby" }) {
const config = service.widget;
const { data: sessionsData, error: sessionsError } = useSWR(formatApiUrl(config, "Sessions"));
if (sessionsError) {
return <Widget error={`${title} API Error`} />;
}
if (!sessionsData) {
return (
<Widget>
<Block label="Playing" />
<Block label="Transcoding" />
<Block label="Bitrate" />
</Widget>
);
}
const playing = sessionsData.filter((session) => session.hasOwnProperty("NowPlayingItem"));
const transcoding = sessionsData.filter(
(session) => session.hasOwnProperty("PlayState") && session.PlayState.PlayMethod === "Transcode"
);
const bitrate = playing.reduce((acc, session) => acc + session.NowPlayingItem.Bitrate, 0);
return (
<Widget>
<Block label="Playing" value={playing.length} />
<Block label="Transcoding" value={transcoding.length} />
<Block label="Bitrate" value={`${Math.round((bitrate / 1024 / 1024) * 100) / 100} Mbps`} />
</Widget>
);
}

View File

@@ -1,6 +0,0 @@
import Emby from "./emby";
// Jellyfin and Emby share the same API, so proxy the Emby widget to Jellyfin.
export default function Jellyfin({ service }) {
return <Emby service={service} title="Jellyfin" />;
}

View File

@@ -1,34 +0,0 @@
import useSWR from "swr";
import Widget from "../widget";
import Block from "../block";
import { formatApiUrl } from "utils/api-helpers";
export default function Jellyseerr({ service }) {
const config = service.widget;
const { data: statsData, error: statsError } = useSWR(formatApiUrl(config, `request/count`));
if (statsError) {
return <Widget error="Jellyseerr API Error" />;
}
if (!statsData) {
return (
<Widget>
<Block label="Pending" />
<Block label="Approved" />
<Block label="Available" />
</Widget>
);
}
return (
<Widget>
<Block label="Pending" value={statsData.pending} />
<Block label="Approved" value={statsData.approved} />
<Block label="Available" value={statsData.available} />
</Widget>
);
}

View File

@@ -1,38 +0,0 @@
import useSWR from "swr";
import Widget from "../widget";
import Block from "../block";
import { formatApiUrl } from "utils/api-helpers";
export default function Npm({ service }) {
const config = service.widget;
const { data: infoData, error: infoError } = useSWR(formatApiUrl(config, "nginx/proxy-hosts"));
if (infoError) {
return <Widget error="NGINX Proxy Manager API Error" />;
}
if (!infoData) {
return (
<Widget>
<Block label="Enabled" />
<Block label="Disabled" />
<Block label="Total" />
</Widget>
);
}
const enabled = infoData.filter((c) => c.enabled === 1).length;
const disabled = infoData.filter((c) => c.enabled === 0).length;
const total = infoData.length;
return (
<Widget>
<Block label="Enabled" value={enabled} />
<Block label="Disabled" value={disabled} />
<Block label="Total" value={total} />
</Widget>
);
}

View File

@@ -1,35 +0,0 @@
import useSWR from "swr";
import Widget from "../widget";
import Block from "../block";
import { formatApiUrl } from "utils/api-helpers";
import { formatBytes } from "utils/stats-helpers";
export default function Nzbget({ service }) {
const config = service.widget;
const { data: statusData, error: statusError } = useSWR(formatApiUrl(config, "status"));
if (statusError) {
return <Widget error="Nzbget API Error" />;
}
if (!statusData) {
return (
<Widget>
<Block label="Rate" />
<Block label="Remaining" />
<Block label="Downloaded" />
</Widget>
);
}
return (
<Widget>
<Block label="Rate" value={`${formatBytes(statusData.DownloadRate)}/s`} />
<Block label="Remaining" value={`${Math.round((statusData.RemainingSizeMB / 1024) * 100) / 100} GB`} />
<Block label="Downloaded" value={`${Math.round((statusData.DownloadedSizeMB / 1024) * 100) / 100} GB`} />
</Widget>
);
}

View File

@@ -1,34 +0,0 @@
import useSWR from "swr";
import Widget from "../widget";
import Block from "../block";
import { formatApiUrl } from "utils/api-helpers";
export default function Ombi({ service }) {
const config = service.widget;
const { data: statsData, error: statsError } = useSWR(formatApiUrl(config, `Request/count`));
if (statsError) {
return <Widget error="Ombi API Error" />;
}
if (!statsData) {
return (
<Widget>
<Block label="Pending" />
<Block label="Approved" />
<Block label="Available" />
</Widget>
);
}
return (
<Widget>
<Block label="Pending" value={statsData.pending} />
<Block label="Approved" value={statsData.approved} />
<Block label="Available" value={statsData.available} />
</Widget>
);
}

View File

@@ -1,34 +0,0 @@
import useSWR from "swr";
import Widget from "../widget";
import Block from "../block";
import { formatApiUrl } from "utils/api-helpers";
export default function Pihole({ service }) {
const config = service.widget;
const { data: piholeData, error: piholeError } = useSWR(formatApiUrl(config, "api.php"));
if (piholeError) {
return <Widget error="PiHole API Error" />;
}
if (!piholeData) {
return (
<Widget>
<Block label="Queries" />
<Block label="Blocked" />
<Block label="Gravity" />
</Widget>
);
}
return (
<Widget>
<Block label="Queries" value={piholeData.dns_queries_today.toLocaleString()} />
<Block label="Blocked" value={piholeData.ads_blocked_today.toLocaleString()} />
<Block label="Gravity" value={piholeData.domains_being_blocked.toLocaleString()} />
</Widget>
);
}

View File

@@ -1,42 +0,0 @@
import useSWR from "swr";
import Widget from "../widget";
import Block from "../block";
import { formatApiUrl } from "utils/api-helpers";
export default function Portainer({ service }) {
const config = service.widget;
const { data: containersData, error: containersError } = useSWR(formatApiUrl(config, `docker/containers/json?all=1`));
if (containersError) {
return <Widget error="Portainer API Error" />;
}
if (!containersData) {
return (
<Widget>
<Block label="Running" />
<Block label="Stopped" />
<Block label="Total" />
</Widget>
);
}
if (containersData.error) {
return <Widget error="Portainer API Error" />;
}
const running = containersData.filter((c) => c.State === "running").length;
const stopped = containersData.filter((c) => c.State === "exited").length;
const total = containersData.length;
return (
<Widget>
<Block label="Running" value={running} />
<Block label="Stopped" value={stopped} />
<Block label="Total" value={total} />
</Widget>
);
}

View File

@@ -1,38 +0,0 @@
import useSWR from "swr";
import Widget from "../widget";
import Block from "../block";
import { formatApiUrl } from "utils/api-helpers";
export default function Radarr({ service }) {
const config = service.widget;
const { data: moviesData, error: moviesError } = useSWR(formatApiUrl(config, "movie"));
const { data: queuedData, error: queuedError } = useSWR(formatApiUrl(config, "queue/status"));
if (moviesError || queuedError) {
return <Widget error="Radarr API Error" />;
}
if (!moviesData || !queuedData) {
return (
<Widget>
<Block label="Wanted" />
<Block label="Queued" />
<Block label="Movies" />
</Widget>
);
}
const wanted = moviesData.filter((movie) => movie.isAvailable === false);
const have = moviesData.filter((movie) => movie.isAvailable === true);
return (
<Widget>
<Block label="Wanted" value={wanted.length} />
<Block label="Queued" value={queuedData.totalCount} />
<Block label="Movies" value={have.length} />
</Widget>
);
}

View File

@@ -1,45 +0,0 @@
import useSWR from "swr";
import Widget from "../widget";
import Block from "../block";
import { formatApiUrl } from "utils/api-helpers";
import { formatBytes } from "utils/stats-helpers";
export default function Rutorrent({ service }) {
const config = service.widget;
const { data: statusData, error: statusError } = useSWR(formatApiUrl(config));
if (statusError) {
return <Widget error="Nzbget API Error" />;
}
if (!statusData) {
return (
<Widget>
<Block label="Active" />
<Block label="Upload" />
<Block label="Download" />
</Widget>
);
}
const upload = statusData.reduce((acc, torrent) => {
return acc + parseInt(torrent["d.get_up_rate"]);
}, 0);
const download = statusData.reduce((acc, torrent) => {
return acc + parseInt(torrent["d.get_down_rate"]);
}, 0);
const active = statusData.filter((torrent) => torrent["d.get_state"] === "1");
return (
<Widget>
<Block label="Active" value={active.length} />
<Block label="Upload" value={`${formatBytes(upload)}/s`} />
<Block label="Download" value={`${formatBytes(download)}/s`} />
</Widget>
);
}

View File

@@ -1,36 +0,0 @@
import useSWR from "swr";
import Widget from "../widget";
import Block from "../block";
import { formatApiUrl } from "utils/api-helpers";
export default function Sonarr({ service }) {
const config = service.widget;
const { data: wantedData, error: wantedError } = useSWR(formatApiUrl(config, "wanted/missing"));
const { data: queuedData, error: queuedError } = useSWR(formatApiUrl(config, "queue"));
const { data: seriesData, error: seriesError } = useSWR(formatApiUrl(config, "series"));
if (wantedError || queuedError || seriesError) {
return <Widget error="Sonar API Error" />;
}
if (!wantedData || !queuedData || !seriesData) {
return (
<Widget>
<Block label="Wanted" />
<Block label="Queued" />
<Block label="Series" />
</Widget>
);
}
return (
<Widget>
<Block label="Wanted" value={wantedData.totalRecords} />
<Block label="Queued" value={queuedData.totalRecords} />
<Block label="Series" value={seriesData.length} />
</Widget>
);
}

View File

@@ -1,35 +0,0 @@
import useSWR from "swr";
import Widget from "../widget";
import Block from "../block";
import { formatBits } from "utils/stats-helpers";
import { formatApiUrl } from "utils/api-helpers";
export default function Speedtest({ service }) {
const config = service.widget;
const { data: speedtestData, error: speedtestError } = useSWR(formatApiUrl(config, "speedtest/latest"));
if (speedtestError) {
return <Widget error="Speedtest API Error" />;
}
if (!speedtestData) {
return (
<Widget>
<Block label="Download" />
<Block label="Upload" />
<Block label="Ping" />
</Widget>
);
}
return (
<Widget>
<Block label="Download" value={`${formatBits(speedtestData.data.download * 1024 * 1024, 0)}ps`} />
<Block label="Upload" value={`${formatBits(speedtestData.data.upload * 1024 * 1024, 0)}ps`} />
<Block label="Ping" value={`${speedtestData.data.ping} ms`} />
</Widget>
);
}

View File

@@ -1,37 +0,0 @@
import useSWR from "swr";
import Widget from "../widget";
import Block from "../block";
import { formatApiUrl } from "utils/api-helpers";
export default function Tautulli({ service }) {
const config = service.widget;
const { data: statsData, error: statsError } = useSWR(formatApiUrl(config, "get_activity"));
if (statsError) {
return <Widget error="Tautulli API Error" />;
}
if (!statsData) {
return (
<Widget>
<Block label="Playing" />
<Block label="Transcoding" />
<Block label="Bitrate" />
</Widget>
);
}
const data = statsData.response.data;
return (
<Widget>
<Block label="Playing" value={data.stream_count} />
<Block label="Transcoding" value={data.stream_count_transcode} />
{/* We divide by 1000 here because thats how Tautulli reports it on its own dashboard */}
<Block label="Bitrate" value={`${Math.round((data.total_bandwidth / 1000) * 100) / 100} Mbps`} />
</Widget>
);
}

View File

@@ -1,34 +0,0 @@
import useSWR from "swr";
import Widget from "../widget";
import Block from "../block";
import { formatApiUrl } from "utils/api-helpers";
export default function Traefik({ service }) {
const config = service.widget;
const { data: traefikData, error: traefikError } = useSWR(formatApiUrl(config, "overview"));
if (traefikError) {
return <Widget error="Traefik API Error" />;
}
if (!traefikData) {
return (
<Widget>
<Block label="Routers" />
<Block label="Services" />
<Block label="Middleware" />
</Widget>
);
}
return (
<Widget>
<Block label="Routers" value={traefikData.http.routers.total} />
<Block label="Services" value={traefikData.http.services.total} />
<Block label="Middleware" value={traefikData.http.middlewares.total} />
</Widget>
);
}

View File

@@ -1,11 +0,0 @@
export default function Widget({ error = false, children }) {
if (error) {
return (
<div className="bg-theme-200/50 dark:bg-theme-900/20 rounded m-1 flex-1 flex flex-col items-center justify-center p-1">
<div className="font-thin text-sm">{error}</div>
</div>
);
}
return <div className="flex flex-row w-full">{children}</div>;
}

View File

@@ -0,0 +1,81 @@
import { useContext, Fragment } from "react";
import { IoColorPalette } from "react-icons/io5";
import { Popover, Transition } from "@headlessui/react";
import classNames from "classnames";
import { ColorContext } from "utils/contexts/color";
const colors = [
"slate",
"gray",
"zinc",
"neutral",
"stone",
"amber",
"yellow",
"lime",
"green",
"emerald",
"teal",
"cyan",
"sky",
"blue",
"indigo",
"violet",
"purple",
"fuchsia",
"pink",
"rose",
"red",
"white",
];
export default function ColorToggle() {
const { color: active, setColor } = useContext(ColorContext);
if (!active) {
return null;
}
return (
<div className="w-full self-center">
<Popover className="relative flex items-center">
<Popover.Button className="outline-none">
<IoColorPalette
className="h-5 w-5 text-theme-800 dark:text-theme-200 transition duration-150 ease-in-out"
aria-hidden="true"
/>
<span className="sr-only">Change color</span>
</Popover.Button>
<Transition
as={Fragment}
enter="transition ease-out duration-200"
enterFrom="opacity-0 translate-y-1"
enterTo="opacity-100 translate-y-0"
leave="transition ease-in duration-150"
leaveFrom="opacity-100 translate-y-0"
leaveTo="opacity-0 translate-y-1"
>
<Popover.Panel className="absolute -top-[75px] left-0">
<div className="rounded-md shadow-lg ring-1 ring-black ring-opacity-5 w-[85vw] sm:w-full">
<div className="relative grid gap-2 p-2 grid-cols-11 bg-white/50 dark:bg-white/10 shadow-black/10 dark:shadow-black/20 rounded-md shadow-md">
{colors.map((color) => (
<button type="button" onClick={() => setColor(color)} key={color}>
<div
title={color}
className={classNames(
active === color ? "border-2" : "border-0",
`rounded-md w-5 h-5 border-black/50 dark:border-white/50 theme-${color} bg-theme-400`
)}
/>
<span className="sr-only">{color}</span>
</button>
))}
</div>
</div>
</Popover.Panel>
</Transition>
</Popover>
</div>
);
}

View File

@@ -0,0 +1,17 @@
import { MdRefresh } from "react-icons/md";
export default function Revalidate() {
const revalidate = () => {
fetch("/api/revalidate").then((res) => {
if (res.ok) {
window.location.reload();
}
});
};
return (
<div className="rounded-full flex align-middle self-center mr-3">
<MdRefresh onClick={() => revalidate()} className="text-theme-800 dark:text-theme-200 w-6 h-6 cursor-pointer" />
</div>
);
}

View File

@@ -1,12 +1,7 @@
import { useContext } from "react";
import {
MdDarkMode,
MdLightMode,
MdToggleOff,
MdToggleOn,
} from "react-icons/md";
import { MdDarkMode, MdLightMode, MdToggleOff, MdToggleOn } from "react-icons/md";
import { ThemeContext } from "utils/theme-context";
import { ThemeContext } from "utils/contexts/theme";
export default function ThemeToggle() {
const { theme, setTheme } = useContext(ThemeContext);

View File

@@ -0,0 +1,51 @@
import { useTranslation } from "next-i18next";
import useSWR from "swr";
import { compareVersions } from "compare-versions";
import { MdNewReleases } from "react-icons/md";
import cachedFetch from "utils/proxy/cached-fetch";
export default function Version() {
const { t, i18n } = useTranslation();
const buildTime = process.env.NEXT_PUBLIC_BUILDTIME ?? new Date().toISOString();
const revision = process.env.NEXT_PUBLIC_REVISION ?? "dev";
const version = process.env.NEXT_PUBLIC_VERSION ?? "dev";
const cachedFetcher = (resource) => cachedFetch(resource, 5).then((res) => res.json());
const { data: releaseData } = useSWR("https://api.github.com/repos/benphelps/homepage/releases", cachedFetcher);
// use Intl.DateTimeFormat to format the date
const formatDate = (date) => {
const options = {
year: "numeric",
month: "short",
day: "numeric",
};
return new Intl.DateTimeFormat(i18n.language, options).format(new Date(date));
};
const latestRelease = releaseData?.[0];
return (
<div className="flex flex-row items-center">
<span className="text-xs text-theme-500 dark:text-theme-400">
{version} ({revision.substring(0, 7)}, {formatDate(buildTime)})
</span>
{version === "main" || version === "dev" || version === "nightly"
? null
: releaseData &&
compareVersions(latestRelease.tag_name, version) > 0 && (
<a
href={latestRelease.html_url}
target="_blank"
rel="noopener noreferrer"
className="ml-2 text-xs text-theme-500 dark:text-theme-400 flex flex-row items-center"
>
<MdNewReleases className="mr-1" /> {t("Update Available")}
</a>
)}
</div>
);
}

View File

@@ -1,26 +0,0 @@
import WeatherApi from "components/widgets/weather/weather";
import OpenWeatherMap from "components/widgets/openweathermap/weather";
import Resources from "components/widgets/resources/resources";
import Search from "components/widgets/search/search";
const widgetMappings = {
weather: WeatherApi, // This key will be deprecated in the future
weatherapi: WeatherApi,
openweathermap: OpenWeatherMap,
resources: Resources,
search: Search,
};
export default function Widget({ widget }) {
const ServiceWidget = widgetMappings[widget.type];
if (ServiceWidget) {
return <ServiceWidget options={widget.options} />;
}
return (
<div className="flex-none flex flex-row items-center justify-center">
Missing <strong>{widget.type}</strong>
</div>
);
}

View File

@@ -0,0 +1,36 @@
import { useState, useEffect } from "react";
import { useTranslation } from "next-i18next";
const textSizes = {
"4xl": "text-4xl",
"3xl": "text-3xl",
"2xl": "text-2xl",
xl: "text-xl",
lg: "text-lg",
md: "text-md",
sm: "text-sm",
xs: "text-xs",
};
export default function DateTime({ options }) {
const { text_size: textSize, format } = options;
const { i18n } = useTranslation();
const [date, setDate] = useState(new Date());
useEffect(() => {
const interval = setInterval(() => {
setDate(new Date());
}, 1000);
return () => clearInterval(interval);
}, [setDate]);
const dateFormat = new Intl.DateTimeFormat(i18n.language, { ...format });
return (
<div className="flex flex-row items-center grow justify-end">
<span className={`text-theme-800 dark:text-theme-200 ${textSizes[textSize || "lg"]}`}>
{dateFormat.format(date)}
</span>
</div>
);
}

View File

@@ -0,0 +1,22 @@
const textSizes = {
"4xl": "text-4xl",
"3xl": "text-3xl",
"2xl": "text-2xl",
xl: "text-xl",
lg: "text-lg",
md: "text-md",
sm: "text-sm",
xs: "text-xs",
};
export default function Greeting({ options }) {
if (options.text) {
return (
<div className="flex flex-row items-center justify-start">
<span className={`text-theme-800 dark:text-theme-200 ${textSizes[options.text_size || "xl"]}`}>
{options.text}
</span>
</div>
);
}
}

View File

@@ -1,7 +1,7 @@
import mapIcon from "utils/owm-condition-map";
import mapIcon from "utils/weather/owm-condition-map";
export default function Icon({ condition, timeOfDay }) {
const Icon = mapIcon(condition, timeOfDay);
const IconComponent = mapIcon(condition, timeOfDay);
return <Icon className="w-10 h-10 text-theme-800 dark:text-theme-200"></Icon>;
return <IconComponent className="w-10 h-10 text-theme-800 dark:text-theme-200" />;
}

View File

@@ -1,22 +1,28 @@
import useSWR from "swr";
import { useState } from "react";
import { BiError } from "react-icons/bi";
import { WiCloudDown } from "react-icons/wi";
import { MdLocationDisabled, MdLocationSearching } from "react-icons/md";
import { useTranslation } from "next-i18next";
import Icon from "./icon";
export default function OpenWeatherMap({ options }) {
function Widget({ options }) {
const { t, i18n } = useTranslation();
const { data, error } = useSWR(
`/api/widgets/openweathermap?lat=${options.latitude}&lon=${options.longitude}&apiKey=${options.apiKey}&duration=${options.cache}&units=${options.units}`
`/api/widgets/openweathermap?${new URLSearchParams({ lang: i18n.language, ...options }).toString()}`
);
if (error || data?.cod == 401) {
if (error || data?.cod === 401 || data?.error) {
return (
<div className="flex flex-col">
<div className="flex flex-col justify-center first:ml-0 ml-4">
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
<BiError className="w-8 h-8 text-theme-800 dark:text-theme-200" />
<div className="flex flex-col ml-3 text-left">
<span className="text-theme-800 dark:text-theme-200 text-sm">API</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">Error</span>
<span className="text-theme-800 dark:text-theme-200 text-sm">{t("widget.api_error")}</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">-</span>
</div>
</div>
</div>
@@ -25,15 +31,25 @@ export default function OpenWeatherMap({ options }) {
}
if (!data) {
return <div className="flex flex-row items-center"></div>;
return (
<div className="flex flex-col justify-center first:ml-0 ml-4">
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
<WiCloudDown className="w-8 h-8 text-theme-800 dark:text-theme-200" />
</div>
<div className="flex flex-col ml-3 text-left">
<span className="text-theme-800 dark:text-theme-200 text-sm">{t("weather.updating")}</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">{t("weather.wait")}</span>
</div>
</div>
</div>
);
}
if (data.error) {
return <div className="flex flex-row items-center"></div>;
}
const unit = options.units === "metric" ? "celsius" : "fahrenheit";
return (
<div className="flex flex-col justify-center">
<div className="flex flex-col justify-center first:ml-0 ml-4">
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
<Icon
@@ -44,13 +60,65 @@ export default function OpenWeatherMap({ options }) {
<div className="flex flex-col ml-3 text-left">
<span className="text-theme-800 dark:text-theme-200 text-sm">
{options.label && `${options.label}, `}
{data.main.temp.toFixed(1)}&deg;
</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">
{data.weather[0].description.charAt(0).toUpperCase() + data.weather[0].description.slice(1)}
{t("common.number", { value: data.main.temp, style: "unit", unit })}
</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">{data.weather[0].description}</span>
</div>
</div>
</div>
);
}
export default function OpenWeatherMap({ options }) {
const { t } = useTranslation();
const [location, setLocation] = useState(false);
const [requesting, setRequesting] = useState(false);
if (!location && options.latitude && options.longitude) {
setLocation({ latitude: options.latitude, longitude: options.longitude });
}
const requestLocation = () => {
setRequesting(true);
if (typeof window !== "undefined") {
navigator.geolocation.getCurrentPosition(
(position) => {
setLocation({ latitude: position.coords.latitude, longitude: position.coords.longitude });
setRequesting(false);
},
() => {
setRequesting(false);
},
{
enableHighAccuracy: true,
maximumAge: 1000 * 60 * 60 * 3,
timeout: 1000 * 30,
}
);
}
};
// if (!requesting && !location) requestLocation();
if (!location) {
return (
<button type="button" onClick={() => requestLocation()} className="flex flex-col justify-center first:ml-0 ml-4">
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
{requesting ? (
<MdLocationSearching className="w-6 h-6 text-theme-800 dark:text-theme-200 animate-pulse" />
) : (
<MdLocationDisabled className="w-6 h-6 text-theme-800 dark:text-theme-200" />
)}
</div>
<div className="flex flex-col ml-3 text-left">
<span className="text-theme-800 dark:text-theme-200 text-sm">{t("weather.current")}</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">{t("weather.allow")}</span>
</div>
</div>
</button>
);
}
return <Widget options={{ ...location, ...options }} />;
}

View File

@@ -1,19 +1,23 @@
import useSWR from "swr";
import { FiCpu } from "react-icons/fi";
import { BiError } from "react-icons/bi";
import { useTranslation } from "next-i18next";
import UsageBar from "./usage-bar";
export default function Cpu({ expanded }) {
const { t } = useTranslation();
export default function Cpu() {
const { data, error } = useSWR(`/api/widgets/resources?type=cpu`, {
refreshInterval: 1500,
});
if (error || data?.error) {
return (
<div className="flex-none flex flex-row items-center justify-center">
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
<BiError className="text-theme-800 dark:text-theme-200 w-5 h-5" />
<div className="flex flex-col ml-3 text-left font-mono">
<span className="text-theme-800 dark:text-theme-200 text-xs">Resources</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">Error</span>
<div className="flex flex-col ml-3 text-left">
<span className="text-theme-800 dark:text-theme-200 text-xs">{t("widget.api_error")}</span>
</div>
</div>
);
@@ -21,26 +25,54 @@ export default function Cpu() {
if (!data) {
return (
<div className="flex-none flex flex-row items-center justify-center">
<div className="flex-none flex flex-row items-center mr-3 py-1.5 animate-pulse">
<FiCpu className="text-theme-800 dark:text-theme-200 w-5 h-5" />
<div className="flex flex-col ml-3 text-left font-mono">
<span className="text-theme-800 dark:text-theme-200 text-xs">- Usage</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">- Load</span>
<div className="flex flex-col ml-3 text-left min-w-[85px]">
<div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">-</div>
<div className="pr-1">{t("docker.cpu")}</div>
</div>
{expanded && (
<div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">-</div>
<div className="pr-1">{t("resources.load")}</div>
</div>
)}
<UsageBar percent={100} />
</div>
</div>
);
}
const percent = data.cpu.usage;
return (
<div className="flex-none flex flex-row items-center justify-center">
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
<FiCpu className="text-theme-800 dark:text-theme-200 w-5 h-5" />
<div className="flex flex-col ml-3 text-left font-mono">
<span className="text-theme-800 dark:text-theme-200 text-xs">
<span className="whitespace-pre">{`${Math.round(data.cpu.usage)}%`.padEnd(3, " ")} Usage</span>
</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">
{`${(Math.round(data.cpu.load * 100) / 100).toFixed(1)}`.padEnd(3, " ")} Load
</span>
<div className="flex flex-col ml-3 text-left min-w-[85px]">
<div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">
{t("common.number", {
value: data.cpu.usage,
style: "unit",
unit: "percent",
maximumFractionDigits: 0,
})}
</div>
<div className="pr-1">{t("docker.cpu")}</div>
</div>
{expanded && (
<div className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">
{t("common.number", {
value: data.cpu.load,
maximumFractionDigits: 2,
})}
</div>
<div className="pr-1">{t("resources.load")}</div>
</div>
)}
<UsageBar percent={percent} />
</div>
</div>
);

View File

@@ -1,20 +1,23 @@
import useSWR from "swr";
import { FiHardDrive } from "react-icons/fi";
import { BiError } from "react-icons/bi";
import { formatBytes } from "utils/stats-helpers";
import { useTranslation } from "next-i18next";
import UsageBar from "./usage-bar";
export default function Disk({ options, expanded }) {
const { t } = useTranslation();
export default function Disk({ options }) {
const { data, error } = useSWR(`/api/widgets/resources?type=disk&target=${options.disk}`, {
refreshInterval: 1500,
});
if (error || data?.error) {
return (
<div className="flex-none flex flex-row items-center justify-center">
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
<BiError className="text-theme-800 dark:text-theme-200 w-5 h-5" />
<div className="flex flex-col ml-3 text-left font-mono">
<span className="text-theme-800 dark:text-theme-200 text-xs">Resources</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">Error</span>
<div className="flex flex-col ml-3 text-left">
<span className="text-theme-800 dark:text-theme-200 text-xs">{t("widget.api_error")}</span>
</div>
</div>
);
@@ -22,26 +25,42 @@ export default function Disk({ options }) {
if (!data) {
return (
<div className="flex-none flex flex-row items-center justify-center">
<div className="flex-none flex flex-row items-center mr-3 py-1.5 animate-pulse">
<FiHardDrive className="text-theme-800 dark:text-theme-200 w-5 h-5" />
<div className="flex flex-col ml-3 text-left font-mono">
<span className="text-theme-800 dark:text-theme-200 text-xs">- Free</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">- Used</span>
<div className="flex flex-col ml-3 text-left min-w-[85px]">
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">-</div>
<div className="pr-1">{t("resources.free")}</div>
</span>
{expanded && (
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">-</div>
<div className="pr-1">{t("resources.total")}</div>
</span>
)}
<UsageBar percent={100} />
</div>
</div>
);
}
const percent = Math.round((data.drive.usedGb / data.drive.totalGb) * 100);
return (
<div className="flex-none flex flex-row items-center justify-center">
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
<FiHardDrive className="text-theme-800 dark:text-theme-200 w-5 h-5" />
<div className="flex flex-col ml-3 text-left font-mono">
<span className="text-theme-800 dark:text-theme-200 text-xs">
{formatBytes(data.drive.freeGb * 1024 * 1024 * 1024)} Free
</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">
{formatBytes(data.drive.usedGb * 1024 * 1024 * 1024)} Used
<div className="flex flex-col ml-3 text-left min-w-[85px]">
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">{t("common.bytes", { value: data.drive.freeGb * 1024 * 1024 * 1024 })}</div>
<div className="pr-1">{t("resources.free")}</div>
</span>
{expanded && (
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">{t("common.bytes", { value: data.drive.totalGb * 1024 * 1024 * 1024 })}</div>
<div className="pr-1">{t("resources.total")}</div>
</span>
)}
<UsageBar percent={percent} />
</div>
</div>
);

View File

@@ -1,20 +1,23 @@
import useSWR from "swr";
import { FaMemory } from "react-icons/fa";
import { BiError } from "react-icons/bi";
import { formatBytes } from "utils/stats-helpers";
import { useTranslation } from "next-i18next";
import UsageBar from "./usage-bar";
export default function Memory({ expanded }) {
const { t } = useTranslation();
export default function Memory() {
const { data, error } = useSWR(`/api/widgets/resources?type=memory`, {
refreshInterval: 1500,
});
if (error || data?.error) {
return (
<div className="flex-none flex flex-row items-center justify-center">
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
<BiError className="text-theme-800 dark:text-theme-200 w-5 h-5" />
<div className="flex flex-col ml-3 text-left font-mono">
<span className="text-theme-800 dark:text-theme-200 text-xs">Resources</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">Error</span>
<div className="flex flex-col ml-3 text-left">
<span className="text-theme-800 dark:text-theme-200 text-xs">{t("widget.api_error")}</span>
</div>
</div>
);
@@ -22,26 +25,50 @@ export default function Memory() {
if (!data) {
return (
<div className="flex-none flex flex-row items-center justify-center">
<div className="flex-none flex flex-row items-center mr-3 py-1.5 animate-pulse">
<FaMemory className="text-theme-800 dark:text-theme-200 w-5 h-5" />
<div className="flex flex-col ml-3 text-left font-mono">
<span className="text-theme-800 dark:text-theme-200 text-xs">- GB Used</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">- GB Free</span>
<div className="flex flex-col ml-3 text-left min-w-[85px]">
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">-</div>
<div className="pr-1">{t("resources.free")}</div>
</span>
{expanded && (
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">-</div>
<div className="pr-1">{t("resources.total")}</div>
</span>
)}
<UsageBar percent={100} />
</div>
</div>
);
}
const percent = Math.round((data.memory.usedMemMb / data.memory.totalMemMb) * 100);
return (
<div className="flex-none flex flex-row items-center justify-center">
<div className="flex-none flex flex-row items-center mr-3 py-1.5">
<FaMemory className="text-theme-800 dark:text-theme-200 w-5 h-5" />
<div className="flex flex-col ml-3 text-left font-mono">
<span className="text-theme-800 dark:text-theme-200 text-xs">
{formatBytes(data.memory.usedMemMb * 1024 * 1024)} Used
</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">
{formatBytes(data.memory.freeMemMb * 1024 * 1024)} Free
<div className="flex flex-col ml-3 text-left min-w-[85px]">
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">
{t("common.bytes", { value: data.memory.freeMemMb * 1024 * 1024, maximumFractionDigits: 0, binary: true })}
</div>
<div className="pr-1">{t("resources.free")}</div>
</span>
{expanded && (
<span className="text-theme-800 dark:text-theme-200 text-xs flex flex-row justify-between">
<div className="pl-0.5">
{t("common.bytes", {
value: data.memory.totalMemMb * 1024 * 1024,
maximumFractionDigits: 0,
binary: true,
})}
</div>
<div className="pr-1">{t("resources.total")}</div>
</span>
)}
<UsageBar percent={percent} />
</div>
</div>
);

View File

@@ -3,20 +3,19 @@ import Cpu from "./cpu";
import Memory from "./memory";
export default function Resources({ options }) {
const { expanded } = options;
return (
<>
<div className="flex flex-col max-w:full basis-1/2 sm:basis-auto self-center">
<div className="flex flex-row space-x-4 self-center">
{options.cpu && <Cpu />}
{options.memory && <Memory />}
{options.disk && <Disk options={options} />}
</div>
{options.label && (
<div className="border-t-2 border-theme-800 dark:border-theme-200 mt-1 pt-1 text-center text-theme-800 dark:text-theme-200 text-xs">
{options.label}
</div>
)}
<div className="flex flex-col max-w:full sm:basis-auto self-center m-auto flex-wrap">
<div className="flex flex-row self-center flex-wrap justify-between">
{options.cpu && <Cpu expanded={expanded} />}
{options.memory && <Memory expanded={expanded} />}
{Array.isArray(options.disk)
? options.disk.map((disk) => <Disk key={disk} options={{ disk }} expanded={expanded} />)
: options.disk && <Disk options={options} expanded={expanded} />}
</div>
</>
{options.label && (
<div className="ml-6 pt-1 text-center text-theme-800 dark:text-theme-200 text-xs">{options.label}</div>
)}
</div>
);
}

View File

@@ -0,0 +1,12 @@
export default function UsageBar({ percent }) {
return (
<div className="mt-0.5 w-full bg-theme-800/30 rounded-full h-1 dark:bg-theme-200/20">
<div
className="bg-theme-800/70 h-1 rounded-full dark:bg-theme-200/50 transition-all duration-1000"
style={{
width: `${percent}%`,
}}
/>
</div>
);
}

View File

@@ -1,6 +1,7 @@
import { useState } from "react";
import { useTranslation } from "next-i18next";
import { FiSearch } from "react-icons/fi";
import { SiDuckduckgo, SiMicrosoftbing, SiGoogle } from "react-icons/si";
import { SiDuckduckgo, SiMicrosoftbing, SiGoogle, SiBaidu } from "react-icons/si";
const providers = {
google: {
@@ -18,6 +19,11 @@ const providers = {
url: "https://www.bing.com/search?q=",
icon: SiMicrosoftbing,
},
baidu: {
name: "Baidu",
url: "https://www.baidu.com/s?wd=",
icon: SiBaidu,
},
custom: {
name: "Custom",
url: false,
@@ -26,11 +32,13 @@ const providers = {
};
export default function Search({ options }) {
const { t } = useTranslation();
const provider = providers[options.provider];
const [query, setQuery] = useState("");
if (!provider) {
return <></>;
return null;
}
function handleSubmit(event) {
@@ -48,21 +56,37 @@ export default function Search({ options }) {
}
return (
<form className="flex-col relative h-8 my-4 min-w-full md:min-w-fit grow" onSubmit={handleSubmit}>
<div className="flex absolute inset-y-0 left-0 items-center pl-3 pointer-events-none w-full text-theme-800 dark:text-theme-200"></div>
<form className="flex-col relative h-8 my-4 min-w-full md:min-w-fit grow first:ml-0 ml-4" onSubmit={handleSubmit}>
<div className="flex absolute inset-y-0 left-0 items-center pl-3 pointer-events-none w-full text-theme-800 dark:text-white" />
<input
type="search"
autoFocus
className={`overflow-hidden w-full placeholder-theme-900 text-xs text-theme-900 bg-theme-50 rounded-md border border-theme-300 focus:ring-theme-500 focus:border-theme-500 dark:bg-theme-800 dark:border-theme-600 dark:placeholder-theme-400 dark:text-white dark:focus:ring-theme-500 dark:focus:border-theme-500 h-full`}
placeholder="Search..."
type="text"
className="
overflow-hidden w-full h-full rounded-md
text-xs text-theme-900 dark:text-white
placeholder-theme-900 dark:placeholder-white/80
bg-white/50 dark:bg-white/10
focus:ring-theme-500 dark:focus:ring-white/50
focus:border-theme-500 dark:focus:border-white/50
border border-theme-300 dark:border-theme-200/50"
placeholder={t("search.placeholder")}
onChange={(s) => setQuery(s.currentTarget.value)}
required
autoCapitalize="off"
autoCorrect="off"
autoComplete="off"
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus={options.focus}
/>
<button
type="submit"
className="text-white absolute right-0.5 bottom-0.5 bg-theme-700 hover:bg-theme-800 border-1 focus:ring-2 focus:ring-theme-300 font-medium rounded-r-md text-sm px-4 py-2 dark:bg-theme-600 dark:hover:bg-theme-700 dark:focus:ring-theme-500"
className="
absolute right-0.5 bottom-0.5 rounded-r-md px-4 py-2 border-1
text-white font-medium text-sm
bg-theme-600/40 dark:bg-white/10
focus:ring-theme-500 dark:focus:ring-white/50"
>
<provider.icon className="text-theme-800 dark:text-theme-200 w-3 h-3" />
<provider.icon className="text-white w-3 h-3" />
<span className="sr-only">{t("search.search")}</span>
</button>
</form>
);

View File

@@ -1,7 +1,7 @@
import mapIcon from "utils/condition-map";
import mapIcon from "utils/weather/condition-map";
export default function Icon({ condition, timeOfDay }) {
const Icon = mapIcon(condition, timeOfDay);
const IconComponent = mapIcon(condition, timeOfDay);
return <Icon className="w-10 h-10 text-theme-800 dark:text-theme-200"></Icon>;
return <IconComponent className="w-10 h-10 text-theme-800 dark:text-theme-200" />;
}

View File

@@ -1,22 +1,28 @@
import useSWR from "swr";
import { useState } from "react";
import { BiError } from "react-icons/bi";
import { WiCloudDown } from "react-icons/wi";
import { MdLocationDisabled, MdLocationSearching } from "react-icons/md";
import { useTranslation } from "next-i18next";
import Icon from "./icon";
export default function WeatherApi({ options }) {
function Widget({ options }) {
const { t, i18n } = useTranslation();
const { data, error } = useSWR(
`/api/widgets/weather?lat=${options.latitude}&lon=${options.longitude}&apiKey=${options.apiKey}&duration=${options.cache}`
`/api/widgets/weather?${new URLSearchParams({ lang: i18n.language, ...options }).toString()}`
);
if (error) {
if (error || data?.error) {
return (
<div className="flex flex-col">
<div className="flex flex-col justify-center first:ml-0 ml-4">
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
<BiError className="w-8 h-8 text-theme-800 dark:text-theme-200" />
<div className="flex flex-col ml-3 text-left">
<span className="text-theme-800 dark:text-theme-200 text-sm">API</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">Error</span>
<span className="text-theme-800 dark:text-theme-200 text-sm">{t("widget.api_error")}</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">-</span>
</div>
</div>
</div>
@@ -25,15 +31,25 @@ export default function WeatherApi({ options }) {
}
if (!data) {
return <div className="flex flex-row items-center justify-end"></div>;
return (
<div className="flex flex-col justify-center first:ml-0 ml-4">
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
<WiCloudDown className="w-8 h-8 text-theme-800 dark:text-theme-200" />
</div>
<div className="flex flex-col ml-3 text-left">
<span className="text-theme-800 dark:text-theme-200 text-sm">{t("weather.updating")}</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">{t("weather.wait")}</span>
</div>
</div>
</div>
);
}
if (data.error) {
return <div className="flex flex-row items-center justify-end"></div>;
}
const unit = options.units === "metric" ? "celsius" : "fahrenheit";
return (
<div className="flex flex-col justify-center">
<div className="flex flex-col justify-center first:ml-0 ml-4">
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
<Icon condition={data.current.condition.code} timeOfDay={data.current.is_day ? "day" : "night"} />
@@ -41,7 +57,11 @@ export default function WeatherApi({ options }) {
<div className="flex flex-col ml-3 text-left">
<span className="text-theme-800 dark:text-theme-200 text-sm">
{options.label && `${options.label}, `}
{options.units === "metric" ? data.current.temp_c : data.current.temp_f}&deg;
{t("common.number", {
value: options.units === "metric" ? data.current.temp_c : data.current.temp_f,
style: "unit",
unit,
})}
</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">{data.current.condition.text}</span>
</div>
@@ -49,3 +69,57 @@ export default function WeatherApi({ options }) {
</div>
);
}
export default function WeatherApi({ options }) {
const { t } = useTranslation();
const [location, setLocation] = useState(false);
const [requesting, setRequesting] = useState(false);
if (!location && options.latitude && options.longitude) {
setLocation({ latitude: options.latitude, longitude: options.longitude });
}
const requestLocation = () => {
setRequesting(true);
if (typeof window !== "undefined") {
navigator.geolocation.getCurrentPosition(
(position) => {
setLocation({ latitude: position.coords.latitude, longitude: position.coords.longitude });
setRequesting(false);
},
() => {
setRequesting(false);
},
{
enableHighAccuracy: true,
maximumAge: 1000 * 60 * 60 * 3,
timeout: 1000 * 30,
}
);
}
};
// if (!requesting && !location) requestLocation();
if (!location) {
return (
<button type="button" onClick={() => requestLocation()} className="flex flex-col justify-center first:ml-0 ml-4">
<div className="flex flex-row items-center justify-end">
<div className="flex flex-col items-center">
{requesting ? (
<MdLocationSearching className="w-6 h-6 text-theme-800 dark:text-theme-200 animate-pulse" />
) : (
<MdLocationDisabled className="w-6 h-6 text-theme-800 dark:text-theme-200" />
)}
</div>
<div className="flex flex-col ml-3 text-left">
<span className="text-theme-800 dark:text-theme-200 text-sm">{t("weather.current")}</span>
<span className="text-theme-800 dark:text-theme-200 text-xs">{t("weather.allow")}</span>
</div>
</div>
</button>
);
}
return <Widget options={{ ...location, ...options }} />;
}

View File

@@ -0,0 +1,24 @@
import dynamic from "next/dynamic";
const widgetMappings = {
weatherapi: dynamic(() => import("components/widgets/weather/weather")),
openweathermap: dynamic(() => import("components/widgets/openweathermap/weather")),
resources: dynamic(() => import("components/widgets/resources/resources")),
search: dynamic(() => import("components/widgets/search/search")),
greeting: dynamic(() => import("components/widgets/greeting/greeting")),
datetime: dynamic(() => import("components/widgets/datetime/datetime")),
};
export default function Widget({ widget }) {
const InfoWidget = widgetMappings[widget.type];
if (InfoWidget) {
return <InfoWidget options={widget.options} />;
}
return (
<div className="flex-none flex flex-row items-center justify-center">
Missing <strong>{widget.type}</strong>
</div>
);
}

View File

@@ -1,18 +0,0 @@
import { SWRConfig } from "swr";
import "styles/globals.css";
import "styles/weather-icons.css";
import "styles/theme.css";
function MyApp({ Component, pageProps }) {
return (
<SWRConfig
value={{
fetcher: (resource, init) => fetch(resource, init).then((res) => res.json()),
}}
>
<Component {...pageProps} />
</SWRConfig>
);
}
export default MyApp;

32
src/pages/_app.jsx Normal file
View File

@@ -0,0 +1,32 @@
/* eslint-disable react/jsx-props-no-spreading */
import { SWRConfig } from "swr";
import { appWithTranslation } from "next-i18next";
import "styles/globals.css";
import "styles/theme.css";
import "styles/manrope.css";
import nextI18nextConfig from "../../next-i18next.config";
import { ColorProvider } from "utils/contexts/color";
import { ThemeProvider } from "utils/contexts/theme";
import { SettingsProvider } from "utils/contexts/settings";
function MyApp({ Component, pageProps }) {
return (
<SWRConfig
value={{
fetcher: (resource, init) => fetch(resource, init).then((res) => res.json()),
}}
>
<ColorProvider>
<ThemeProvider>
<SettingsProvider>
<Component {...pageProps} />
</SettingsProvider>
</ThemeProvider>
</ColorProvider>
</SWRConfig>
);
}
export default appWithTranslation(MyApp, nextI18nextConfig);

View File

@@ -1,20 +0,0 @@
import { Html, Head, Main, NextScript } from "next/document";
export default function Document() {
return (
<Html>
<Head>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="true" />
<link
href="https://fonts.googleapis.com/css2?family=Poppins:ital,wght@0,300;0,400;0,500;0,600;1,300;1,400;1,500&display=swap"
rel="stylesheet"
/>
</Head>
<body className="w-full h-full bg-theme-50 dark:bg-theme-800 transition duration-150 ease-in-out">
<Main />
<NextScript />
</body>
</Html>
);
}

Some files were not shown because too many files have changed in this diff Show More