Compare commits

...

138 Commits

Author SHA1 Message Date
community-scripts-pr-app[bot]
d617a49766 Update CHANGELOG.md (#7608)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-13 00:12:34 +00:00
community-scripts-pr-app[bot]
7c0d79c115 Update versions.json (#7607)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-13 02:12:13 +02:00
community-scripts-pr-app[bot]
0d4a508543 Update CHANGELOG.md (#7606)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-12 19:28:52 +00:00
CanbiZ
f979dd2277 [core]: add fallback if mariadb upstream unreachable (#7599) 2025-09-12 21:28:28 +02:00
community-scripts-pr-app[bot]
87de220511 Update CHANGELOG.md (#7605)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-12 18:49:50 +00:00
Slaviša Arežina
481e70b0aa Increase resources (#7600) 2025-09-12 20:49:25 +02:00
community-scripts-pr-app[bot]
6c3a16e579 Update CHANGELOG.md (#7604)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-12 18:21:43 +00:00
community-scripts-pr-app[bot]
394f91c994 Update CHANGELOG.md (#7603)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-12 18:21:19 +00:00
community-scripts-pr-app[bot]
63a268d6c5 Update date in json (#7602)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2025-09-12 18:21:16 +00:00
push-app-to-main[bot]
9ee6e23a59 Stylus (#7588)
* 'Add new script'

* Update stylus.sh

* Update stylus-install.sh

* Update stylus.json

* fix stylus update

* cleanup

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com>
Co-authored-by: CanbiZ <47820557+MickLesk@users.noreply.github.com>
2025-09-12 20:20:58 +02:00
community-scripts-pr-app[bot]
eceb1cd53c Update CHANGELOG.md (#7601)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-12 18:20:30 +00:00
rell3k
719c55655d Update post-pve-install.sh (#7598)
Create directory if it doesn't exist.
2025-09-12 20:20:06 +02:00
community-scripts-pr-app[bot]
aeb15c7ea1 Update CHANGELOG.md (#7592)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-12 12:08:11 +00:00
community-scripts-pr-app[bot]
0c7a366782 Update date in json (#7591)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2025-09-12 12:07:51 +00:00
push-app-to-main[bot]
93a3a572d4 uhf (#7589)
* 'Add new script'

* Update uhf.sh

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: Slaviša Arežina <58952836+tremor021@users.noreply.github.com>
2025-09-12 14:07:30 +02:00
community-scripts-pr-app[bot]
8b2645a529 Update versions.json (#7590)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-12 14:06:23 +02:00
community-scripts-pr-app[bot]
b72e132699 Update CHANGELOG.md (#7587)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-12 10:30:23 +00:00
webmogul1
f4df8e2ccc Update openwebui.sh (#7582) 2025-09-12 12:30:00 +02:00
community-scripts-pr-app[bot]
f03f004226 Update CHANGELOG.md (#7584)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-12 00:13:59 +00:00
community-scripts-pr-app[bot]
b13c840bda Update versions.json (#7583)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-12 02:13:39 +02:00
community-scripts-pr-app[bot]
ce90647bda Update CHANGELOG.md (#7581)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-11 19:04:00 +00:00
push-app-to-main[bot]
164e487090 telegraf (#7576) 2025-09-11 21:03:34 +02:00
community-scripts-pr-app[bot]
a4660adedd Update CHANGELOG.md (#7580)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-11 16:47:46 +00:00
Siyuan Gao
9352eec854 Fix frontend url (#7578) 2025-09-11 18:47:21 +02:00
community-scripts-pr-app[bot]
4478f8f6e0 Update versions.json (#7574)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-11 14:05:43 +02:00
community-scripts-pr-app[bot]
d69cbcd941 Update CHANGELOG.md (#7573)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-11 12:01:38 +00:00
Bram Suurd
affcfd06cf Add margin-bottom to Most Viewed Scripts header (#7572) 2025-09-11 14:01:14 +02:00
community-scripts-pr-app[bot]
b94b088c19 Update CHANGELOG.md (#7571)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-11 11:15:36 +00:00
dvino
5385382a88 post-pve-install mobile nag fix (#7567) 2025-09-11 13:15:07 +02:00
community-scripts-pr-app[bot]
d06ad37a22 Update CHANGELOG.md (#7570)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-11 10:44:37 +00:00
Slaviša Arežina
72c7d4199b Sort functions (#7569) 2025-09-11 12:44:13 +02:00
community-scripts-pr-app[bot]
2e75ced83f Update CHANGELOG.md (#7568)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-11 09:49:40 +00:00
Burrito
9a28ce0263 alpine-install: switch to using GitHub to fetch tools when using GitHub (#7566) 2025-09-11 11:49:14 +02:00
community-scripts-pr-app[bot]
9ed2507bdc Update CHANGELOG.md (#7564)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-11 00:12:39 +00:00
community-scripts-pr-app[bot]
c617870c2b Update versions.json (#7563)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-11 02:12:16 +02:00
community-scripts-pr-app[bot]
eb71d21ea3 Update CHANGELOG.md (#7559)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-10 17:56:21 +00:00
Chris
762452b2b3 Palmr: fix #7556 (#7558) 2025-09-10 19:55:54 +02:00
community-scripts-pr-app[bot]
31cd3e3119 Update CHANGELOG.md (#7557)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-10 16:14:06 +00:00
Tobias
c25dba9212 Remove Pingvin Share (#7553) 2025-09-10 18:13:40 +02:00
community-scripts-pr-app[bot]
52cefe4a00 Update CHANGELOG.md (#7555)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-10 14:22:22 +00:00
Chris
7b8fcab242 Wizarr: fix #7545 (#7552)
- ensure to delete contents of migrations/versions folder prior to flask
operations
- use `--frozen` for uv operations rather than locking
2025-09-10 16:21:52 +02:00
community-scripts-pr-app[bot]
b733e8b5ea Update CHANGELOG.md (#7554)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-10 14:20:55 +00:00
CanbiZ
4a4e67a3cf Refactor: audiobookshelf (#7538)
Increase default disk size from 4GB to 5GB and mark audiobookshelf as updateable in JSON. Update install script to explicitly install ffmpeg and set FFMPEG/FFPROBE paths in /etc/default/audiobookshelf. Revise update logic to use /etc/default/audiobookshelf as installation check and perform apt updates/upgrades.
2025-09-10 16:20:26 +02:00
community-scripts-pr-app[bot]
b00feea00d Update CHANGELOG.md (#7549)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-10 12:41:46 +00:00
CanbiZ
c250cec418 Refactor: Blocky (#7537)
Updated blocky.sh to improve update logic, including backup and restore of config, service management, and release fetching. Refactored blocky-install.sh to use fetch_and_deploy_gh_release for installation, removing manual release handling. Set Blocky as updateable in blocky.json.
2025-09-10 14:41:25 +02:00
community-scripts-pr-app[bot]
a0af0f5196 Update CHANGELOG.md (#7548)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-10 12:38:50 +00:00
Chris
2f0b6e10ab Palmr v3.2.1-beta (#7526)
- Add CUSTOM_PATH env var with comment
- Update JSON: add note about new env var
- Update JSON: remove warning about RAM - now advisable to leave as-is
2025-09-10 14:38:19 +02:00
community-scripts-pr-app[bot]
a41364d91d Update CHANGELOG.md (#7547)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-10 12:37:41 +00:00
CanbiZ
e580a5d9c1 Add external installer warnings and user confirmation (#7539)
Added explicit warnings and user confirmation prompts to install scripts that run external installers from third-party sources. Updated JSON metadata to remove warning notes about external sources, as the scripts now handle user notification and consent directly. This improves transparency and user safety during installation.
2025-09-10 14:37:12 +02:00
community-scripts-pr-app[bot]
9d059b2a13 Update versions.json (#7546)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-10 14:05:11 +02:00
community-scripts-pr-app[bot]
6e32eebdf0 Update CHANGELOG.md (#7544)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-10 11:41:03 +00:00
community-scripts-pr-app[bot]
7f3ebd4296 Update CHANGELOG.md (#7543)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-10 11:40:49 +00:00
community-scripts-pr-app[bot]
0c4d55bd78 Update date in json (#7542)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2025-09-10 11:40:41 +00:00
push-app-to-main[bot]
8f05be3f6b Autocaliweb (#7515)
* 'Add new script'

* cleanup

* Update logo URL in autocaliweb.json

---------

Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
Co-authored-by: Tobias <96661824+CrazyWolf13@users.noreply.github.com>
Co-authored-by: CanbiZ <47820557+MickLesk@users.noreply.github.com>
2025-09-10 13:40:15 +02:00
community-scripts-pr-app[bot]
e06cd4b28c Update CHANGELOG.md (#7541)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-10 11:00:42 +00:00
CanbiZ
b9242b3232 fix: pmg - split no-nag script into separate config files (#7540) 2025-09-10 13:00:19 +02:00
community-scripts-pr-app[bot]
63f6d772ea Update CHANGELOG.md (#7536)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-10 07:44:30 +00:00
CanbiZ
652df1f370 Set updateable to true for all JSON app configs (#7534) 2025-09-10 09:44:09 +02:00
community-scripts-pr-app[bot]
f4b5baf308 Update CHANGELOG.md (#7535)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-10 07:15:02 +00:00
Michel Roegl-Brunner
cc36fd5434 Booklore: Add Bookdrop location to .env (#7533) 2025-09-10 09:14:41 +02:00
CanbiZ
3e182978ad Improve npmplus credential retrieval and messaging (#7532)
* Improve npmplus credential retrieval and messaging

Enhanced the install script to attempt live log monitoring for credentials if not found initially, and updated the info message in npmplus.json to guide users to check docker logs if the credentials file is missing.

* Update npmplus.json

* Change updateable status to true in npmplus.json
2025-09-10 09:14:15 +02:00
community-scripts-pr-app[bot]
e7adf1a9b5 Update CHANGELOG.md (#7529)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-10 00:12:25 +00:00
community-scripts-pr-app[bot]
36fb86eaf8 Update versions.json (#7528)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-10 02:12:00 +02:00
community-scripts-pr-app[bot]
495c47224e Update CHANGELOG.md (#7525)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-09 21:23:22 +00:00
community-scripts-pr-app[bot]
7af71384b4 Update CHANGELOG.md (#7524)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-09 21:18:08 +00:00
dependabot[bot]
e318152ee3 Bump vite from 7.0.0 to 7.1.5 in /frontend (#7522)
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.0.0 to 7.1.5.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v7.1.5/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 7.1.5
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2025-09-09 23:17:43 +02:00
community-scripts-pr-app[bot]
17dc7c90a1 Update CHANGELOG.md (#7521)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-09 20:35:29 +00:00
Chris
226a5bce8f Pulse: standardise install/update with Pulse repo script (#7519)
- revert the pulse => pulse-backend service name change
- remove message about older installs
- symlink pulse binary to /usr/local/bin
2025-09-09 22:35:04 +02:00
community-scripts-pr-app[bot]
ffd2ed01b9 Update CHANGELOG.md (#7518)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-09 17:13:00 +00:00
Chris
3348e2fff0 Tududi: v0.81 (#7517) 2025-09-09 19:12:27 +02:00
community-scripts-pr-app[bot]
def41f66f4 Update CHANGELOG.md (#7516)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-09 14:48:50 +00:00
Slaviša Arežina
02a1a732f8 WGDashboard: Revert back to old update method (#7500)
* Revert back to git clone

* Add git to sh
2025-09-09 16:48:12 +02:00
community-scripts-pr-app[bot]
2494af7e1c Update CHANGELOG.md (#7514)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-09 13:39:02 +00:00
CanbiZ
0c4711d99f Change category ID from 15 to 13 in swizzin.json (#7511) 2025-09-09 15:38:33 +02:00
community-scripts-pr-app[bot]
039f73a5ed Update versions.json (#7512)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-09 14:05:31 +02:00
CanbiZ
74b58d5b10 planka: fix copy issue 2025-09-09 11:40:59 +02:00
community-scripts-pr-app[bot]
61044104a2 Update CHANGELOG.md (#7510)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-09 09:25:29 +00:00
CanbiZ
fac612077a AdventureLog: remove folder during update process (#7507) 2025-09-09 11:24:58 +02:00
community-scripts-pr-app[bot]
135b3ff964 Update CHANGELOG.md (#7509)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-09 09:22:02 +00:00
Slaviša Arežina
393b853119 Fix backup and restore (#7505) 2025-09-09 11:21:38 +02:00
community-scripts-pr-app[bot]
6bb2938e34 Update CHANGELOG.md (#7503)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-09 07:52:08 +00:00
Slaviša Arežina
fbf16fd54d Fixes (#7502) 2025-09-09 09:51:38 +02:00
community-scripts-pr-app[bot]
d6d4fd034f Update CHANGELOG.md (#7501)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-09 07:28:55 +00:00
Bram Suurd
aa4999dac6 Refactor GitHubStarsButton to wrap in Link component for external navigation (#7492) 2025-09-09 09:28:32 +02:00
community-scripts-pr-app[bot]
b6c0b50e79 Update CHANGELOG.md (#7495)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-09 00:13:49 +00:00
community-scripts-pr-app[bot]
0f07f1927e Update versions.json (#7494)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-09 02:13:21 +02:00
community-scripts-pr-app[bot]
4493d86e51 Update CHANGELOG.md (#7490)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-08 19:06:13 +00:00
Chris
fbfeeeb88f Immich: bump to version 1.141.1 (#7418) 2025-09-08 21:05:50 +02:00
community-scripts-pr-app[bot]
2366111bba Update CHANGELOG.md (#7486)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-08 12:28:04 +00:00
CanbiZ
5fb42b87f1 CT's: fix missing variable declaration (actualBudget, openziti, umlautadaptarr) (#7483) 2025-09-08 14:27:40 +02:00
community-scripts-pr-app[bot]
500c35c58d Update CHANGELOG.md (#7484)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-08 12:18:24 +00:00
Tobias
ca3446c90e Change ExecStart to use index.js instead of index.mjs (#7482) 2025-09-08 14:18:04 +02:00
CanbiZ
4c3d42d5d1 fix verbose 2025-09-08 14:09:20 +02:00
CanbiZ
299a10efe8 Update build.func 2025-09-08 14:07:25 +02:00
community-scripts-pr-app[bot]
7adac2a342 Update versions.json (#7481)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-08 14:05:54 +02:00
community-scripts-pr-app[bot]
eb58b10d75 Update CHANGELOG.md (#7480)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-08 12:03:58 +00:00
CanbiZ
5e46d81c45 [core]: switch all base_settings to variables (#7479) 2025-09-08 14:03:34 +02:00
community-scripts-pr-app[bot]
2963926c45 Update CHANGELOG.md (#7478)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-08 10:50:01 +00:00
Bram Suurd
d9a0b863a8 Format numerical values in DataFetcher component for better readability (#7477) 2025-09-08 12:49:38 +02:00
community-scripts-pr-app[bot]
db6369f3c6 Update CHANGELOG.md (#7476)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-08 09:58:53 +00:00
Slaviša Arežina
d450e263f0 Update (#7473) 2025-09-08 11:58:29 +02:00
community-scripts-pr-app[bot]
462960d9bf Update CHANGELOG.md (#7472)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-08 06:42:51 +00:00
Bram Suurd
8ea4829e8a feat: enhance github stars button to be better looking and more compact (#7464)
* feat: enhance github stars button to be better looking and more compact to make mobile compatibility easier in the future

* feat: introduce a new Button component
2025-09-08 08:42:31 +02:00
community-scripts-pr-app[bot]
c5d23dc883 Update CHANGELOG.md (#7471)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-08 06:01:46 +00:00
Seb Guy
3dc973e4ac Update searxng-install.sh (#7469) 2025-09-08 08:01:26 +02:00
community-scripts-pr-app[bot]
751f488f9e Update CHANGELOG.md (#7467)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-08 00:12:50 +00:00
community-scripts-pr-app[bot]
0ed4363247 Update versions.json (#7466)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-08 02:12:28 +02:00
community-scripts-pr-app[bot]
e77612c27e Update CHANGELOG.md (#7461)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-07 19:19:11 +00:00
Tobias
59c8e214af Update ExecStart path for karakeep service (#7460) 2025-09-07 21:18:46 +02:00
community-scripts-pr-app[bot]
c790f03a6b Update versions.json (#7454)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-07 14:04:47 +02:00
community-scripts-pr-app[bot]
54d4d58b15 Update CHANGELOG.md (#7450)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-07 00:13:32 +00:00
community-scripts-pr-app[bot]
889a58c00e Update versions.json (#7449)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-07 02:13:05 +02:00
community-scripts-pr-app[bot]
e9a5d7587a Update CHANGELOG.md (#7448)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-06 22:05:03 +00:00
community-scripts-pr-app[bot]
6f84046741 Update CHANGELOG.md (#7447)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-06 22:04:44 +00:00
Ivan Penchev
ff96351db8 feat: added mobile ui subscription nag removal (#7164)
* feat: added mobile ui nag removal

* chore: remove my ansible comment
2025-09-07 00:04:38 +02:00
community-scripts-pr-app[bot]
1b632199b3 Update CHANGELOG.md (#7446)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-06 22:04:26 +00:00
community-scripts-pr-app[bot]
9fb02a93b4 Update date in json (#7445)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2025-09-06 22:04:23 +00:00
push-app-to-main[bot]
3aa56651d8 'Add new script' (#7442)
Co-authored-by: push-app-to-main[bot] <203845782+push-app-to-main[bot]@users.noreply.github.com>
2025-09-07 00:04:06 +02:00
community-scripts-pr-app[bot]
17d4c59041 Update versions.json (#7441)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-06 14:04:48 +02:00
community-scripts-pr-app[bot]
2bfb35779b Update CHANGELOG.md (#7437)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-06 09:03:16 +00:00
EtlamGit
83b93390c9 use debian source for direct installation of MQTT (#7423)
as newer Debian contains mosquitto in sources, directly install it without adding extra repository
2025-09-06 11:02:54 +02:00
community-scripts-pr-app[bot]
7ce47ad414 Update CHANGELOG.md (#7433)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-06 06:36:37 +00:00
community-scripts-pr-app[bot]
646e0c31f4 Update CHANGELOG.md (#7432)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-06 06:36:20 +00:00
community-scripts-pr-app[bot]
0c7e200a94 Update date in json (#7431)
Co-authored-by: GitHub Actions <github-actions[bot]@users.noreply.github.com>
2025-09-06 06:36:18 +00:00
push-app-to-main[bot]
a9b02b3e9c 'Add new script' (#7414) 2025-09-06 08:36:01 +02:00
community-scripts-pr-app[bot]
b62adc2c5c Update CHANGELOG.md (#7430)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-06 06:35:57 +00:00
Austin
3438b046e5 MediaManager Configuration Path (#7408) 2025-09-06 08:35:40 +02:00
community-scripts-pr-app[bot]
cbd6d6d0f3 Update CHANGELOG.md (#7429)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-06 06:35:36 +00:00
Slaviša Arežina
cf6c429c57 Remove default creds (#7403) 2025-09-06 08:35:12 +02:00
community-scripts-pr-app[bot]
bbe71cbbb9 Update CHANGELOG.md (#7428)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-06 00:12:58 +00:00
community-scripts-pr-app[bot]
9b6a736c8c Update versions.json (#7427)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-06 02:12:30 +02:00
community-scripts-pr-app[bot]
c395ccc270 Update CHANGELOG.md (#7421)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-05 17:28:01 +00:00
Chris
3dd72e08e9 Pin version to 0.80 (#7420)
- a lot of changes in next version
2025-09-05 19:27:40 +02:00
community-scripts-pr-app[bot]
1d989bea73 Update versions.json (#7417)
Co-authored-by: GitHub Actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-05 14:05:32 +02:00
community-scripts-pr-app[bot]
f881b88344 Update CHANGELOG.md (#7411)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-05 06:07:57 +00:00
Slaviša Arežina
06dbad83ef AdventureLog: Update dependencies (#7404)
* Update adventurelog-install.sh

* Check and install memcached if not present

---------

Co-authored-by: CanbiZ <47820557+MickLesk@users.noreply.github.com>
2025-09-05 08:07:34 +02:00
community-scripts-pr-app[bot]
7ff966b042 Update CHANGELOG.md (#7410)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2025-09-05 05:24:44 +00:00
Bram Suurd
62264f37a6 refactor: Enhance ScriptAccordion and Sidebar components to support selectedCategory state (#7405)
* refactor: Enhance ScriptAccordion and Sidebar components to support selectedCategory state

* lint

* chore: Add ESLint configuration to ignore errors during builds in next.config.mjs
2025-09-05 07:24:19 +02:00
142 changed files with 5123 additions and 2448 deletions

View File

@@ -10,8 +10,191 @@
> [!CAUTION] > [!CAUTION]
Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes. Exercise vigilance regarding copycat or coat-tailing sites that seek to exploit the project's popularity for potentially malicious purposes.
## 2025-09-13
## 2025-09-12
### 🆕 New Scripts
- Stylus ([#7588](https://github.com/community-scripts/ProxmoxVE/pull/7588))
- UHF ([#7589](https://github.com/community-scripts/ProxmoxVE/pull/7589))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Tweak: post-pve-install: create folder if Not exist [@JVKeller](https://github.com/JVKeller) ([#7598](https://github.com/community-scripts/ProxmoxVE/pull/7598))
- Update openwebui.sh [@webmogul1](https://github.com/webmogul1) ([#7582](https://github.com/community-scripts/ProxmoxVE/pull/7582))
- #### ✨ New Features
- [core]: add fallback if mariadb upstream unreachable [@MickLesk](https://github.com/MickLesk) ([#7599](https://github.com/community-scripts/ProxmoxVE/pull/7599))
- ESPHome: Increase default disk size [@tremor021](https://github.com/tremor021) ([#7600](https://github.com/community-scripts/ProxmoxVE/pull/7600))
## 2025-09-11
### 🆕 New Scripts
- telegraf ([#7576](https://github.com/community-scripts/ProxmoxVE/pull/7576))
### 🚀 Updated Scripts
- [core] Sort tools.func functions alphabeticaly [@tremor021](https://github.com/tremor021) ([#7569](https://github.com/community-scripts/ProxmoxVE/pull/7569))
- mobile subscription nag fix [@dvino](https://github.com/dvino) ([#7567](https://github.com/community-scripts/ProxmoxVE/pull/7567))
- #### 🐞 Bug Fixes
- alpine-install: switch to using GitHub to fetch tools when using GitHub [@burritosoftware](https://github.com/burritosoftware) ([#7566](https://github.com/community-scripts/ProxmoxVE/pull/7566))
### 🌐 Website
- #### 🐞 Bug Fixes
- Add margin-bottom to Most Viewed Scripts header to unifi UI [@BramSuurdje](https://github.com/BramSuurdje) ([#7572](https://github.com/community-scripts/ProxmoxVE/pull/7572))
- #### 📝 Script Information
- Fix frontend url [@r1cebank](https://github.com/r1cebank) ([#7578](https://github.com/community-scripts/ProxmoxVE/pull/7578))
## 2025-09-10
### 🆕 New Scripts
- Autocaliweb ([#7515](https://github.com/community-scripts/ProxmoxVE/pull/7515))
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Palmr: fix #7556 [@vhsdream](https://github.com/vhsdream) ([#7558](https://github.com/community-scripts/ProxmoxVE/pull/7558))
- Wizarr: Fix DB migrations [@vhsdream](https://github.com/vhsdream) ([#7552](https://github.com/community-scripts/ProxmoxVE/pull/7552))
- fix: pmg - split no-nag script into separate config files [@MickLesk](https://github.com/MickLesk) ([#7540](https://github.com/community-scripts/ProxmoxVE/pull/7540))
- #### ✨ New Features
- Update Palmr to Support new v3.2.1 [@vhsdream](https://github.com/vhsdream) ([#7526](https://github.com/community-scripts/ProxmoxVE/pull/7526))
- add external installer warnings and user confirmation in several LXC's [@MickLesk](https://github.com/MickLesk) ([#7539](https://github.com/community-scripts/ProxmoxVE/pull/7539))
- Booklore: Add Bookdrop location to .env [@michelroegl-brunner](https://github.com/michelroegl-brunner) ([#7533](https://github.com/community-scripts/ProxmoxVE/pull/7533))
- #### 🔧 Refactor
- Refactor: audiobookshelf [@MickLesk](https://github.com/MickLesk) ([#7538](https://github.com/community-scripts/ProxmoxVE/pull/7538))
- Refactor: Blocky [@MickLesk](https://github.com/MickLesk) ([#7537](https://github.com/community-scripts/ProxmoxVE/pull/7537))
- Improve npmplus credential retrieval and messaging [@MickLesk](https://github.com/MickLesk) ([#7532](https://github.com/community-scripts/ProxmoxVE/pull/7532))
### 🌐 Website
- #### 💥 Breaking Changes
- Remove Pingvin Share [@CrazyWolf13](https://github.com/CrazyWolf13) ([#7553](https://github.com/community-scripts/ProxmoxVE/pull/7553))
- #### 📝 Script Information
- set updateable to true for several lxc JSON-configs [@MickLesk](https://github.com/MickLesk) ([#7534](https://github.com/community-scripts/ProxmoxVE/pull/7534))
## 2025-09-09
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Tududi: v0.81 [@vhsdream](https://github.com/vhsdream) ([#7517](https://github.com/community-scripts/ProxmoxVE/pull/7517))
- WGDashboard: Revert back to old update method [@tremor021](https://github.com/tremor021) ([#7500](https://github.com/community-scripts/ProxmoxVE/pull/7500))
- AdventureLog: remove folder during update process [@MickLesk](https://github.com/MickLesk) ([#7507](https://github.com/community-scripts/ProxmoxVE/pull/7507))
- PLANKA: Fix backup and restore commands [@tremor021](https://github.com/tremor021) ([#7505](https://github.com/community-scripts/ProxmoxVE/pull/7505))
- Recyclarr: Suppress config creation output [@tremor021](https://github.com/tremor021) ([#7502](https://github.com/community-scripts/ProxmoxVE/pull/7502))
- #### 🔧 Refactor
- Pulse: standardise install/update with Pulse repo script [@vhsdream](https://github.com/vhsdream) ([#7519](https://github.com/community-scripts/ProxmoxVE/pull/7519))
### 🌐 Website
- #### 🐞 Bug Fixes
- Refactor GitHubStarsButton to wrap in Link component for external navigation [@BramSuurdje](https://github.com/BramSuurdje) ([#7492](https://github.com/community-scripts/ProxmoxVE/pull/7492))
- #### ✨ New Features
- Bump vite from 7.0.0 to 7.1.5 in /frontend [@dependabot[bot]](https://github.com/dependabot[bot]) ([#7522](https://github.com/community-scripts/ProxmoxVE/pull/7522))
- #### 📝 Script Information
- swizzin: Change category from nvr to media [@MickLesk](https://github.com/MickLesk) ([#7511](https://github.com/community-scripts/ProxmoxVE/pull/7511))
## 2025-09-08
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- CT's: fix missing variable declaration (actualBudget, openziti, umlautadaptarr) [@MickLesk](https://github.com/MickLesk) ([#7483](https://github.com/community-scripts/ProxmoxVE/pull/7483))
- karakeep: fix service file [@CrazyWolf13](https://github.com/CrazyWolf13) ([#7482](https://github.com/community-scripts/ProxmoxVE/pull/7482))
- Update searxng-install.sh [@sebguy](https://github.com/sebguy) ([#7469](https://github.com/community-scripts/ProxmoxVE/pull/7469))
- #### ✨ New Features
- Immich: bump to version 1.141.1 [@vhsdream](https://github.com/vhsdream) ([#7418](https://github.com/community-scripts/ProxmoxVE/pull/7418))
- [core]: switch all base_settings to variables [@MickLesk](https://github.com/MickLesk) ([#7479](https://github.com/community-scripts/ProxmoxVE/pull/7479))
- #### 💥 Breaking Changes
- RustDesk Server: Update the credentials info [@tremor021](https://github.com/tremor021) ([#7473](https://github.com/community-scripts/ProxmoxVE/pull/7473))
### 🌐 Website
- #### 🐞 Bug Fixes
- Format numerical values in DataFetcher component for better readability [@BramSuurdje](https://github.com/BramSuurdje) ([#7477](https://github.com/community-scripts/ProxmoxVE/pull/7477))
- #### ✨ New Features
- feat: enhance github stars button to be better looking and more compact [@BramSuurdje](https://github.com/BramSuurdje) ([#7464](https://github.com/community-scripts/ProxmoxVE/pull/7464))
## 2025-09-07
### 🚀 Updated Scripts
- #### 🐞 Bug Fixes
- Update ExecStart path for karakeep service [@CrazyWolf13](https://github.com/CrazyWolf13) ([#7460](https://github.com/community-scripts/ProxmoxVE/pull/7460))
## 2025-09-06
### 🆕 New Scripts
- Resilio Sync ([#7442](https://github.com/community-scripts/ProxmoxVE/pull/7442))
- leantime ([#7414](https://github.com/community-scripts/ProxmoxVE/pull/7414))
### 🚀 Updated Scripts
- use debian source for direct installation of MQTT [@EtlamGit](https://github.com/EtlamGit) ([#7423](https://github.com/community-scripts/ProxmoxVE/pull/7423))
- #### ✨ New Features
- feat: added mobile ui subscription nag removal [@ivan-penchev](https://github.com/ivan-penchev) ([#7164](https://github.com/community-scripts/ProxmoxVE/pull/7164))
### 🌐 Website
- #### 📝 Script Information
- MediaManager Configuration Path [@austinpilz](https://github.com/austinpilz) ([#7408](https://github.com/community-scripts/ProxmoxVE/pull/7408))
- Paperless-NGX: Remove default credentials from json [@tremor021](https://github.com/tremor021) ([#7403](https://github.com/community-scripts/ProxmoxVE/pull/7403))
## 2025-09-05 ## 2025-09-05
### 🚀 Updated Scripts
- Tududi: Pin version to 0.80 [@vhsdream](https://github.com/vhsdream) ([#7420](https://github.com/community-scripts/ProxmoxVE/pull/7420))
- #### 🐞 Bug Fixes
- AdventureLog: Update dependencies [@tremor021](https://github.com/tremor021) ([#7404](https://github.com/community-scripts/ProxmoxVE/pull/7404))
### 🌐 Website
- refactor: Enhance ScriptAccordion and Sidebar components to support selectedCategory state [@BramSuurdje](https://github.com/BramSuurdje) ([#7405](https://github.com/community-scripts/ProxmoxVE/pull/7405))
## 2025-09-04 ## 2025-09-04
### 🚀 Updated Scripts ### 🚀 Updated Scripts

View File

@@ -6,13 +6,13 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
# Source: https://actualbudget.org/ # Source: https://actualbudget.org/
APP="Actual Budget" APP="Actual Budget"
var_tags="finance" var_tags="${var_tags:-finance}"
var_cpu="2" var_cpu="${var_cpu:-2}"
var_ram="2048" var_ram="${var_ram:-2048}"
var_disk="4" var_disk="${var_disk:-4}"
var_os="debian" var_os="${var_os:-debian}"
var_version="12" var_version="${var_version:-12}"
var_unprivileged="1" var_unprivileged="${var_unprivileged:-1}"
header_info "$APP" header_info "$APP"
variables variables

View File

@@ -27,6 +27,10 @@ function update_script() {
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
if ! command -v memcached >/dev/null 2>&1; then
$STD apt-get update
$STD apt-get install -y memcached libmemcached-tools
fi
if check_for_gh_release "adventurelog" "seanmorley15/adventurelog"; then if check_for_gh_release "adventurelog" "seanmorley15/adventurelog"; then
msg_info "Stopping Services" msg_info "Stopping Services"
systemctl stop adventurelog-backend systemctl stop adventurelog-backend
@@ -35,6 +39,7 @@ function update_script() {
msg_info "Backup Old Installation" msg_info "Backup Old Installation"
cp -r /opt/adventurelog /opt/adventurelog-backup cp -r /opt/adventurelog /opt/adventurelog-backup
rm -rf /opt/adventurelog
msg_ok "Backup done" msg_ok "Backup done"
fetch_and_deploy_gh_release "adventurelog" "seanmorley15/adventurelog" fetch_and_deploy_gh_release "adventurelog" "seanmorley15/adventurelog"

View File

@@ -9,7 +9,7 @@ APP="audiobookshelf"
var_tags="${var_tags:-podcast;audiobook}" var_tags="${var_tags:-podcast;audiobook}"
var_cpu="${var_cpu:-2}" var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}" var_ram="${var_ram:-2048}"
var_disk="${var_disk:-4}" var_disk="${var_disk:-5}"
var_os="${var_os:-debian}" var_os="${var_os:-debian}"
var_version="${var_version:-12}" var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-1}"
@@ -23,11 +23,15 @@ function update_script() {
header_info header_info
check_container_storage check_container_storage
check_container_resources check_container_resources
if [[ ! -f /etc/apt/trusted.gpg.d/audiobookshelf-ppa.asc ]]; then if [[ ! -f /etc/default/audiobookshelf ]]; then
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
echo "This application receives updates through the APT package manager."
msg_info "Updating $APP LXC"
$STD apt-get update
$STD apt-get -y upgrade
msg_ok "Updated $APP LXC"
exit exit
} }

83
ct/autocaliweb.sh Normal file
View File

@@ -0,0 +1,83 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: vhsdream
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/gelbphoenix/autocaliweb
APP="Autocaliweb"
var_tags="${var_tags:-ebooks}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-6}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/autocaliweb ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
setup_uv
RELEASE=$(curl -fsSL https://api.github.com/repos/gelbphoenix/autocaliweb/releases/latest | jq '.tag_name' | sed 's/^"v//;s/"$//')
if check_for_gh_release "autocaliweb" "gelbphoenix/autocaliweb"; then
msg_info "Stopping Services"
systemctl stop autocaliweb metadata-change-detector acw-ingest-service acw-auto-zipper
msg_ok "Stopped Services"
INSTALL_DIR="/opt/autocaliweb"
export VIRTUAL_ENV="${INSTALL_DIR}/venv"
$STD tar -cf ~/autocaliweb_bkp.tar "$INSTALL_DIR"/{metadata_change_logs,dirs.json,.env,scripts/ingest_watcher.sh,scripts/auto_zipper_wrapper.sh,scripts/metadata_change_detector_wrapper.sh}
fetch_and_deploy_gh_release "autocaliweb" "gelbphoenix/autocaliweb" "tarball" "latest" "/opt/autocaliweb"
msg_info "Updating ${APP}"
cd "$INSTALL_DIR"
if [[ ! -d "$VIRTUAL_ENV" ]]; then
$STD uv venv "$VIRTUAL_ENV"
fi
$STD uv sync --all-extras --active
cd "$INSTALL_DIR"/koreader/plugins
PLUGIN_DIGEST="$(find acwsync.koplugin -type f -name "*.lua" -o -name "*.json" | sort | xargs sha256sum | sha256sum | cut -d' ' -f1)"
echo "Plugin files digest: $PLUGIN_DIGEST" >acwsync.koplugin/${PLUGIN_DIGEST}.digest
echo "Build date: $(date)" >>acwsync.koplugin/${PLUGIN_DIGEST}.digest
echo "Files included:" >>acwsync.koplugin/${PLUGIN_DIGEST}.digest
$STD zip -r koplugin.zip acwsync.koplugin/
cp -r koplugin.zip "$INSTALL_DIR"/cps/static
mkdir -p "$INSTALL_DIR"/metadata_temp
$STD tar -xf ~/autocaliweb_bkp.tar --directory /
KEPUB_VERSION="$(/usr/bin/kepubify --version)"
CALIBRE_RELEASE="$(curl -s https://api.github.com/repos/kovidgoyal/calibre/releases/latest | grep -o '"tag_name": "[^"]*' | cut -d'"' -f4)"
echo "${KEPUB_VERSION#v}" >"$INSTALL_DIR"/KEPUBIFY_RELEASE
echo "${CALIBRE_RELEASE#v}" >/"$INSTALL_DIR"/CALIBRE_RELEASE
sed 's/^/v/' ~/.autocaliweb >"$INSTALL_DIR"/ACW_RELEASE
chown -R acw:acw "$INSTALL_DIR"
rm ~/autocaliweb_bkp.tar
msg_ok "Updated $APP"
msg_info "Starting Services"
systemctl start autocaliweb metadata-change-detector acw-ingest-service acw-auto-zipper
msg_ok "Started Services"
msg_ok "Updated Successfully"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8083${CL}"

View File

@@ -3,7 +3,7 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
# Copyright (c) 2021-2025 tteck # Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster) # Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE # License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://0xerr0r.github.io/blocky/latest/ # Source: https://0xerr0r.github.io/blocky
APP="Blocky" APP="Blocky"
var_tags="${var_tags:-adblock}" var_tags="${var_tags:-adblock}"
@@ -23,14 +23,34 @@ function update_script() {
header_info header_info
check_container_storage check_container_storage
check_container_resources check_container_resources
if [[ ! -d /var ]]; then if [[ ! -d /opt/blocky ]]; then
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
msg_info "Updating $APP LXC" if check_for_gh_release "blocky" "0xERR0R/blocky"; then
$STD apt-get update msg_info "Stopping Service"
$STD apt-get -y upgrade systemctl stop blocky
msg_ok "Updated $APP LXC" msg_ok "Stopped Service"
msg_info "Backup Config"
mv /opt/blocky/config.yml /opt/config.yml
msg_ok "Backed Up Config"
msg_info "Removing Old Version"
rm -rf /opt/blocky
msg_ok "Removed Old Version"
fetch_and_deploy_gh_release "blocky" "0xERR0R/blocky" "prebuild" "latest" "/opt/blocky" "blocky_*_linux_x86_64.tar.gz"
msg_info "Restore Config"
mv /opt/config.yml /opt/blocky/config.yml
msg_ok "Restored Config"
msg_info "Starting Service"
systemctl start blocky
msg_ok "Started Service"
msg_ok "Updated Successfully"
fi
exit exit
} }

View File

@@ -9,7 +9,7 @@ APP="ESPHome"
var_tags="${var_tags:-automation}" var_tags="${var_tags:-automation}"
var_cpu="${var_cpu:-2}" var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-1024}" var_ram="${var_ram:-1024}"
var_disk="${var_disk:-4}" var_disk="${var_disk:-10}"
var_os="${var_os:-debian}" var_os="${var_os:-debian}"
var_version="${var_version:-12}" var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}" var_unprivileged="${var_unprivileged:-1}"

6
ct/headers/autocaliweb Normal file
View File

@@ -0,0 +1,6 @@
___ __ ___ __
/ | __ __/ /_____ _________ _/ (_) _____ / /_
/ /| |/ / / / __/ __ \/ ___/ __ `/ / / | /| / / _ \/ __ \
/ ___ / /_/ / /_/ /_/ / /__/ /_/ / / /| |/ |/ / __/ /_/ /
/_/ |_\__,_/\__/\____/\___/\__,_/_/_/ |__/|__/\___/_.___/

6
ct/headers/leantime Normal file
View File

@@ -0,0 +1,6 @@
__ __ _
/ / ___ ____ _____ / /_(_)___ ___ ___
/ / / _ \/ __ `/ __ \/ __/ / __ `__ \/ _ \
/ /___/ __/ /_/ / / / / /_/ / / / / / / __/
/_____/\___/\__,_/_/ /_/\__/_/_/ /_/ /_/\___/

View File

@@ -1,6 +0,0 @@
____ _ _
/ __ \(_)___ ____ __ __(_)___
/ /_/ / / __ \/ __ `/ | / / / __ \
/ ____/ / / / / /_/ /| |/ / / / / /
/_/ /_/_/ /_/\__, / |___/_/_/ /_/
/____/

6
ct/headers/resiliosync Normal file
View File

@@ -0,0 +1,6 @@
____ _ ___ _____
/ __ \___ _____(_) (_)___ / ___/__ ______ _____
/ /_/ / _ \/ ___/ / / / __ \ \__ \/ / / / __ \/ ___/
/ _, _/ __(__ ) / / / /_/ / ___/ / /_/ / / / / /__
/_/ |_|\___/____/_/_/_/\____/ /____/\__, /_/ /_/\___/
/____/

6
ct/headers/stylus Normal file
View File

@@ -0,0 +1,6 @@
_____ __ __
/ ___// /___ __/ /_ _______
\__ \/ __/ / / / / / / / ___/
___/ / /_/ /_/ / / /_/ (__ )
/____/\__/\__, /_/\__,_/____/
/____/

6
ct/headers/telegraf Normal file
View File

@@ -0,0 +1,6 @@
__ __ ____
/ /____ / /__ ____ __________ _/ __/
/ __/ _ \/ / _ \/ __ `/ ___/ __ `/ /_
/ /_/ __/ / __/ /_/ / / / /_/ / __/
\__/\___/_/\___/\__, /_/ \__,_/_/
/____/

6
ct/headers/uhf Normal file
View File

@@ -0,0 +1,6 @@
__ ____ ________
/ / / / / / / ____/
/ / / / /_/ / /_
/ /_/ / __ / __/
\____/_/ /_/_/

View File

@@ -61,7 +61,7 @@ function update_script() {
done done
msg_ok "Image-processing libraries up to date" msg_ok "Image-processing libraries up to date"
fi fi
RELEASE="1.140.1" RELEASE="1.141.1"
if check_for_gh_release "immich" "immich-app/immich" "${RELEASE}"; then if check_for_gh_release "immich" "immich-app/immich" "${RELEASE}"; then
msg_info "Stopping Services" msg_info "Stopping Services"
systemctl stop immich-web systemctl stop immich-web

View File

@@ -53,6 +53,11 @@ function update_script() {
systemctl daemon-reload systemctl daemon-reload
fi fi
if grep -q '^ExecStart=/usr/bin/node\s\+dist/index\.mjs$' /etc/systemd/system/karakeep-workers.service; then
sed -i -E 's#^(ExecStart=/usr/bin/node\s+dist/)index\.mjs$#\1index.js#' /etc/systemd/system/karakeep-workers.service
systemctl daemon-reload
fi
fetch_and_deploy_gh_release "karakeep" "karakeep-app/karakeep" fetch_and_deploy_gh_release "karakeep" "karakeep-app/karakeep"
if command -v corepack >/dev/null; then if command -v corepack >/dev/null; then
$STD corepack disable $STD corepack disable

62
ct/leantime.sh Normal file
View File

@@ -0,0 +1,62 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: Stroopwafe1
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://leantime.io
APP="Leantime"
var_tags="${var_tags:-productivity}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-20}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/leantime ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "leantime" "Leantime/leantime"; then
msg_info "Creating Backup"
mariadb-dump leantime >"/opt/${APP}_db_backup_$(date +%F).sql"
tar -czf "/opt/${APP}_backup_$(date +%F).tar.gz" "/opt/${APP}"
mv /opt/leantime /opt/leantime_bak
msg_ok "Backup Created"
fetch_and_deploy_gh_release "leantime" "Leantime/leantime" "prebuild" "latest" "/opt/leantime" Leantime*.tar.gz
msg_info "Restoring Config & Permissions"
mv /opt/leantime_bak/config/.env /opt/leantime/config/.env
chown -R www-data:www-data "/opt/leantime"
chmod -R 750 "/opt/leantime"
msg_ok "Restored Config & Permissions"
msg_info "Removing Backup"
rm -rf /opt/leantime_bak
msg_ok "Removed Backup"
msg_ok "Updated Successfully"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}/install${CL}"

View File

@@ -33,11 +33,17 @@ function update_script() {
OLLAMA_VERSION=$(ollama -v | awk '{print $NF}') OLLAMA_VERSION=$(ollama -v | awk '{print $NF}')
RELEASE=$(curl -s https://api.github.com/repos/ollama/ollama/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4)}') RELEASE=$(curl -s https://api.github.com/repos/ollama/ollama/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4)}')
if [ "$OLLAMA_VERSION" != "$RELEASE" ]; then if [ "$OLLAMA_VERSION" != "$RELEASE" ]; then
msg_info "Stopping Service"
systemctl stop ollama
msg_ok "Stopped Service"
curl -fsSLO https://ollama.com/download/ollama-linux-amd64.tgz
rm -rf /usr/lib/ollama rm -rf /usr/lib/ollama
rm -rf /usr/bin/ollama rm -rf /usr/bin/ollama
curl -fsSLO https://ollama.com/download/ollama-linux-amd64.tgz
tar -C /usr -xzf ollama-linux-amd64.tgz tar -C /usr -xzf ollama-linux-amd64.tgz
rm -rf ollama-linux-amd64.tgz rm -rf ollama-linux-amd64.tgz
msg_info "Starting Service"
systemctl start ollama
msg_info "Started Service"
msg_ok "Ollama updated to version $RELEASE" msg_ok "Ollama updated to version $RELEASE"
else else
msg_ok "Ollama is already up to date." msg_ok "Ollama is already up to date."

View File

@@ -6,13 +6,13 @@ source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/m
# Source: https://github.com/openziti/ziti # Source: https://github.com/openziti/ziti
APP="openziti-controller" APP="openziti-controller"
var_tags="network;openziti-controller" var_tags="${var_tags:-network;openziti-controller}"
var_cpu="2" var_cpu="${var_cpu:-2}"
var_ram="1024" var_ram="${var_ram:-1024}"
var_disk="8" var_disk="${var_disk:-8}"
var_os="debian" var_os="${var_os:-debian}"
var_version="12" var_version="${var_version:-12}"
var_unprivileged="1" var_unprivileged="${var_unprivileged:-1}"
header_info "$APP" header_info "$APP"
variables variables

View File

@@ -42,9 +42,9 @@ function update_script() {
cd /opt/palmr/apps/server cd /opt/palmr/apps/server
mv /opt/palmr.env /opt/palmr/apps/server/.env mv /opt/palmr.env /opt/palmr/apps/server/.env
$STD pnpm install $STD pnpm install
$STD pnpm dlx prisma generate $STD npx prisma generate
$STD pnpm dlx prisma migrate deploy $STD npx prisma migrate deploy
$STD pnpm dlx prisma db push $STD npx prisma db push
$STD pnpm build $STD pnpm build
cd /opt/palmr/apps/web cd /opt/palmr/apps/web

View File

@@ -1,73 +0,0 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 tteck
# Author: tteck (tteckster)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://stonith404.github.io/pingvin-share/introduction
APP="Pingvin"
var_tags="${var_tags:-sharing}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/pingvin-share ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
RELEASE=$(curl -fsSL https://api.github.com/repos/stonith404/pingvin-share/releases/latest | grep "tag_name" | awk '{print substr($2, 3, length($2)-4) }')
if [[ ! -f /opt/pingvin_version.txt ]] || [[ "${RELEASE}" != "$(cat /opt/pingvin_version.txt)" ]]; then
msg_info "Stopping Pingvin Share"
systemctl stop pm2-root.service
msg_ok "Stopped Pingvin Share"
msg_info "Updating Pingvin Share to v${RELEASE}"
cd /opt
curl -fsSL "https://github.com/stonith404/pingvin-share/archive/refs/tags/v${RELEASE}.zip" -o $(basename "https://github.com/stonith404/pingvin-share/archive/refs/tags/v${RELEASE}.zip")
$STD unzip v${RELEASE}.zip
cp -rf pingvin-share-${RELEASE}/* /opt/pingvin-share
cd /opt/pingvin-share
cd backend
$STD npm install
$STD npm run build
cd ../frontend
$STD npm install
$STD npm run build
echo "${RELEASE}" >"/opt/pingvin_version.txt"
rm -rf /opt/v${RELEASE}.zip
rm -rf /opt/pingvin-share-${RELEASE}
msg_ok "Updated Pingvin Share to v${RELEASE}"
msg_info "Starting Pingvin Share"
systemctl start pm2-root.service
msg_ok "Started Pingvin Share"
msg_ok "Updated Successfully"
exit
else
msg_ok "No update required. Pingvin Share is already at v${RELEASE}."
fi
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:3000${CL}"

View File

@@ -34,12 +34,13 @@ function update_script() {
msg_ok "Stopped $APP" msg_ok "Stopped $APP"
msg_info "Backing up data" msg_info "Backing up data"
mkdir -p /opt/planka-backup/{favicons,user-avatars,background-images,attachments} BK="/opt/planka-backup"
mv /opt/planka/.env /opt/planka-backup mkdir -p "$BK"/{favicons,user-avatars,background-images,attachments}
[ -d /opt/planka/public/favicons ] && find /opt/planka/public/favicons -maxdepth 1 -type f -exec mv -t /opt/planka-backup/favicons {} + [ -f /opt/planka/.env ] && mv /opt/planka/.env "$BK"/
[ -d /opt/planka/public/user-avatars ] && find /opt/planka/public/user-avatars -maxdepth 1 -type f -exec mv -t /opt/planka-backup/user-avatars {} + [ -d /opt/planka/public/favicons ] && cp -a /opt/planka/public/favicons/. "$BK/favicons/"
[ -d /opt/planka/public/background-images ] && find /opt/planka/public/background-images -maxdepth 1 -type f -exec mv -t /opt/planka-backup/background-images {} + [ -d /opt/planka/public/user-avatars ] && cp -a /opt/planka/public/user-avatars/. "$BK/user-avatars/"
[ -d /opt/planka/private/attachments ] && find /opt/planka/private/attachments -maxdepth 1 -type f -exec mv -t /opt/planka-backup/attachments {} + [ -d /opt/planka/public/background-images ] && cp -a /opt/planka/public/background-images/. "$BK/background-images/"
[ -d /opt/planka/private/attachments ] && cp -a /opt/planka/private/attachments/. "$BK/attachments/"
rm -rf /opt/planka rm -rf /opt/planka
msg_ok "Backed up data" msg_ok "Backed up data"
@@ -51,11 +52,13 @@ function update_script() {
msg_ok "Updated Frontend" msg_ok "Updated Frontend"
msg_info "Restoring data" msg_info "Restoring data"
mv /opt/planka-backup/.env /opt/planka/ [ -f "$BK/.env" ] && mv "$BK/.env" /opt/planka/.env
[ -d /opt/planka-backup/favicons ] && find /opt/planka-backup/favicons -maxdepth 1 -type f -exec mv -t /opt/planka/public/favicons {} + mkdir -p /opt/planka/public/{favicons,user-avatars,background-images} /opt/planka/private/attachments
[ -d /opt/planka-backup/user-avatars ] && find /opt/planka-backup/user-avatars -maxdepth 1 -type f -exec mv -t /opt/planka/public/user-avatars {} + [ -d "$BK/favicons" ] && cp -a "$BK/favicons/." /opt/planka/public/favicons/
[ -d /opt/planka-backup/background-images ] && find /opt/planka-backup/background-images -maxdepth 1 -type f -exec mv -t /opt/planka/public/background-images {} + [ -d "$BK/user-avatars" ] && cp -a "$BK/user-avatars/." /opt/planka/public/user-avatars/
[ -d /opt/planka-backup/attachments ] && find /opt/planka-backup/attachments -maxdepth 1 -type f -exec mv -t /opt/planka/private/attachments {} + [ -d "$BK/background-images" ] && cp -a "$BK/background-images/." /opt/planka/public/background-images/
[ -d "$BK/attachments" ] && cp -a "$BK/attachments/." /opt/planka/private/attachments/
rm -rf "$BK"
msg_ok "Restored data" msg_ok "Restored data"
msg_info "Starting $APP" msg_info "Starting $APP"

View File

@@ -28,10 +28,6 @@ function update_script() {
exit exit
fi fi
if [[ ! -f ~/.pulse ]]; then
msg_error "Old Installation Found! Please recreate the container due big changes in the software."
exit 1
fi
if check_for_gh_release "pulse" "rcourtman/Pulse"; then if check_for_gh_release "pulse" "rcourtman/Pulse"; then
SERVICE_PATH="/etc/systemd/system" SERVICE_PATH="/etc/systemd/system"
msg_info "Stopping Services" msg_info "Stopping Services"
@@ -43,19 +39,20 @@ function update_script() {
fi fi
fetch_and_deploy_gh_release "pulse" "rcourtman/Pulse" "prebuild" "latest" "/opt/pulse" "*-linux-amd64.tar.gz" fetch_and_deploy_gh_release "pulse" "rcourtman/Pulse" "prebuild" "latest" "/opt/pulse" "*-linux-amd64.tar.gz"
ln -sf /opt/pulse/bin/pulse /usr/local/bin/pulse
chown -R pulse:pulse /etc/pulse /opt/pulse chown -R pulse:pulse /etc/pulse /opt/pulse
if [[ -f "$SERVICE_PATH"/pulse.service ]]; then if [[ -f "$SERVICE_PATH"/pulse-backend.service ]]; then
mv "$SERVICE_PATH"/pulse.service "$SERVICE_PATH"/pulse-backend.service mv "$SERVICE_PATH"/pulse-backend.service "$SERVICE_PATH"/pulse.service
fi fi
sed -i -e 's|pulse/pulse|pulse/bin/pulse|' \ sed -i -e 's|pulse/pulse|pulse/bin/pulse|' \
-e 's/^Environment="API.*$//' "$SERVICE_PATH"/pulse-backend.service -e 's/^Environment="API.*$//' "$SERVICE_PATH"/pulse.service
systemctl daemon-reload systemctl daemon-reload
if grep -q 'pulse-home:/bin/bash' /etc/passwd; then if grep -q 'pulse-home:/bin/bash' /etc/passwd; then
usermod -s /usr/sbin/nologin pulse usermod -s /usr/sbin/nologin pulse
fi fi
msg_info "Starting Services" msg_info "Starting Services"
systemctl start pulse-backend systemctl start pulse
msg_ok "Started Services" msg_ok "Started Services"
msg_ok "Updated Successfully" msg_ok "Updated Successfully"
fi fi

View File

@@ -34,6 +34,7 @@ function update_script() {
msg_ok "Stopped Service" msg_ok "Stopped Service"
fetch_and_deploy_gh_release "recyclarr" "recyclarr/recyclarr" "prebuild" "latest" "/usr/local/bin" "recyclarr-linux-x64.tar.xz" fetch_and_deploy_gh_release "recyclarr" "recyclarr/recyclarr" "prebuild" "latest" "/usr/local/bin" "recyclarr-linux-x64.tar.xz"
msg_info "Starting Service" msg_info "Starting Service"
systemctl start recyclarr systemctl start recyclarr
msg_ok "Started Service" msg_ok "Started Service"

44
ct/resiliosync.sh Normal file
View File

@@ -0,0 +1,44 @@
#!/usr/bin/env bash
source <(curl -s https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: David Bennett (dbinit)
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.resilio.com/sync
APP="Resilio Sync"
var_tags="${var_tags:-sync}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /var/lib/resilio-sync ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Updating ${APP} LXC"
$STD apt-get update
$STD apt-get -y upgrade
msg_ok "Updated Successfully"
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}https://${IP}:8888${CL}"

54
ct/stylus.sh Normal file
View File

@@ -0,0 +1,54 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: luismco
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/mmastrac/stylus
APP="Stylus"
var_tags="${var_tags:-network}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-2}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
var_fuse="${var_fuse:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/stylus ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "stylus" "mmastrac/stylus"; then
msg_info "Stopping $APP"
systemctl stop stylus
msg_ok "Stopped $APP"
fetch_and_deploy_gh_release "stylus" "mmastrac/stylus" "singlefile" "latest" "/usr/bin/" "*_linux_amd64"
msg_info "Starting $APP"
systemctl start stylus
msg_ok "Started $APP"
msg_ok "Update Successful"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:8000${CL}"

52
ct/telegraf.sh Normal file
View File

@@ -0,0 +1,52 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: CrazyWolf13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://github.com/influxdata/telegraf
APP="telegraf"
var_tags="${var_tags:-collector;metrics}"
var_cpu="${var_cpu:-1}"
var_ram="${var_ram:-1024}"
var_disk="${var_disk:-4}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -f /etc/telegraf/telegraf.conf ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
msg_info "Stopping $APP"
systemctl stop telegraf
msg_ok "Stopped $APP"
msg_info "Updating $APP"
$STD apt-get update
$STD apt-get upgrade telegraf -y
msg_ok "Updated $APP"
msg_info "Starting $APP"
systemctl start telegraf
msg_ok "Started $APP"
msg_ok "Updated Successfully"
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"

View File

@@ -27,17 +27,22 @@ function update_script() {
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
NODE_VERSION="22" setup_nodejs
if check_for_gh_release "tududi" "chrisvel/tududi"; then if check_for_gh_release "tududi" "chrisvel/tududi"; then
msg_info "Stopping Service" msg_info "Stopping Service"
systemctl stop tududi systemctl stop tududi
msg_ok "Stopped Service" msg_ok "Stopped Service"
msg_info "Remove and backup Files" msg_info "Remove and backup Files"
DB="$(sed -n '/^DB_FILE/s/[^=]*=//p' /opt/tududi/backend/.env)"
export DB_FILE="$DB"
cp /opt/tududi/backend/.env /opt/tududi.env cp /opt/tududi/backend/.env /opt/tududi.env
rm -rf /opt/tududi/backend/dist rm -rf /opt/tududi/backend/dist
msg_ok "Backup and removed Files" msg_ok "Backup and removed Files"
fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" fetch_and_deploy_gh_release "tududi" "chrisvel/tududi" "tarball" "latest" "/opt/tududi"
msg_info "Updating ${APP}" msg_info "Updating ${APP}"
cd /opt/tududi cd /opt/tududi
@@ -48,6 +53,10 @@ function update_script() {
mv ./public/locales ./backend/dist mv ./public/locales ./backend/dist
mv ./public/favicon.* ./backend/dist mv ./public/favicon.* ./backend/dist
mv /opt/tududi.env /opt/tududi/.env mv /opt/tududi.env /opt/tududi/.env
sed -i -e 's|/tududi$|/tududi/backend|' \
-e 's|npm run start|bash /opt/tududi/backend/cmd/start.sh|' \
/etc/systemd/system/tududi.service
systemctl daemon-reload
msg_ok "Updated $APP" msg_ok "Updated $APP"
msg_info "Starting Service" msg_info "Starting Service"

63
ct/uhf.sh Normal file
View File

@@ -0,0 +1,63 @@
#!/usr/bin/env bash
source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxVE/main/misc/build.func)
# Copyright (c) 2021-2025 community-scripts ORG
# Author: zackwithak13
# License: MIT | https://github.com/community-scripts/ProxmoxVE/raw/main/LICENSE
# Source: https://www.uhfapp.com/server
APP="UHF"
var_tags="${var_tags:-media}"
var_cpu="${var_cpu:-2}"
var_ram="${var_ram:-2048}"
var_disk="${var_disk:-8}"
var_os="${var_os:-debian}"
var_version="${var_version:-12}"
var_unprivileged="${var_unprivileged:-1}"
header_info "$APP"
variables
color
catch_errors
function update_script() {
header_info
check_container_storage
check_container_resources
if [[ ! -d /opt/uhf-server ]]; then
msg_error "No ${APP} Installation Found!"
exit
fi
if check_for_gh_release "uhf-server" "swapplications/uhf-server-dist"; then
msg_info "Stopping Service"
systemctl stop uhf-server
msg_ok "Stopped Service"
msg_info "Updating ${APP} LXC"
$STD apt-get update
$STD apt-get -y upgrade
msg_ok "Updated ${APP} LXC"
fetch_and_deploy_gh_release "comskip" "swapplications/comskip" "prebuild" "latest" "/opt/comskip" "comskip-x64-*.zip"
fetch_and_deploy_gh_release "uhf-server" "swapplications/uhf-server-dist" "prebuild" "latest" "/opt/uhf-server" "UHF.Server-linux-x64-*.zip"
msg_info "Starting Service"
systemctl start uhf-server
msg_ok "Started Service"
msg_info "Cleaning up"
$STD apt-get -y autoremove
$STD apt-get -y autoclean
msg_ok "Cleaned"
msg_ok "Updated Successfully"
fi
exit
}
start
build_container
description
msg_ok "Completed Successfully!\n"
echo -e "${CREATING}${GN}${APP} setup has been successfully initialized!${CL}"
echo -e "${INFO}${YW} Access it using the following URL:${CL}"
echo -e "${TAB}${GATEWAY}${BGN}http://${IP}:7568${CL}"

View File

@@ -6,13 +6,13 @@ source <(curl -fsSL https://raw.githubusercontent.com/community-scripts/ProxmoxV
# Source: https://github.com/PCJones/UmlautAdaptarr # Source: https://github.com/PCJones/UmlautAdaptarr
APP="UmlautAdaptarr" APP="UmlautAdaptarr"
var_tags="arr" var_tags="${var_tags:-arr}"
var_cpu="1" var_cpu="${var_cpu:-1}"
var_ram="512" var_ram="${var_ram:-512}"
var_disk="4" var_disk="${var_disk:-4}"
var_os="debian" var_os="${var_os:-debian}"
var_version="12" var_version="${var_version:-12}"
var_unprivileged="1" var_unprivileged="${var_unprivileged:-1}"
header_info "$APP" header_info "$APP"
variables variables

View File

@@ -28,6 +28,12 @@ function update_script() {
msg_error "No ${APP} Installation Found!" msg_error "No ${APP} Installation Found!"
exit exit
fi fi
if ! dpkg -s git >/dev/null 2>&1; then
msg_info "Installing git"
$STD apt-get update
$STD apt-get install -y git
msg_ok "Installed git"
fi
apt-get update apt-get update
apt-get -y upgrade apt-get -y upgrade
if [[ -d /etc/wgdashboard ]]; then if [[ -d /etc/wgdashboard ]]; then

View File

@@ -39,20 +39,23 @@ function update_script() {
msg_info "Creating Backup" msg_info "Creating Backup"
BACKUP_FILE="/opt/wizarr_backup_$(date +%F).tar.gz" BACKUP_FILE="/opt/wizarr_backup_$(date +%F).tar.gz"
$STD tar -czf "$BACKUP_FILE" /opt/wizarr/{.env,start.sh} /opt/wizarr/database/ &>/dev/null $STD tar -czf "$BACKUP_FILE" /opt/wizarr/{.env,start.sh} /opt/wizarr/database/ &>/dev/null
rm -rf /opt/wizarr/migrations/versions/*
msg_ok "Backup Created" msg_ok "Backup Created"
fetch_and_deploy_gh_release "wizarr" "wizarrrr/wizarr" fetch_and_deploy_gh_release "wizarr" "wizarrrr/wizarr"
msg_info "Updating $APP" msg_info "Updating $APP"
cd /opt/wizarr cd /opt/wizarr
$STD /usr/local/bin/uv lock $STD /usr/local/bin/uv sync --frozen
$STD /usr/local/bin/uv sync --locked $STD /usr/local/bin/uv run --frozen pybabel compile -d app/translations
$STD /usr/local/bin/uv run pybabel compile -d app/translations
$STD npm --prefix app/static install $STD npm --prefix app/static install
$STD npm --prefix app/static run build:css $STD npm --prefix app/static run build:css
mkdir -p ./.cache mkdir -p ./.cache
$STD tar -xf "$BACKUP_FILE" --directory=/ $STD tar -xf "$BACKUP_FILE" --directory=/
$STD /usr/local/bin/uv run flask db upgrade $STD /usr/local/bin/uv run --frozen flask db upgrade
if ! grep -q 'frozen' /opt/wizarr/start.sh; then
sed -i 's/run/& --frozen/' /opt/wizarr/start.sh
fi
msg_ok "Updated $APP" msg_ok "Updated $APP"
msg_info "Starting $APP" msg_info "Starting $APP"

View File

@@ -13,5 +13,8 @@
"aliases": { "aliases": {
"components": "@/components", "components": "@/components",
"utils": "@/lib/utils" "utils": "@/lib/utils"
},
"registries": {
"@animate-ui": "https://animate-ui.com/r/{name}.json"
} }
} }

View File

@@ -18,6 +18,10 @@ const nextConfig = {
BASE_PATH: "ProxmoxVE", BASE_PATH: "ProxmoxVE",
}, },
eslint: {
ignoreDuringBuilds: true,
},
output: "export", output: "export",
basePath: `/ProxmoxVE`, basePath: `/ProxmoxVE`,
}; };

View File

@@ -31,8 +31,9 @@
"date-fns": "^4.1.0", "date-fns": "^4.1.0",
"framer-motion": "^11.18.2", "framer-motion": "^11.18.2",
"fuse.js": "^7.1.0", "fuse.js": "^7.1.0",
"lucide-react": "^0.453.0", "lucide-react": "^0.542.0",
"mini-svg-data-uri": "^1.4.4", "mini-svg-data-uri": "^1.4.4",
"motion": "^12.23.12",
"next": "15.5.2", "next": "15.5.2",
"next-themes": "^0.4.4", "next-themes": "^0.4.4",
"nuqs": "^2.4.1", "nuqs": "^2.4.1",
@@ -46,6 +47,7 @@
"react-dom": "19.0.0", "react-dom": "19.0.0",
"react-icons": "^5.5.0", "react-icons": "^5.5.0",
"react-simple-typewriter": "^5.0.1", "react-simple-typewriter": "^5.0.1",
"react-use-measure": "^2.1.7",
"sharp": "^0.33.5", "sharp": "^0.33.5",
"simple-icons": "^13.21.0", "simple-icons": "^13.21.0",
"sonner": "^1.7.4", "sonner": "^1.7.4",
@@ -7664,11 +7666,14 @@
} }
}, },
"node_modules/fdir": { "node_modules/fdir": {
"version": "6.4.6", "version": "6.5.0",
"resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.6.tgz", "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.5.0.tgz",
"integrity": "sha512-hiFoqpyZcfNm1yc4u8oWCf9A2c4D3QjCrks3zmoVKVxpQRzmPNar1hUJcBG2RQHvEVGDN+Jm81ZheVLAQMK6+w==", "integrity": "sha512-tIbYtZbucOs0BRGqPJkshJUYdL+SDH7dVM8gjy+ERp3WAUjLEFJE+02kanyHtwjWOnwrKYBiwAmM0p4kLJAnXg==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": {
"node": ">=12.0.0"
},
"peerDependencies": { "peerDependencies": {
"picomatch": "^3 || ^4" "picomatch": "^3 || ^4"
}, },
@@ -9293,12 +9298,12 @@
} }
}, },
"node_modules/lucide-react": { "node_modules/lucide-react": {
"version": "0.453.0", "version": "0.542.0",
"resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.453.0.tgz", "resolved": "https://registry.npmjs.org/lucide-react/-/lucide-react-0.542.0.tgz",
"integrity": "sha512-kL+RGZCcJi9BvJtzg2kshO192Ddy9hv3ij+cPrVPWSRzgCWCVazoQJxOjAwgK53NomL07HB7GPHW120FimjNhQ==", "integrity": "sha512-w3hD8/SQB7+lzU2r4VdFyzzOzKnUjTZIF/MQJGSSvni7Llewni4vuViRppfRAa2guOsY5k4jZyxw/i9DQHv+dw==",
"license": "ISC", "license": "ISC",
"peerDependencies": { "peerDependencies": {
"react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0-rc" "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0"
} }
}, },
"node_modules/magic-string": { "node_modules/magic-string": {
@@ -10339,6 +10344,32 @@
"pathe": "^2.0.1" "pathe": "^2.0.1"
} }
}, },
"node_modules/motion": {
"version": "12.23.12",
"resolved": "https://registry.npmjs.org/motion/-/motion-12.23.12.tgz",
"integrity": "sha512-8jCD8uW5GD1csOoqh1WhH1A6j5APHVE15nuBkFeRiMzYBdRwyAHmSP/oXSuW0WJPZRXTFdBoG4hY9TFWNhhwng==",
"license": "MIT",
"dependencies": {
"framer-motion": "^12.23.12",
"tslib": "^2.4.0"
},
"peerDependencies": {
"@emotion/is-prop-valid": "*",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@emotion/is-prop-valid": {
"optional": true
},
"react": {
"optional": true
},
"react-dom": {
"optional": true
}
}
},
"node_modules/motion-dom": { "node_modules/motion-dom": {
"version": "11.18.1", "version": "11.18.1",
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz", "resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-11.18.1.tgz",
@@ -10354,6 +10385,48 @@
"integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==", "integrity": "sha512-49Kt+HKjtbJKLtgO/LKj9Ld+6vw9BjH5d9sc40R/kVyH8GLAXgT42M2NnuPcJNuA3s9ZfZBUcwIgpmZWGEE+hA==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/motion/node_modules/framer-motion": {
"version": "12.23.12",
"resolved": "https://registry.npmjs.org/framer-motion/-/framer-motion-12.23.12.tgz",
"integrity": "sha512-6e78rdVtnBvlEVgu6eFEAgG9v3wLnYEboM8I5O5EXvfKC8gxGQB8wXJdhkMy10iVcn05jl6CNw7/HTsTCfwcWg==",
"license": "MIT",
"dependencies": {
"motion-dom": "^12.23.12",
"motion-utils": "^12.23.6",
"tslib": "^2.4.0"
},
"peerDependencies": {
"@emotion/is-prop-valid": "*",
"react": "^18.0.0 || ^19.0.0",
"react-dom": "^18.0.0 || ^19.0.0"
},
"peerDependenciesMeta": {
"@emotion/is-prop-valid": {
"optional": true
},
"react": {
"optional": true
},
"react-dom": {
"optional": true
}
}
},
"node_modules/motion/node_modules/motion-dom": {
"version": "12.23.12",
"resolved": "https://registry.npmjs.org/motion-dom/-/motion-dom-12.23.12.tgz",
"integrity": "sha512-RcR4fvMCTESQBD/uKQe49D5RUeDOokkGRmz4ceaJKDBgHYtZtntC/s2vLvY38gqGaytinij/yi3hMcWVcEF5Kw==",
"license": "MIT",
"dependencies": {
"motion-utils": "^12.23.6"
}
},
"node_modules/motion/node_modules/motion-utils": {
"version": "12.23.6",
"resolved": "https://registry.npmjs.org/motion-utils/-/motion-utils-12.23.6.tgz",
"integrity": "sha512-eAWoPgr4eFEOFfg2WjIsMoqJTW6Z8MTUCgn/GZ3VRpClWBdnbjryiA3ZSNLyxCTmCQx4RmYX6jX1iWHbenUPNQ==",
"license": "MIT"
},
"node_modules/ms": { "node_modules/ms": {
"version": "2.1.3", "version": "2.1.3",
"resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
@@ -11362,9 +11435,9 @@
"license": "ISC" "license": "ISC"
}, },
"node_modules/picomatch": { "node_modules/picomatch": {
"version": "4.0.2", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.3.tgz",
"integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==", "integrity": "sha512-5gTmgEY/sqK6gFXLIsQNH19lWb4ebPDLA4SdLP7dsWkIXHWlG66oPuVvXSGFPppYZz8ZDZq0dYYrbHfBCVUb1Q==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
@@ -11990,6 +12063,21 @@
"react": ">= 0.14.0" "react": ">= 0.14.0"
} }
}, },
"node_modules/react-use-measure": {
"version": "2.1.7",
"resolved": "https://registry.npmjs.org/react-use-measure/-/react-use-measure-2.1.7.tgz",
"integrity": "sha512-KrvcAo13I/60HpwGO5jpW7E9DfusKyLPLvuHlUyP5zqnmAPhNc6qTRjUQrdTADl0lpPpDVU2/Gg51UlOGHXbdg==",
"license": "MIT",
"peerDependencies": {
"react": ">=16.13",
"react-dom": ">=16.13"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
}
}
},
"node_modules/read-cache": { "node_modules/read-cache": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz", "resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
@@ -13307,14 +13395,14 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/tinyglobby": { "node_modules/tinyglobby": {
"version": "0.2.14", "version": "0.2.15",
"resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.15.tgz",
"integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==", "integrity": "sha512-j2Zq4NyQYG5XMST4cbs02Ak8iJUdxRM0XI5QyxXuZOzKOINmWurp3smXu3y5wDcJrptwpSjgXHzIQxR0omXljQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"fdir": "^6.4.4", "fdir": "^6.5.0",
"picomatch": "^4.0.2" "picomatch": "^4.0.3"
}, },
"engines": { "engines": {
"node": ">=12.0.0" "node": ">=12.0.0"
@@ -13837,19 +13925,19 @@
"license": "MIT" "license": "MIT"
}, },
"node_modules/vite": { "node_modules/vite": {
"version": "7.0.0", "version": "7.1.5",
"resolved": "https://registry.npmjs.org/vite/-/vite-7.0.0.tgz", "resolved": "https://registry.npmjs.org/vite/-/vite-7.1.5.tgz",
"integrity": "sha512-ixXJB1YRgDIw2OszKQS9WxGHKwLdCsbQNkpJN171udl6szi/rIySHL6/Os3s2+oE4P/FLD4dxg4mD7Wust+u5g==", "integrity": "sha512-4cKBO9wR75r0BeIWWWId9XK9Lj6La5X846Zw9dFfzMRw38IlTk2iCcUt6hsyiDRcPidc55ZParFYDXi0nXOeLQ==",
"dev": true, "dev": true,
"license": "MIT", "license": "MIT",
"peer": true, "peer": true,
"dependencies": { "dependencies": {
"esbuild": "^0.25.0", "esbuild": "^0.25.0",
"fdir": "^6.4.6", "fdir": "^6.5.0",
"picomatch": "^4.0.2", "picomatch": "^4.0.3",
"postcss": "^8.5.6", "postcss": "^8.5.6",
"rollup": "^4.40.0", "rollup": "^4.43.0",
"tinyglobby": "^0.2.14" "tinyglobby": "^0.2.15"
}, },
"bin": { "bin": {
"vite": "bin/vite.js" "vite": "bin/vite.js"

4
frontend/package.json generated
View File

@@ -38,8 +38,9 @@
"date-fns": "^4.1.0", "date-fns": "^4.1.0",
"framer-motion": "^11.18.2", "framer-motion": "^11.18.2",
"fuse.js": "^7.1.0", "fuse.js": "^7.1.0",
"lucide-react": "^0.453.0", "lucide-react": "^0.542.0",
"mini-svg-data-uri": "^1.4.4", "mini-svg-data-uri": "^1.4.4",
"motion": "^12.23.12",
"next": "15.5.2", "next": "15.5.2",
"next-themes": "^0.4.4", "next-themes": "^0.4.4",
"nuqs": "^2.4.1", "nuqs": "^2.4.1",
@@ -53,6 +54,7 @@
"react-dom": "19.0.0", "react-dom": "19.0.0",
"react-icons": "^5.5.0", "react-icons": "^5.5.0",
"react-simple-typewriter": "^5.0.1", "react-simple-typewriter": "^5.0.1",
"react-use-measure": "^2.1.7",
"sharp": "^0.33.5", "sharp": "^0.33.5",
"simple-icons": "^13.21.0", "simple-icons": "^13.21.0",
"sonner": "^1.7.4", "sonner": "^1.7.4",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-19", "date_created": "2024-05-19",
"type": "addon", "type": "addon",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
"documentation": "https://docs.netbird.io/", "documentation": "https://docs.netbird.io/",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "addon", "type": "addon",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
"documentation": "https://tailscale.com/kb/1017/install", "documentation": "https://tailscale.com/kb/1017/install",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 3142, "interface_port": 3142,
"documentation": "https://www.unix-ag.uni-kl.de/~bloch/acng/html/index.html", "documentation": "https://www.unix-ag.uni-kl.de/~bloch/acng/html/index.html",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 13378, "interface_port": 13378,
"documentation": "https://www.audiobookshelf.org/guides/", "documentation": "https://www.audiobookshelf.org/guides/",
@@ -21,7 +21,7 @@
"resources": { "resources": {
"cpu": 2, "cpu": 2,
"ram": 2048, "ram": 2048,
"hdd": 4, "hdd": 5,
"os": "debian", "os": "debian",
"version": "12" "version": "12"
} }

View File

@@ -0,0 +1,35 @@
{
"name": "Autocaliweb",
"slug": "autocaliweb",
"categories": [
13
],
"date_created": "2025-09-10",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8083,
"documentation": "https://github.com/gelbphoenix/autocaliweb/wiki",
"config_path": "/etc/autocaliweb",
"website": "https://github.com/gelbphoenix/autocaliweb",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/autocaliweb.webp",
"description": "A modern web management system for eBooks, eComics and PDFs",
"install_methods": [
{
"type": "default",
"script": "ct/autocaliweb.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 6,
"os": "Debian",
"version": "12"
}
}
],
"default_credentials": {
"username": "admin",
"password": "admin123"
},
"notes": []
}

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2025-01-20", "date_created": "2025-01-20",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 8090, "interface_port": 8090,
"documentation": "https://beszel.dev/guide/what-is-beszel", "documentation": "https://beszel.dev/guide/what-is-beszel",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 4000, "interface_port": 4000,
"documentation": "https://0xerr0r.github.io/blocky/latest/configuration/", "documentation": "https://0xerr0r.github.io/blocky/latest/configuration/",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2025-05-22", "date_created": "2025-05-22",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
"documentation": "https://github.com/favonia/cloudflare-ddns/blob/main/README.markdown", "documentation": "https://github.com/favonia/cloudflare-ddns/blob/main/README.markdown",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
"documentation": "https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/", "documentation": "https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 4000, "interface_port": 4000,
"documentation": "https://dashy.to/docs", "documentation": "https://dashy.to/docs",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": true, "privileged": true,
"interface_port": 80, "interface_port": 80,
"documentation": "https://github.com/dresden-elektronik/deconz-rest-plugin/wiki", "documentation": "https://github.com/dresden-elektronik/deconz-rest-plugin/wiki",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 8112, "interface_port": 8112,
"documentation": "https://www.deluge-torrent.org/userguide/", "documentation": "https://www.deluge-torrent.org/userguide/",

View File

@@ -21,7 +21,7 @@
"resources": { "resources": {
"cpu": 2, "cpu": 2,
"ram": 1024, "ram": 1024,
"hdd": 4, "hdd": 10,
"os": "debian", "os": "debian",
"version": "12" "version": "12"
} }

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 8083, "interface_port": 8083,
"documentation": "https://fhem.de/#Documentation", "documentation": "https://fhem.de/#Documentation",

View File

@@ -7,7 +7,7 @@
], ],
"date_created": "2025-06-18", "date_created": "2025-06-18",
"type": "addon", "type": "addon",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 8080, "interface_port": 8080,
"documentation": "https://github.com/gtsteffaniak/filebrowser/wiki/Getting-Started", "documentation": "https://github.com/gtsteffaniak/filebrowser/wiki/Getting-Started",

View File

@@ -7,7 +7,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "addon", "type": "addon",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 8080, "interface_port": 8080,
"documentation": null, "documentation": null,

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 8581, "interface_port": 8581,
"documentation": "https://github.com/homebridge/homebridge/wiki", "documentation": "https://github.com/homebridge/homebridge/wiki",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": true, "privileged": true,
"interface_port": 8090, "interface_port": 8090,
"documentation": "https://github.com/awawa-dev/HyperHDR/wiki", "documentation": "https://github.com/awawa-dev/HyperHDR/wiki",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 8086, "interface_port": 8086,
"documentation": "https://docs.influxdata.com/", "documentation": "https://docs.influxdata.com/",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2025-07-29", "date_created": "2025-07-29",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 80, "interface_port": 80,
"documentation": "https://doc.jeedom.com", "documentation": "https://doc.jeedom.com",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-12-26", "date_created": "2024-12-26",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 8080, "interface_port": 8080,
"documentation": "https://www.jenkins.io/doc/", "documentation": "https://www.jenkins.io/doc/",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 5299, "interface_port": 5299,
"documentation": "https://lazylibrarian.gitlab.io/lazylibrarian.gitlab.io/", "documentation": "https://lazylibrarian.gitlab.io/lazylibrarian.gitlab.io/",

View File

@@ -0,0 +1,35 @@
{
"name": "Leantime",
"slug": "leantime",
"categories": [
12
],
"date_created": "2025-09-06",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 80,
"documentation": "https://docs.leantime.io/",
"config_path": "/opt/Leantime/config/.env",
"website": "https://leantime.io",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/leantime.webp",
"description": "Leantime is a goals focused project management system for non-project managers. Building with ADHD, Autism, and dyslexia in mind. ",
"install_methods": [
{
"type": "default",
"script": "ct/leantime.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 20,
"os": "Debian",
"version": "12"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-08-06", "date_created": "2024-08-06",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 17170, "interface_port": 17170,
"documentation": "https://github.com/lldap/lldap/blob/main/README.md", "documentation": "https://github.com/lldap/lldap/blob/main/README.md",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 3306, "interface_port": 3306,
"documentation": "https://github.com/community-scripts/ProxmoxVE/discussions/192", "documentation": "https://github.com/community-scripts/ProxmoxVE/discussions/192",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2025-01-30", "date_created": "2025-01-30",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 8065, "interface_port": 8065,
"documentation": "https://docs.mattermost.com/", "documentation": "https://docs.mattermost.com/",

View File

@@ -11,7 +11,7 @@
"privileged": false, "privileged": false,
"interface_port": 8000, "interface_port": 8000,
"documentation": "https://maxdorninger.github.io/MediaManager/introduction.html", "documentation": "https://maxdorninger.github.io/MediaManager/introduction.html",
"config_path": "/opt/mm_data/config.toml", "config_path": "/opt/mm/config/config.toml",
"website": "https://github.com/maxdorninger/MediaManager", "website": "https://github.com/maxdorninger/MediaManager",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/mediamanager.webp", "logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/mediamanager.webp",
"description": "A modern selfhosted media management system for your media library", "description": "A modern selfhosted media management system for your media library",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-18", "date_created": "2024-05-18",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 27017, "interface_port": 27017,
"documentation": "https://www.mongodb.com/docs/manual/", "documentation": "https://www.mongodb.com/docs/manual/",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
"documentation": "https://mosquitto.org/documentation/", "documentation": "https://mosquitto.org/documentation/",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2025-03-13", "date_created": "2025-03-13",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 81, "interface_port": 81,
"documentation": "https://github.com/ZoeyVid/NPMplus/blob/develop/README.md", "documentation": "https://github.com/ZoeyVid/NPMplus/blob/develop/README.md",
@@ -39,7 +39,7 @@
} }
], ],
"default_credentials": { "default_credentials": {
"username": "root", "username": "admin@example.org",
"password": null "password": null
}, },
"notes": [ "notes": [
@@ -52,7 +52,7 @@
"type": "info" "type": "info"
}, },
{ {
"text": "Application credentials: `cat /opt/.npm_pwd`", "text": "Application credentials: `cat /opt/.npm_pwd` - if file not exist in LXC check docker logs for password with `docker logs npmplus`",
"type": "info" "type": "info"
} }
] ]

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 80, "interface_port": 80,
"documentation": "https://docs.ntfy.sh/", "documentation": "https://docs.ntfy.sh/",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 80, "interface_port": 80,
"documentation": "https://docs.openmediavault.org/en/stable/", "documentation": "https://docs.openmediavault.org/en/stable/",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 8443, "interface_port": 8443,
"documentation": "https://www.openhab.org/docs/", "documentation": "https://www.openhab.org/docs/",

View File

@@ -33,11 +33,7 @@
}, },
"notes": [ "notes": [
{ {
"text": "This LXC is very memory-hungry when updating; it requires at least 6GB RAM, but RAM may be reduced to as low as 2GB when running normally", "text": "To use a bind mount for storage, create symlinks to your mount for both `uploads` and `temp-uploads` in `/opt/palmr_data`, and uncomment `CUSTOM_PATH` to add the path to your bind mount",
"type": "warning"
},
{
"text": "To use a bind mount for storage, create symlinks to your mount for both `uploads` and `temp-uploads` in `/opt/palmr_data`",
"type": "info" "type": "info"
}, },
{ {

View File

@@ -28,7 +28,7 @@
} }
], ],
"default_credentials": { "default_credentials": {
"username": "admin", "username": null,
"password": null "password": null
}, },
"notes": [ "notes": [

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
"documentation": "https://github.com/leiweibau/Pi.Alert/blob/main/README.md", "documentation": "https://github.com/leiweibau/Pi.Alert/blob/main/README.md",
@@ -31,10 +31,5 @@
"username": null, "username": null,
"password": null "password": null
}, },
"notes": [ "notes": []
{
"text": "WARNING: Installation sources scripts outside of Community Scripts repo. Please check the source before installing.",
"type": "warning"
}
]
} }

View File

@@ -35,10 +35,6 @@
{ {
"text": "With Privileged/Unprivileged Hardware Acceleration Support", "text": "With Privileged/Unprivileged Hardware Acceleration Support",
"type": "info" "type": "info"
},
{
"text": "WARNING: Installation sources scripts outside of Community Scripts repo. Please check the source before installing.",
"type": "warning"
} }
] ]
} }

View File

@@ -43,10 +43,6 @@
{ {
"text": "Options to Install Portainer or Portainer Agent", "text": "Options to Install Portainer or Portainer Agent",
"type": "warning" "type": "warning"
},
{
"text": "WARNING: Installation sources scripts outside of Community Scripts repo. Please check the source before installing.",
"type": "warning"
} }
] ]
} }

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2025-02-02", "date_created": "2025-02-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 5232, "interface_port": 5232,
"documentation": "https://radicale.org/master.html#documentation-1", "documentation": "https://radicale.org/master.html#documentation-1",

View File

@@ -0,0 +1,40 @@
{
"name": "Resilio Sync",
"slug": "resiliosync",
"categories": [
11
],
"date_created": "2025-09-06",
"type": "ct",
"updateable": true,
"privileged": false,
"config_path": "/etc/resilio-sync/config.json",
"interface_port": 8888,
"documentation": "https://help.resilio.com/",
"website": "https://www.resilio.com/sync",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/resilio-sync.webp",
"description": "Fast, reliable, and simple file sync and share solution, powered by P2P technology. Sync files across all your devices without storing them in the cloud.",
"install_methods": [
{
"type": "default",
"script": "ct/resiliosync.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 8,
"os": "debian",
"version": "12"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "After free registration, you will receive a license keyfile to your email address. Upload it into any LXC directory and select on first run.",
"type": "info"
}
]
}

View File

@@ -48,7 +48,11 @@
"type": "info" "type": "info"
}, },
{ {
"text": "Login credentials: `cat ~/rustdesk.creds`", "text": "To set admin password on Debian, type `cd /var/lib/rustdesk-api && rustdesk-api reset-admin-pwd <yournewpasswordhere>` inside LXC.",
"type": "info"
},
{
"text": "To see admin password on Alpine, type `cat ~/rustdesk.creds` inside LXC.",
"type": "info" "type": "info"
} }
] ]

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": null, "interface_port": null,
"documentation": "https://oss.oetiker.ch/smokeping/doc/index.en.html", "documentation": "https://oss.oetiker.ch/smokeping/doc/index.en.html",

View File

@@ -0,0 +1,35 @@
{
"name": "Stylus",
"slug": "stylus",
"categories": [
4
],
"date_created": "2025-09-12",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 8000,
"documentation": "https://mmastrac.github.io/stylus/",
"website": "https://github.com/mmastrac/stylus",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/stylus.webp",
"config_path": "/opt/stylus/config.yaml",
"description": "Stylus (style + status) is a lightweight status page for infrastructure and networks. Configure a set of bash scripts that test the various parts of your infrastructure, set up visualizations with minimal configuration, and Stylus will generate you a dashboard for your system.",
"install_methods": [
{
"type": "default",
"script": "ct/stylus.sh",
"resources": {
"cpu": 1,
"ram": 1024,
"hdd": 2,
"os": "debian",
"version": "12"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -2,7 +2,7 @@
"name": "Swizzin", "name": "Swizzin",
"slug": "swizzin", "slug": "swizzin",
"categories": [ "categories": [
15 13
], ],
"date_created": "2025-08-19", "date_created": "2025-08-19",
"type": "ct", "type": "ct",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 8384, "interface_port": 8384,
"documentation": "https://docs.syncthing.net/", "documentation": "https://docs.syncthing.net/",

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 8181, "interface_port": 8181,
"documentation": "https://github.com/Tautulli/Tautulli/wiki", "documentation": "https://github.com/Tautulli/Tautulli/wiki",

View File

@@ -0,0 +1,40 @@
{
"name": "Telegraf",
"slug": "telegraf",
"categories": [
9
],
"date_created": "2025-09-11",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": null,
"documentation": "https://docs.influxdata.com/telegraf/v1/",
"config_path": "/etc/telegraf/telegraf.conf",
"website": "https://github.com/influxdata/telegraf",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/telegraf.webp",
"description": "Telegraf collects and sends time series data from databases, systems, and IoT sensors. It has no external dependencies, is easy to install, and requires minimal memory.",
"install_methods": [
{
"type": "default",
"script": "ct/telegraf.sh",
"resources": {
"cpu": 1,
"ram": 1024,
"hdd": 4,
"os": "Debian",
"version": "12"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": [
{
"text": "Make sure to configure an output for the telegraf config and start the service with `systemctl start telegraf`.",
"type": "info"
}
]
}

View File

@@ -0,0 +1,35 @@
{
"name": "UHF Server",
"slug": "uhf",
"categories": [
13
],
"date_created": "2025-09-12",
"type": "ct",
"updateable": true,
"privileged": false,
"interface_port": 7568,
"documentation": "https://www.uhfapp.com/server",
"website": "https://www.uhfapp.com/",
"logo": "https://cdn.jsdelivr.net/gh/selfhst/icons/webp/uhf.webp",
"config_path": "/etc/uhf-server/",
"description": "UHF Server is a powerful companion app that lets you seamlessly schedule and record your favorite shows from the UHF app.",
"install_methods": [
{
"type": "default",
"script": "ct/uhf.sh",
"resources": {
"cpu": 2,
"ram": 2048,
"hdd": 8,
"os": "Debian",
"version": "12"
}
}
],
"default_credentials": {
"username": null,
"password": null
},
"notes": []
}

View File

@@ -6,7 +6,7 @@
], ],
"date_created": "2024-05-02", "date_created": "2024-05-02",
"type": "ct", "type": "ct",
"updateable": false, "updateable": true,
"privileged": false, "privileged": false,
"interface_port": 8443, "interface_port": 8443,
"documentation": null, "documentation": null,

File diff suppressed because it is too large Load Diff

View File

@@ -73,7 +73,13 @@ function CategoryView() {
}; };
const handleScriptClick = (scriptSlug: string) => { const handleScriptClick = (scriptSlug: string) => {
router.push(`/scripts?id=${scriptSlug}`); // Include category context when navigating to scripts
const categoryName = selectedCategoryIndex !== null ? categories[selectedCategoryIndex]?.name : null;
const queryParams = new URLSearchParams({ id: scriptSlug });
if (categoryName) {
queryParams.append("category", categoryName);
}
router.push(`/scripts?${queryParams.toString()}`);
}; };
const navigateCategory = (direction: "prev" | "next") => { const navigateCategory = (direction: "prev" | "next") => {

View File

@@ -38,6 +38,7 @@ const DataFetcher: React.FC = () => {
const [currentPage, setCurrentPage] = useState(1); const [currentPage, setCurrentPage] = useState(1);
const [itemsPerPage, setItemsPerPage] = useState(25); const [itemsPerPage, setItemsPerPage] = useState(25);
const [sortConfig, setSortConfig] = useState<{ key: string; direction: "ascending" | "descending" } | null>(null); const [sortConfig, setSortConfig] = useState<{ key: string; direction: "ascending" | "descending" } | null>(null);
const nf = new Intl.NumberFormat("en-US", { maximumFractionDigits: 0 });
useEffect(() => { useEffect(() => {
const fetchSummary = async () => { const fetchSummary = async () => {
@@ -129,19 +130,24 @@ const DataFetcher: React.FC = () => {
<p className="text-lg font-bold mt-4"> </p> <p className="text-lg font-bold mt-4"> </p>
<div className="mb-4 flex justify-between items-center"> <div className="mb-4 flex justify-between items-center">
<p className="text-lg font-bold"> <p className="text-lg font-bold">
{summary?.total_entries} {nf.format(
summary?.total_entries ?? 0,
)}
{" "} {" "}
results found results found
</p> </p>
<p className="text-lg font"> <p className="text-lg font">
Status Legend: 🔄 installing Status Legend: 🔄 installing
{summary?.status_count.installing ?? 0} {" "}
{nf.format(summary?.status_count.installing ?? 0)}
{" "} {" "}
| completed | completed
{summary?.status_count.done ?? 0} {" "}
{nf.format(summary?.status_count.done ?? 0)}
{" "} {" "}
| failed | failed
{summary?.status_count.failed ?? 0} {" "}
{nf.format(summary?.status_count.failed ?? 0)}
{" "} {" "}
| unknown | unknown
</p> </p>

View File

@@ -4,12 +4,7 @@ import Link from "next/link";
import type { Category } from "@/lib/types"; import type { Category } from "@/lib/types";
import { import { Accordion, AccordionContent, AccordionItem, AccordionTrigger } from "@/components/ui/accordion";
Accordion,
AccordionContent,
AccordionItem,
AccordionTrigger,
} from "@/components/ui/accordion";
import { formattedBadge } from "@/components/command-menu"; import { formattedBadge } from "@/components/command-menu";
import { basePath } from "@/config/site-config"; import { basePath } from "@/config/site-config";
import { cn } from "@/lib/utils"; import { cn } from "@/lib/utils";
@@ -18,14 +13,16 @@ export default function ScriptAccordion({
items, items,
selectedScript, selectedScript,
setSelectedScript, setSelectedScript,
selectedCategory,
setSelectedCategory,
}: { }: {
items: Category[]; items: Category[];
selectedScript: string | null; selectedScript: string | null;
setSelectedScript: (script: string | null) => void; setSelectedScript: (script: string | null) => void;
selectedCategory: string | null;
setSelectedCategory: (category: string | null) => void;
}) { }) {
const [expandedItem, setExpandedItem] = useState<string | undefined>( const [expandedItem, setExpandedItem] = useState<string | undefined>(undefined);
undefined,
);
const linkRefs = useRef<{ [key: string]: HTMLAnchorElement | null }>({}); const linkRefs = useRef<{ [key: string]: HTMLAnchorElement | null }>({});
const handleAccordionChange = (value: string | undefined) => { const handleAccordionChange = (value: string | undefined) => {
@@ -41,15 +38,27 @@ export default function ScriptAccordion({
useEffect(() => { useEffect(() => {
if (selectedScript) { if (selectedScript) {
const category = items.find(category => let category;
category.scripts.some(script => script.slug === selectedScript),
// If we have a selected category, try to find the script in that specific category
if (selectedCategory) {
category = items.find(
cat => cat.name === selectedCategory && cat.scripts.some(script => script.slug === selectedScript),
); );
}
// Fallback: if no category is selected or script not found in selected category,
// use the first category containing the script (backward compatibility)
if (!category) {
category = items.find(category => category.scripts.some(script => script.slug === selectedScript));
}
if (category) { if (category) {
setExpandedItem(category.name); setExpandedItem(category.name);
handleSelected(selectedScript); handleSelected(selectedScript);
} }
} }
}, [selectedScript, items, handleSelected]); }, [selectedScript, selectedCategory, items, handleSelected]);
return ( return (
<Accordion <Accordion
type="single" type="single"
@@ -82,10 +91,7 @@ export default function ScriptAccordion({
</div> </div>
{" "} {" "}
</AccordionTrigger> </AccordionTrigger>
<AccordionContent <AccordionContent data-state={expandedItem === category.name ? "open" : "closed"} className="pt-0">
data-state={expandedItem === category.name ? "open" : "closed"}
className="pt-0"
>
{category.scripts {category.scripts
.slice() .slice()
.sort((a, b) => a.name.localeCompare(b.name)) .sort((a, b) => a.name.localeCompare(b.name))
@@ -94,7 +100,7 @@ export default function ScriptAccordion({
<Link <Link
href={{ href={{
pathname: "/scripts", pathname: "/scripts",
query: { id: script.slug }, query: { id: script.slug, category: category.name },
}} }}
prefetch={false} prefetch={false}
className={`flex cursor-pointer items-center justify-between gap-1 px-1 py-1 text-muted-foreground hover:rounded-lg hover:bg-accent/60 hover:dark:bg-accent/20 ${ className={`flex cursor-pointer items-center justify-between gap-1 px-1 py-1 text-muted-foreground hover:rounded-lg hover:bg-accent/60 hover:dark:bg-accent/20 ${
@@ -102,7 +108,10 @@ export default function ScriptAccordion({
? "rounded-lg bg-accent font-semibold dark:bg-accent/30 dark:text-white" ? "rounded-lg bg-accent font-semibold dark:bg-accent/30 dark:text-white"
: "" : ""
}`} }`}
onClick={() => handleSelected(script.slug)} onClick={() => {
handleSelected(script.slug);
setSelectedCategory(category.name);
}}
ref={(el) => { ref={(el) => {
linkRefs.current[script.slug] = el; linkRefs.current[script.slug] = el;
}} }}
@@ -113,15 +122,11 @@ export default function ScriptAccordion({
height={16} height={16}
width={16} width={16}
unoptimized unoptimized
onError={e => onError={e => ((e.currentTarget as HTMLImageElement).src = `/${basePath}/logo.png`)}
((e.currentTarget as HTMLImageElement).src
= `/${basePath}/logo.png`)}
alt={script.name} alt={script.name}
className="mr-1 w-4 h-4 rounded-full" className="mr-1 w-4 h-4 rounded-full"
/> />
<span className="flex items-center gap-2"> <span className="flex items-center gap-2">{script.name}</span>
{script.name}
</span>
</div> </div>
{formattedBadge(script.type)} {formattedBadge(script.type)}
</Link> </Link>

View File

@@ -143,7 +143,7 @@ export function MostViewedScripts({ items }: { items: Category[] }) {
<div className=""> <div className="">
{mostViewedScripts.length > 0 && ( {mostViewedScripts.length > 0 && (
<> <>
<h2 className="text-lg font-semibold">Most Viewed Scripts</h2> <h2 className="text-lg font-semibold mb-1">Most Viewed Scripts</h2>
</> </>
)} )}
<div className="min-w flex w-full flex-row flex-wrap gap-4"> <div className="min-w flex w-full flex-row flex-wrap gap-4">

View File

@@ -8,10 +8,14 @@ function Sidebar({
items, items,
selectedScript, selectedScript,
setSelectedScript, setSelectedScript,
selectedCategory,
setSelectedCategory,
}: { }: {
items: Category[]; items: Category[];
selectedScript: string | null; selectedScript: string | null;
setSelectedScript: (script: string | null) => void; setSelectedScript: (script: string | null) => void;
selectedCategory: string | null;
setSelectedCategory: (category: string | null) => void;
}) { }) {
const uniqueScripts = items.reduce((acc, category) => { const uniqueScripts = items.reduce((acc, category) => {
for (const script of category.scripts) { for (const script of category.scripts) {
@@ -37,6 +41,8 @@ function Sidebar({
items={items} items={items}
selectedScript={selectedScript} selectedScript={selectedScript}
setSelectedScript={setSelectedScript} setSelectedScript={setSelectedScript}
selectedCategory={selectedCategory}
setSelectedCategory={setSelectedCategory}
/> />
</div> </div>
</div> </div>

View File

@@ -8,16 +8,14 @@ import type { Category, Script } from "@/lib/types";
import { ScriptItem } from "@/app/scripts/_components/script-item"; import { ScriptItem } from "@/app/scripts/_components/script-item";
import { fetchCategories } from "@/lib/data"; import { fetchCategories } from "@/lib/data";
import { import { LatestScripts, MostViewedScripts } from "./_components/script-info-blocks";
LatestScripts,
MostViewedScripts,
} from "./_components/script-info-blocks";
import Sidebar from "./_components/sidebar"; import Sidebar from "./_components/sidebar";
export const dynamic = "force-static"; export const dynamic = "force-static";
function ScriptContent() { function ScriptContent() {
const [selectedScript, setSelectedScript] = useQueryState("id"); const [selectedScript, setSelectedScript] = useQueryState("id");
const [selectedCategory, setSelectedCategory] = useQueryState("category");
const [links, setLinks] = useState<Category[]>([]); const [links, setLinks] = useState<Category[]>([]);
const [item, setItem] = useState<Script>(); const [item, setItem] = useState<Script>();
@@ -47,6 +45,8 @@ function ScriptContent() {
items={links} items={links}
selectedScript={selectedScript} selectedScript={selectedScript}
setSelectedScript={setSelectedScript} setSelectedScript={setSelectedScript}
selectedCategory={selectedCategory}
setSelectedCategory={setSelectedCategory}
/> />
</div> </div>
<div className="mx-4 w-full sm:mx-0 sm:ml-4"> <div className="mx-4 w-full sm:mx-0 sm:ml-4">

View File

@@ -0,0 +1,61 @@
"use client";
import type { VariantProps } from "class-variance-authority";
import { cva } from "class-variance-authority";
import * as React from "react";
import type { ButtonProps as ButtonPrimitiveProps } from "@/components/animate-ui/primitives/buttons/button";
import {
Button as ButtonPrimitive,
} from "@/components/animate-ui/primitives/buttons/button";
import { cn } from "@/lib/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[box-shadow,_color,_background-color,_border-color,_outline-color,_text-decoration-color,_fill,_stroke] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
{
variants: {
variant: {
default:
"bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
accent: "bg-accent text-accent-foreground shadow-xs hover:bg-accent/90",
destructive:
"bg-destructive text-white shadow-xs hover:bg-destructive/90 focus-visible:ring-destructive/20 dark:focus-visible:ring-destructive/40 dark:bg-destructive/60",
outline:
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
secondary:
"bg-secondary text-secondary-foreground shadow-xs hover:bg-secondary/80",
ghost:
"hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
link: "text-primary underline-offset-4 hover:underline",
},
size: {
"default": "h-9 px-4 py-2 has-[>svg]:px-3",
"sm": "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
"lg": "h-10 rounded-md px-6 has-[>svg]:px-4",
"icon": "size-9",
"icon-sm": "size-8 rounded-md",
"icon-lg": "size-10 rounded-md",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
);
type ButtonProps = ButtonPrimitiveProps & VariantProps<typeof buttonVariants>;
function Button({ className, variant, size, ...props }: ButtonProps) {
return (
<ButtonPrimitive
className={cn(buttonVariants({ variant, size, className }))}
{...props}
/>
);
}
export { Button, type ButtonProps, buttonVariants };

View File

@@ -0,0 +1,109 @@
import type { VariantProps } from "class-variance-authority";
import { cva } from "class-variance-authority";
import { StarIcon } from "lucide-react";
import Link from "next/link";
import type { ButtonProps as ButtonPrimitiveProps } from "@/components/animate-ui/primitives/buttons/button";
import type { GithubStarsProps } from "@/components/animate-ui/primitives/animate/github-stars";
import {
GithubStars,
GithubStarsIcon,
GithubStarsLogo,
GithubStarsNumber,
GithubStarsParticles,
} from "@/components/animate-ui/primitives/animate/github-stars";
import { Button as ButtonPrimitive } from "@/components/animate-ui/primitives/buttons/button";
import { cn } from "@/lib/utils";
const buttonVariants = cva(
"inline-flex items-center justify-center gap-2 whitespace-nowrap rounded-md text-sm font-medium transition-[box-shadow,_color,_background-color,_border-color,_outline-color,_text-decoration-color,_fill,_stroke] disabled:pointer-events-none disabled:opacity-50 [&_svg]:pointer-events-none [&_svg:not([class*='size-'])]:size-4 shrink-0 [&_svg]:shrink-0 outline-none focus-visible:border-ring focus-visible:ring-ring/50 focus-visible:ring-[3px] aria-invalid:ring-destructive/20 dark:aria-invalid:ring-destructive/40 aria-invalid:border-destructive",
{
variants: {
variant: {
default: "bg-primary text-primary-foreground shadow-xs hover:bg-primary/90",
accent: "bg-accent text-accent-foreground shadow-xs hover:bg-accent/90",
outline:
"border bg-background shadow-xs hover:bg-accent hover:text-accent-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50",
ghost: "hover:bg-accent hover:text-accent-foreground dark:hover:bg-accent/50",
},
size: {
default: "h-9 px-4 py-2 has-[>svg]:px-3",
sm: "h-8 rounded-md gap-1.5 px-3 has-[>svg]:px-2.5",
lg: "h-10 rounded-md px-6 has-[>svg]:px-4",
},
},
defaultVariants: {
variant: "default",
size: "default",
},
},
);
const buttonStarVariants = cva("", {
variants: {
variant: {
default: "fill-neutral-700 stroke-neutral-700 dark:fill-neutral-300 dark:stroke-neutral-300",
accent: "fill-neutral-300 stroke-neutral-300 dark:fill-neutral-700 dark:stroke-neutral-700",
outline: "fill-neutral-300 stroke-neutral-300 dark:fill-neutral-700 dark:stroke-neutral-700",
ghost: "fill-neutral-300 stroke-neutral-300 dark:fill-neutral-700 dark:stroke-neutral-700",
},
},
defaultVariants: {
variant: "default",
},
});
type GitHubStarsButtonProps = Omit<ButtonPrimitiveProps & GithubStarsProps, "asChild" | "children">
& VariantProps<typeof buttonVariants>;
function GitHubStarsButton({
className,
username,
repo,
value,
delay,
inView,
inViewMargin,
inViewOnce,
variant,
size,
...props
}: GitHubStarsButtonProps) {
return (
<Link
target="_blank"
rel="noopener noreferrer"
data-umami-event="github-stars"
href={`https://github.com/${username}/${repo}`}
>
<GithubStars
asChild
username={username}
repo={repo}
value={value}
delay={delay}
inView={inView}
inViewMargin={inViewMargin}
inViewOnce={inViewOnce}
>
<ButtonPrimitive className={cn(buttonVariants({ variant, size, className }))} {...props}>
<GithubStarsLogo />
<GithubStarsNumber />
<GithubStarsParticles className="text-yellow-500">
<GithubStarsIcon
icon={StarIcon}
data-variant={variant}
className={cn(buttonStarVariants({ variant }))}
activeClassName="text-yellow-500"
size={18}
/>
</GithubStarsParticles>
</ButtonPrimitive>
</GithubStars>
</Link>
);
}
export { GitHubStarsButton, type GitHubStarsButtonProps };

View File

@@ -0,0 +1,206 @@
"use client";
import type { HTMLMotionProps } from "motion/react";
import { motion } from "motion/react";
import * as React from "react";
import type { SlidingNumberProps } from "@/components/animate-ui/primitives/texts/sliding-number";
import type { ParticlesEffectProps } from "@/components/animate-ui/primitives/effects/particles";
import type { WithAsChild } from "@/components/animate-ui/primitives/animate/slot";
import type { UseIsInViewOptions } from "@/hooks/use-is-in-view";
import { Particles, ParticlesEffect } from "@/components/animate-ui/primitives/effects/particles";
import { SlidingNumber } from "@/components/animate-ui/primitives/texts/sliding-number";
import { Slot } from "@/components/animate-ui/primitives/animate/slot";
import { getStrictContext } from "@/lib/get-strict-context";
import { useIsInView } from "@/hooks/use-is-in-view";
import { cn } from "@/lib/utils";
type GithubStarsContextType = {
stars: number;
setStars: (stars: number) => void;
currentStars: number;
setCurrentStars: (stars: number) => void;
isCompleted: boolean;
isLoading: boolean;
};
const [GithubStarsProvider, useGithubStars] = getStrictContext<GithubStarsContextType>("GithubStarsContext");
type GithubStarsProps = WithAsChild<
{
children: React.ReactNode;
username?: string;
repo?: string;
value?: number;
delay?: number;
} & UseIsInViewOptions
& HTMLMotionProps<"div">
>;
function GithubStars({
ref,
children,
username,
repo,
value,
delay = 0,
inView = false,
inViewMargin = "0px",
inViewOnce = true,
asChild = false,
...props
}: GithubStarsProps) {
const { ref: localRef, isInView } = useIsInView(ref as React.Ref<HTMLDivElement>, {
inView,
inViewOnce,
inViewMargin,
});
const [stars, setStars] = React.useState(value ?? 0);
const [currentStars, setCurrentStars] = React.useState(0);
const [isLoading, setIsLoading] = React.useState(true);
const isCompleted = React.useMemo(() => currentStars === stars, [currentStars, stars]);
const Component = asChild ? Slot : motion.div;
React.useEffect(() => {
if (value !== undefined && username && repo)
return;
if (!isInView) {
setStars(0);
setIsLoading(true);
return;
}
const timeout = setTimeout(() => {
fetch(`https://api.github.com/repos/${username}/${repo}`)
.then(response => response.json())
.then((data) => {
if (data && typeof data.stargazers_count === "number") {
setStars(data.stargazers_count);
}
})
.catch(console.error)
.finally(() => setIsLoading(false));
}, delay);
return () => clearTimeout(timeout);
}, [username, repo, value, isInView, delay]);
return (
<GithubStarsProvider
value={{
stars,
currentStars,
isCompleted,
isLoading,
setStars,
setCurrentStars,
}}
>
{!isLoading && (
<Component ref={localRef} {...props}>
{children}
</Component>
)}
</GithubStarsProvider>
);
}
type GithubStarsNumberProps = Omit<SlidingNumberProps, "number" | "fromNumber">;
function GithubStarsNumber({ padStart = true, ...props }: GithubStarsNumberProps) {
const { stars, setCurrentStars } = useGithubStars();
return (
<SlidingNumber number={stars} fromNumber={0} onNumberChange={setCurrentStars} padStart={padStart} {...props} />
);
}
type GithubStarsIconProps<T extends React.ElementType> = {
icon: React.ReactElement<T>;
color?: string;
activeClassName?: string;
} & React.ComponentProps<T>;
function GithubStarsIcon<T extends React.ElementType>({
icon: Icon,
color = "currentColor",
activeClassName,
className,
...props
}: GithubStarsIconProps<T>) {
const { stars, currentStars, isCompleted } = useGithubStars();
const fillPercentage = (currentStars / stars) * 100;
return (
<div style={{ position: "relative" }}>
<Icon aria-hidden="true" className={cn(className)} {...props} />
<Icon
aria-hidden="true"
style={{
position: "absolute",
top: 0,
left: 0,
fill: color,
stroke: color,
clipPath: `inset(${100 - (isCompleted ? fillPercentage : fillPercentage - 10)}% 0 0 0)`,
}}
className={cn(className, activeClassName)}
{...props}
/>
</div>
);
}
type GithubStarsParticlesProps = ParticlesEffectProps & {
children: React.ReactElement;
size?: number;
};
function GithubStarsParticles({ children, size = 4, style, ...props }: GithubStarsParticlesProps) {
const { isCompleted } = useGithubStars();
return (
<Particles animate={isCompleted}>
{children}
<ParticlesEffect
style={{
backgroundColor: "currentcolor",
borderRadius: "50%",
width: size,
height: size,
...style,
}}
{...props}
/>
</Particles>
);
}
type GithubStarsLogoProps = React.SVGProps<SVGSVGElement>;
function GithubStarsLogo(props: GithubStarsLogoProps) {
return (
<svg role="img" viewBox="0 0 24 24" fill="currentColor" aria-label="GitHub" {...props}>
<path d="M12 .297c-6.63 0-12 5.373-12 12 0 5.303 3.438 9.8 8.205 11.385.6.113.82-.258.82-.577 0-.285-.01-1.04-.015-2.04-3.338.724-4.042-1.61-4.042-1.61C4.422 18.07 3.633 17.7 3.633 17.7c-1.087-.744.084-.729.084-.729 1.205.084 1.838 1.236 1.838 1.236 1.07 1.835 2.809 1.305 3.495.998.108-.776.417-1.305.76-1.605-2.665-.3-5.466-1.332-5.466-5.93 0-1.31.465-2.38 1.235-3.22-.135-.303-.54-1.523.105-3.176 0 0 1.005-.322 3.3 1.23.96-.267 1.98-.399 3-.405 1.02.006 2.04.138 3 .405 2.28-1.552 3.285-1.23 3.285-1.23.645 1.653.24 2.873.12 3.176.765.84 1.23 1.91 1.23 3.22 0 4.61-2.805 5.625-5.475 5.92.42.36.81 1.096.81 2.22 0 1.606-.015 2.896-.015 3.286 0 .315.21.69.825.57C20.565 22.092 24 17.592 24 12.297c0-6.627-5.373-12-12-12"></path>
</svg>
);
}
export {
GithubStars,
type GithubStarsContextType,
GithubStarsIcon,
type GithubStarsIconProps,
GithubStarsLogo,
type GithubStarsLogoProps,
GithubStarsNumber,
type GithubStarsNumberProps,
GithubStarsParticles,
type GithubStarsParticlesProps,
type GithubStarsProps,
useGithubStars,
};

View File

@@ -0,0 +1,101 @@
"use client";
import type { HTMLMotionProps } from "motion/react";
import { isMotionComponent, motion } from "motion/react";
import * as React from "react";
import { cn } from "@/lib/utils";
type AnyProps = Record<string, unknown>;
type DOMMotionProps<T extends HTMLElement = HTMLElement> = Omit<
HTMLMotionProps<keyof HTMLElementTagNameMap>,
"ref"
> & { ref?: React.Ref<T> };
type WithAsChild<Base extends object>
= | (Base & { asChild: true; children: React.ReactElement })
| (Base & { asChild?: false | undefined });
type SlotProps<T extends HTMLElement = HTMLElement> = {
children?: any;
} & DOMMotionProps<T>;
function mergeRefs<T>(
...refs: (React.Ref<T> | undefined)[]
): React.RefCallback<T> {
return (node) => {
refs.forEach((ref) => {
if (!ref)
return;
if (typeof ref === "function") {
ref(node);
}
else {
(ref as React.RefObject<T | null>).current = node;
}
});
};
}
function mergeProps<T extends HTMLElement>(
childProps: AnyProps,
slotProps: DOMMotionProps<T>,
): AnyProps {
const merged: AnyProps = { ...childProps, ...slotProps };
if (childProps.className || slotProps.className) {
merged.className = cn(
childProps.className as string,
slotProps.className as string,
);
}
if (childProps.style || slotProps.style) {
merged.style = {
...(childProps.style as React.CSSProperties),
...(slotProps.style as React.CSSProperties),
};
}
return merged;
}
function Slot<T extends HTMLElement = HTMLElement>({
children,
ref,
...props
}: SlotProps<T>) {
const isAlreadyMotion
= typeof children.type === "object"
&& children.type !== null
&& isMotionComponent(children.type);
const Base = React.useMemo(
() =>
isAlreadyMotion
? (children.type as React.ElementType)
: motion.create(children.type as React.ElementType),
[isAlreadyMotion, children.type],
);
if (!React.isValidElement(children))
return null;
const { ref: childRef, ...childProps } = children.props as AnyProps;
const mergedProps = mergeProps(childProps, props);
return (
<Base {...mergedProps} ref={mergeRefs(childRef as React.Ref<T>, ref)} />
);
}
export {
type AnyProps,
type DOMMotionProps,
Slot,
type SlotProps,
type WithAsChild,
};

View File

@@ -0,0 +1,36 @@
"use client";
import type { HTMLMotionProps } from "motion/react";
import { motion } from "motion/react";
import * as React from "react";
import type { WithAsChild } from "@/components/animate-ui/primitives/animate/slot";
import { Slot } from "@/components/animate-ui/primitives/animate/slot";
type ButtonProps = WithAsChild<
HTMLMotionProps<"button"> & {
hoverScale?: number;
tapScale?: number;
}
>;
function Button({
hoverScale = 1.05,
tapScale = 0.95,
asChild = false,
...props
}: ButtonProps) {
const Component = asChild ? Slot : motion.button;
return (
<Component
whileTap={{ scale: tapScale }}
whileHover={{ scale: hoverScale }}
{...props}
/>
);
}
export { Button, type ButtonProps };

View File

@@ -0,0 +1,160 @@
"use client";
import type { HTMLMotionProps } from "motion/react";
import { AnimatePresence, motion } from "motion/react";
import * as React from "react";
import type { WithAsChild } from "@/components/animate-ui/primitives/animate/slot";
import type { UseIsInViewOptions } from "@/hooks/use-is-in-view";
import { Slot } from "@/components/animate-ui/primitives/animate/slot";
import { getStrictContext } from "@/lib/get-strict-context";
import {
useIsInView,
} from "@/hooks/use-is-in-view";
type Side = "top" | "bottom" | "left" | "right";
type Align = "start" | "center" | "end";
type ParticlesContextType = {
animate: boolean;
isInView: boolean;
};
const [ParticlesProvider, useParticles]
= getStrictContext<ParticlesContextType>("ParticlesContext");
type ParticlesProps = WithAsChild<
Omit<HTMLMotionProps<"div">, "children"> & {
animate?: boolean;
children: React.ReactNode;
} & UseIsInViewOptions
>;
function Particles({
ref,
animate = true,
asChild = false,
inView = false,
inViewMargin = "0px",
inViewOnce = true,
children,
style,
...props
}: ParticlesProps) {
const { ref: localRef, isInView } = useIsInView(
ref as React.Ref<HTMLDivElement>,
{ inView, inViewOnce, inViewMargin },
);
const Component = asChild ? Slot : motion.div;
return (
<ParticlesProvider value={{ animate, isInView }}>
<Component
ref={localRef}
style={{ position: "relative", ...style }}
{...props}
>
{children}
</Component>
</ParticlesProvider>
);
}
type ParticlesEffectProps = Omit<HTMLMotionProps<"div">, "children"> & {
side?: Side;
align?: Align;
count?: number;
radius?: number;
spread?: number;
duration?: number;
holdDelay?: number;
sideOffset?: number;
alignOffset?: number;
delay?: number;
};
function ParticlesEffect({
side = "top",
align = "center",
count = 6,
radius = 30,
spread = 360,
duration = 0.8,
holdDelay = 0.05,
sideOffset = 0,
alignOffset = 0,
delay = 0,
transition,
style,
...props
}: ParticlesEffectProps) {
const { animate, isInView } = useParticles();
const isVertical = side === "top" || side === "bottom";
const alignPct = align === "start" ? "0%" : align === "end" ? "100%" : "50%";
const top = isVertical
? side === "top"
? `calc(0% - ${sideOffset}px)`
: `calc(100% + ${sideOffset}px)`
: `calc(${alignPct} + ${alignOffset}px)`;
const left = isVertical
? `calc(${alignPct} + ${alignOffset}px)`
: side === "left"
? `calc(0% - ${sideOffset}px)`
: `calc(100% + ${sideOffset}px)`;
const containerStyle: React.CSSProperties = {
position: "absolute",
top,
left,
transform: "translate(-50%, -50%)",
};
const angleStep = (spread * (Math.PI / 180)) / Math.max(1, count - 1);
return (
<AnimatePresence>
{animate
&& isInView
&& Array.from({ length: count }).map((_, i) => {
const angle = i * angleStep;
const x = Math.cos(angle) * radius;
const y = Math.sin(angle) * radius;
return (
<motion.div
key={i}
style={{ ...containerStyle, ...style }}
initial={{ scale: 0, opacity: 0 }}
animate={{
x: `${x}px`,
y: `${y}px`,
scale: [0, 1, 0],
opacity: [0, 1, 0],
}}
transition={{
duration,
delay: delay + i * holdDelay,
ease: "easeOut",
...transition,
}}
{...props}
/>
);
})}
</AnimatePresence>
);
}
export {
Particles,
ParticlesEffect,
type ParticlesEffectProps,
type ParticlesProps,
};

View File

@@ -0,0 +1,338 @@
"use client";
import type { MotionValue, SpringOptions } from "motion/react";
import {
motion,
useMotionValue,
useSpring,
useTransform,
} from "motion/react";
import useMeasure from "react-use-measure";
import * as React from "react";
import type { UseIsInViewOptions } from "@/hooks/use-is-in-view";
import {
useIsInView,
} from "@/hooks/use-is-in-view";
type SlidingNumberRollerProps = {
prevValue: number;
value: number;
place: number;
transition: SpringOptions;
delay?: number;
};
function SlidingNumberRoller({
prevValue,
value,
place,
transition,
delay = 0,
}: SlidingNumberRollerProps) {
const startNumber = Math.floor(prevValue / place) % 10;
const targetNumber = Math.floor(value / place) % 10;
const animatedValue = useSpring(startNumber, transition);
React.useEffect(() => {
const timeoutId = setTimeout(() => {
animatedValue.set(targetNumber);
}, delay);
return () => clearTimeout(timeoutId);
}, [targetNumber, animatedValue, delay]);
const [measureRef, { height }] = useMeasure();
return (
<span
ref={measureRef}
data-slot="sliding-number-roller"
style={{
position: "relative",
display: "inline-block",
width: "1ch",
overflowX: "visible",
overflowY: "clip",
lineHeight: 1,
fontVariantNumeric: "tabular-nums",
}}
>
<span style={{ visibility: "hidden" }}>0</span>
{Array.from({ length: 10 }, (_, i) => (
<SlidingNumberDisplay
key={i}
motionValue={animatedValue}
number={i}
height={height}
transition={transition}
/>
))}
</span>
);
}
type SlidingNumberDisplayProps = {
motionValue: MotionValue<number>;
number: number;
height: number;
transition: SpringOptions;
};
function SlidingNumberDisplay({
motionValue,
number,
height,
transition,
}: SlidingNumberDisplayProps) {
const y = useTransform(motionValue, (latest) => {
if (!height)
return 0;
const currentNumber = latest % 10;
const offset = (10 + number - currentNumber) % 10;
let translateY = offset * height;
if (offset > 5)
translateY -= 10 * height;
return translateY;
});
if (!height) {
return (
<span style={{ visibility: "hidden", position: "absolute" }}>
{number}
</span>
);
}
return (
<motion.span
data-slot="sliding-number-display"
style={{
y,
position: "absolute",
inset: 0,
display: "flex",
alignItems: "center",
justifyContent: "center",
}}
transition={{ ...transition, type: "spring" }}
>
{number}
</motion.span>
);
}
type SlidingNumberProps = Omit<React.ComponentProps<"span">, "children"> & {
number: number;
fromNumber?: number;
onNumberChange?: (number: number) => void;
padStart?: boolean;
decimalSeparator?: string;
decimalPlaces?: number;
thousandSeparator?: string;
transition?: SpringOptions;
delay?: number;
} & UseIsInViewOptions;
function SlidingNumber({
ref,
number,
fromNumber,
onNumberChange,
inView = false,
inViewMargin = "0px",
inViewOnce = true,
padStart = false,
decimalSeparator = ".",
decimalPlaces = 0,
thousandSeparator,
transition = { stiffness: 200, damping: 20, mass: 0.4 },
delay = 0,
...props
}: SlidingNumberProps) {
const { ref: localRef, isInView } = useIsInView(
ref as React.Ref<HTMLElement>,
{
inView,
inViewOnce,
inViewMargin,
},
);
const prevNumberRef = React.useRef<number>(0);
const hasAnimated = fromNumber !== undefined;
const motionVal = useMotionValue(fromNumber ?? 0);
const springVal = useSpring(motionVal, { stiffness: 90, damping: 50 });
React.useEffect(() => {
if (!hasAnimated)
return;
const timeoutId = setTimeout(() => {
if (isInView)
motionVal.set(number);
}, delay);
return () => clearTimeout(timeoutId);
}, [hasAnimated, isInView, number, motionVal, delay]);
const [effectiveNumber, setEffectiveNumber] = React.useState(0);
React.useEffect(() => {
if (hasAnimated) {
const inferredDecimals
= typeof decimalPlaces === "number" && decimalPlaces >= 0
? decimalPlaces
: (() => {
const s = String(number);
const idx = s.indexOf(".");
return idx >= 0 ? s.length - idx - 1 : 0;
})();
const factor = 10 ** inferredDecimals;
const unsubscribe = springVal.on("change", (latest: number) => {
const newValue
= inferredDecimals > 0
? Math.round(latest * factor) / factor
: Math.round(latest);
if (effectiveNumber !== newValue) {
setEffectiveNumber(newValue);
onNumberChange?.(newValue);
}
});
return () => unsubscribe();
}
else {
setEffectiveNumber(!isInView ? 0 : Math.abs(Number(number)));
}
}, [
hasAnimated,
springVal,
isInView,
number,
decimalPlaces,
onNumberChange,
effectiveNumber,
]);
const formatNumber = React.useCallback(
(num: number) =>
decimalPlaces != null ? num.toFixed(decimalPlaces) : num.toString(),
[decimalPlaces],
);
const numberStr = formatNumber(effectiveNumber);
const [newIntStrRaw, newDecStrRaw = ""] = numberStr.split(".");
const finalIntLength = padStart
? Math.max(
Math.floor(Math.abs(number)).toString().length,
newIntStrRaw.length,
)
: newIntStrRaw.length;
const newIntStr = padStart
? newIntStrRaw.padStart(finalIntLength, "0")
: newIntStrRaw;
const prevFormatted = formatNumber(prevNumberRef.current);
const [prevIntStrRaw = "", prevDecStrRaw = ""] = prevFormatted.split(".");
const prevIntStr = padStart
? prevIntStrRaw.padStart(finalIntLength, "0")
: prevIntStrRaw;
const adjustedPrevInt = React.useMemo(() => {
return prevIntStr.length > finalIntLength
? prevIntStr.slice(-finalIntLength)
: prevIntStr.padStart(finalIntLength, "0");
}, [prevIntStr, finalIntLength]);
const adjustedPrevDec = React.useMemo(() => {
if (!newDecStrRaw)
return "";
return prevDecStrRaw.length > newDecStrRaw.length
? prevDecStrRaw.slice(0, newDecStrRaw.length)
: prevDecStrRaw.padEnd(newDecStrRaw.length, "0");
}, [prevDecStrRaw, newDecStrRaw]);
React.useEffect(() => {
if (isInView)
prevNumberRef.current = effectiveNumber;
}, [effectiveNumber, isInView]);
const intPlaces = React.useMemo(
() =>
Array.from({ length: finalIntLength }, (_, i) =>
10 ** (finalIntLength - i - 1)),
[finalIntLength],
);
const decPlaces = React.useMemo(
() =>
newDecStrRaw
? Array.from({ length: newDecStrRaw.length }, (_, i) =>
10 ** (newDecStrRaw.length - i - 1))
: [],
[newDecStrRaw],
);
const newDecValue = newDecStrRaw ? Number.parseInt(newDecStrRaw, 10) : 0;
const prevDecValue = adjustedPrevDec ? Number.parseInt(adjustedPrevDec, 10) : 0;
return (
<span
ref={localRef}
data-slot="sliding-number"
style={{
display: "inline-flex",
alignItems: "center",
}}
{...props}
>
{isInView && Number(number) < 0 && (
<span style={{ marginRight: "0.25rem" }}>-</span>
)}
{intPlaces.map((place, idx) => {
const digitsToRight = intPlaces.length - idx - 1;
const isSeparatorPosition
= typeof thousandSeparator !== "undefined"
&& digitsToRight > 0
&& digitsToRight % 3 === 0;
return (
<React.Fragment key={`int-${place}`}>
<SlidingNumberRoller
prevValue={Number.parseInt(adjustedPrevInt, 10)}
value={Number.parseInt(newIntStr ?? "0", 10)}
place={place}
transition={transition}
/>
{isSeparatorPosition && <span>{thousandSeparator}</span>}
</React.Fragment>
);
})}
{newDecStrRaw && (
<>
<span>{decimalSeparator}</span>
{decPlaces.map(place => (
<SlidingNumberRoller
key={`dec-${place}`}
prevValue={prevDecValue}
value={newDecValue}
place={place}
transition={transition}
delay={delay}
/>
))}
</>
)}
</span>
);
}
export { SlidingNumber, type SlidingNumberProps };

View File

@@ -4,10 +4,10 @@ import Image from "next/image";
import Link from "next/link"; import Link from "next/link";
import { navbarLinks } from "@/config/site-config"; import { navbarLinks } from "@/config/site-config";
import { Button } from "@/components/ui/button";
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip"; import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from "./ui/tooltip";
import StarOnGithubButton from "./ui/star-on-github-button"; import { GitHubStarsButton } from "./animate-ui/components/buttons/github-stars";
import { Button } from "./animate-ui/components/buttons/button";
import { ThemeToggle } from "./ui/theme-toggle"; import { ThemeToggle } from "./ui/theme-toggle";
import CommandMenu from "./command-menu"; import CommandMenu from "./command-menu";
@@ -39,31 +39,18 @@ function Navbar() {
href="/" href="/"
className="flex cursor-pointer w-full justify-center sm:justify-start flex-row-reverse items-center gap-2 font-semibold sm:flex-row" className="flex cursor-pointer w-full justify-center sm:justify-start flex-row-reverse items-center gap-2 font-semibold sm:flex-row"
> >
<Image <Image height={18} unoptimized width={18} alt="logo" src="/ProxmoxVE/logo.png" className="" />
height={18}
unoptimized
width={18}
alt="logo"
src="/ProxmoxVE/logo.png"
className=""
/>
<span className="hidden md:block">Proxmox VE Helper-Scripts</span> <span className="hidden md:block">Proxmox VE Helper-Scripts</span>
</Link> </Link>
<div className="flex gap-2"> <div className="flex gap-2">
<CommandMenu /> <CommandMenu />
<StarOnGithubButton /> <GitHubStarsButton username="community-scripts" repo="ProxmoxVE" />
{navbarLinks.map(({ href, event, icon, text, mobileHidden }) => ( {navbarLinks.map(({ href, event, icon, text, mobileHidden }) => (
<TooltipProvider key={event}> <TooltipProvider key={event}>
<Tooltip delayDuration={100}> <Tooltip delayDuration={100}>
<TooltipTrigger <TooltipTrigger className={mobileHidden ? "hidden lg:block" : ""}>
className={mobileHidden ? "hidden lg:block" : ""}
>
<Button variant="ghost" size="icon" asChild> <Button variant="ghost" size="icon" asChild>
<Link <Link target="_blank" href={href} data-umami-event={event}>
target="_blank"
href={href}
data-umami-event={event}
>
{icon} {icon}
<span className="sr-only">{text}</span> <span className="sr-only">{text}</span>
</Link> </Link>

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