diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md new file mode 100644 index 000000000..48ae7fdc9 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -0,0 +1,30 @@ +--- +name: Bug report +about: Create a report to help us improve +title: "[Bug] " +labels: '' +assignees: '' + +--- + +**Describe the bug** +A clear and concise description of what the bug is. + +**Expected behavior** +A clear and concise description of what you expected to happen. + +**Screenshots** +If applicable, add screenshots to help explain your problem. + +**Configuration** +If applicable, +```yaml +# Please provide your service, widget or otherwise related configuration here +``` + +**Additional context** +Add any other context about the problem here. This includes things like: + - Service version or API version + - Docker version + - Deployment method + - Sample YAML configurations diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md new file mode 100644 index 000000000..05d91b523 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -0,0 +1,17 @@ +--- +name: Feature request +about: Suggest an idea for this project +title: "[Feature Request] " +labels: '' +assignees: '' + +--- + +**Is your feature request related to a service? Please describe.** +A clear and concise description of what you would like to see from this service. + +**Is your feature request related to a problem? Please describe.** +A clear and concise description of what the problem is. Ex. I would like it if [...] + +**Additional context** +Add any other context or screenshots about the feature request here. diff --git a/.github/workflows/docker-publish.yml b/.github/workflows/docker-publish.yml index caeabab22..aa5265edb 100644 --- a/.github/workflows/docker-publish.yml +++ b/.github/workflows/docker-publish.yml @@ -96,7 +96,7 @@ jobs: labels: ${{ steps.meta.outputs.labels }} # https://github.com/docker/setup-qemu-action#about # platforms: linux/amd64,linux/arm64,linux/riscv64,linux/ppc64le,linux/s390x,linux/386,linux/mips64le,linux/mips64,linux/arm/v7,linux/arm/v6 - platforms: linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7 + platforms: linux/amd64,linux/arm64,linux/arm/v7,linux/arm/v6 cache-from: type=local,src=/tmp/.buildx-cache cache-to: type=local,dest=/tmp/.buildx-cache-new,mode=max diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md new file mode 100644 index 000000000..f989048e5 --- /dev/null +++ b/CODE_OF_CONDUCT.md @@ -0,0 +1,128 @@ +# Contributor Covenant Code of Conduct + +## Our Pledge + +We as members, contributors, and leaders pledge to make participation in our +community a harassment-free experience for everyone, regardless of age, body +size, visible or invisible disability, ethnicity, sex characteristics, gender +identity and expression, level of experience, education, socio-economic status, +nationality, personal appearance, race, religion, or sexual identity +and orientation. + +We pledge to act and interact in ways that contribute to an open, welcoming, +diverse, inclusive, and healthy community. + +## Our Standards + +Examples of behavior that contributes to a positive environment for our +community include: + +* Demonstrating empathy and kindness toward other people +* Being respectful of differing opinions, viewpoints, and experiences +* Giving and gracefully accepting constructive feedback +* Accepting responsibility and apologizing to those affected by our mistakes, + and learning from the experience +* Focusing on what is best not just for us as individuals, but for the + overall community + +Examples of unacceptable behavior include: + +* The use of sexualized language or imagery, and sexual attention or + advances of any kind +* Trolling, insulting or derogatory comments, and personal or political attacks +* Public or private harassment +* Publishing others' private information, such as a physical or email + address, without their explicit permission +* Other conduct which could reasonably be considered inappropriate in a + professional setting + +## Enforcement Responsibilities + +Community leaders are responsible for clarifying and enforcing our standards of +acceptable behavior and will take appropriate and fair corrective action in +response to any behavior that they deem inappropriate, threatening, offensive, +or harmful. + +Community leaders have the right and responsibility to remove, edit, or reject +comments, commits, code, wiki edits, issues, and other contributions that are +not aligned to this Code of Conduct, and will communicate reasons for moderation +decisions when appropriate. + +## Scope + +This Code of Conduct applies within all community spaces, and also applies when +an individual is officially representing the community in public spaces. +Examples of representing our community include using an official e-mail address, +posting via an official social media account, or acting as an appointed +representative at an online or offline event. + +## Enforcement + +Instances of abusive, harassing, or otherwise unacceptable behavior may be +reported to the community leaders responsible for enforcement at +ben@phelps.io. +All complaints will be reviewed and investigated promptly and fairly. + +All community leaders are obligated to respect the privacy and security of the +reporter of any incident. + +## Enforcement Guidelines + +Community leaders will follow these Community Impact Guidelines in determining +the consequences for any action they deem in violation of this Code of Conduct: + +### 1. Correction + +**Community Impact**: Use of inappropriate language or other behavior deemed +unprofessional or unwelcome in the community. + +**Consequence**: A private, written warning from community leaders, providing +clarity around the nature of the violation and an explanation of why the +behavior was inappropriate. A public apology may be requested. + +### 2. Warning + +**Community Impact**: A violation through a single incident or series +of actions. + +**Consequence**: A warning with consequences for continued behavior. No +interaction with the people involved, including unsolicited interaction with +those enforcing the Code of Conduct, for a specified period of time. This +includes avoiding interactions in community spaces as well as external channels +like social media. Violating these terms may lead to a temporary or +permanent ban. + +### 3. Temporary Ban + +**Community Impact**: A serious violation of community standards, including +sustained inappropriate behavior. + +**Consequence**: A temporary ban from any sort of interaction or public +communication with the community for a specified period of time. No public or +private interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, is allowed during this period. +Violating these terms may lead to a permanent ban. + +### 4. Permanent Ban + +**Community Impact**: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behavior, harassment of an +individual, or aggression toward or disparagement of classes of individuals. + +**Consequence**: A permanent ban from any sort of public interaction within +the community. + +## Attribution + +This Code of Conduct is adapted from the [Contributor Covenant][homepage], +version 2.0, available at +https://www.contributor-covenant.org/version/2/0/code_of_conduct.html. + +Community Impact Guidelines were inspired by [Mozilla's code of conduct +enforcement ladder](https://github.com/mozilla/diversity). + +[homepage]: https://www.contributor-covenant.org + +For answers to common questions about this code of conduct, see the FAQ at +https://www.contributor-covenant.org/faq. Translations are available at +https://www.contributor-covenant.org/translations. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 000000000..b80f89fb9 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,41 @@ +# Contributing to Homepage +We love your input! We want to make contributing to this project as easy and transparent as possible, whether it's: + +- Reporting a bug +- Discussing the current state of the project +- Submitting a fix +- Proposing new features +- Becoming a maintainer + +## We Develop with Github +We use github to host code, to track issues and feature requests, as well as accept pull requests. + +## Any contributions you make will be under the GNU General Public License v3.0 +In short, when you submit code changes, your submissions are understood to be under the same [GNU General Public License v3.0](https://choosealicense.com/licenses/gpl-3.0/) that covers the project. Feel free to contact the maintainers if that's a concern. + +## Report bugs using Github's [issues](https://github.com/benphelps/homepage/issues) +We use GitHub issues to track public bugs. Report a bug by [opening a new issue](https://github.com/benphelps/homepage/issues/new); it's that easy! + +## Write bug reports with detail, background, and sample configurations +Homepage includes a lot of configuration options and is often deploying in larger systems. Please include as much information (configurations, deployment method, Docker & API versions, etc) as you can when reporting an issue. + +**Great Bug Reports** tend to have: + +- A quick summary and/or background +- Steps to reproduce + - Be specific! + - Give example configurations if you can. +- What you expected would happen +- What actually happens +- Notes (possibly including why you think this might be happening, or stuff you tried that didn't work) + +People *love* thorough bug reports. I'm not even kidding. + +## Use a Consistent Coding Style +This project follows the [Airbnb JavaScript Style Guide](https://github.com/airbnb/javascript), please follow it when submitting pull requests. + +## License +By contributing, you agree that your contributions will be licensed under its GNU General Public License. + +## References +This document was adapted from the open-source contribution guidelines for [Facebook's Draft](https://github.com/facebook/draft-js/blob/main/CONTRIBUTING.md) diff --git a/README.md b/README.md index f3c8829a7..fd45423c8 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,7 @@ - Automatic service discovery (via labels) * Service Integration - Sonarr, Radarr, Readarr, Prowlarr, Emby, Jellyfin, Tautulli (Plex) - - Ombi, Overseerr, Jellyseerr, NZBGet, SABnzbd, ruTorrent + - Ombi, Overseerr, Jellyseerr, NZBGet, SABnzbd, ruTorrent, Transmission - Portainer, Traefik, Speedtest Tracker, PiHole, Nginx Proxy Manager, Gotify * Information Providers - Coin Market Cap @@ -127,7 +127,7 @@ Huge thanks to the all the contributors who have helped make this project what i * [ilusi0n](https://github.com/benphelps/homepage/commits?author=ilusi0n) - Jellyseerr Integration * [ItsJustMeChris](https://github.com/benphelps/homepage/commits?author=ItsJustMeChris) - Coin Market Cap Widget * [jackblk](https://github.com/benphelps/homepage/commits?author=jackblk) - Vietnamese Translation - * [JazzFisch](https://github.com/benphelps/homepage/commits?author=JazzFisch) - Readarr, SABnzbd Integrations + * [JazzFisch](https://github.com/benphelps/homepage/commits?author=JazzFisch) - Readarr, SABnzbd & Transmission Integrations * [modem7](https://github.com/benphelps/homepage/commits?author=modem7) - Impvoed Docker Image * [nicedc](https://github.com/benphelps/homepage/commits?author=nicedc) - Chinese Translation * [Nonoss117](https://github.com/benphelps/homepage/commits?author=Nonoss117) - French Translation diff --git a/docker-entrypoint.sh b/docker-entrypoint.sh new file mode 100755 index 000000000..5603d7e58 --- /dev/null +++ b/docker-entrypoint.sh @@ -0,0 +1,9 @@ +#!/bin/sh + +set -e + +# This is in attempt to preserve the original behavior of the Dockerfile, +# while also supporting the lscr.io /config directory +[ ! -d "/app/config" ] && ln -s /config /app/config + +node server.js diff --git a/package.json b/package.json index b7bbd3845..dd9f7f87a 100644 --- a/package.json +++ b/package.json @@ -6,13 +6,13 @@ "dev": "next dev", "build": "next build", "start": "next start", - "lint": "next lint" + "lint": "next lint", + "telemetry": "next telemetry disable" }, "dependencies": { "@headlessui/react": "^1.7.0", "@tailwindcss/forms": "^0.5.3", "classnames": "^2.3.1", - "currency-symbol-map": "^5.1.0", "dockerode": "^3.3.4", "follow-redirects": "^1.15.2", "i18next": "^21.9.1", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2d19e8a5a..193092180 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -5,7 +5,6 @@ specifiers: '@tailwindcss/forms': ^0.5.3 autoprefixer: ^10.4.9 classnames: ^2.3.1 - currency-symbol-map: ^5.1.0 dockerode: ^3.3.4 eslint: ^8.23.1 eslint-config-airbnb: ^19.0.4 @@ -44,7 +43,6 @@ dependencies: '@headlessui/react': 1.7.0_biqbaboplfbrettd7655fr4n2y '@tailwindcss/forms': 0.5.3_tailwindcss@3.1.8 classnames: 2.3.1 - currency-symbol-map: 5.1.0 dockerode: 3.3.4 follow-redirects: 1.15.2 i18next: 21.9.1 @@ -710,10 +708,6 @@ packages: engines: {node: '>=4'} hasBin: true - /currency-symbol-map/5.1.0: - resolution: {integrity: sha512-LO/lzYRw134LMDVnLyAf1dHE5tyO6axEFkR3TXjQIOmMkAM9YL6QsiUwuXzZAmFnuDJcs4hayOgyIYtViXFrLw==} - dev: false - /damerau-levenshtein/1.0.8: resolution: {integrity: sha512-sdQSFB7+llfUcQHUQO3+B8ERRj0Oa4w9POWMI/puGtuf7gFywGmkaLCElnudfTiKZV+NvHqL0ifzdrI8Ro7ESA==} dev: true diff --git a/public/locales/ca/common.json b/public/locales/ca/common.json new file mode 100644 index 000000000..94936d40c --- /dev/null +++ b/public/locales/ca/common.json @@ -0,0 +1,136 @@ +{ + "widget": { + "missing_type": "Missing Widget Type: {{type}}", + "api_error": "API Error", + "status": "Status" + }, + "weather": { + "allow": "Click to allow", + "updating": "Updating", + "wait": "Please wait", + "current": "Current Location" + }, + "search": { + "placeholder": "Search…" + }, + "transmission": { + "seed": "Seed", + "download": "Download", + "upload": "Upload", + "leech": "Leech" + }, + "sonarr": { + "wanted": "Wanted", + "queued": "Queued", + "series": "Series" + }, + "speedtest": { + "ping": "Ping", + "upload": "Upload", + "download": "Download" + }, + "resources": { + "total": "Total", + "free": "Free", + "used": "Used", + "load": "Load" + }, + "docker": { + "rx": "RX", + "tx": "TX", + "mem": "MEM", + "cpu": "CPU", + "offline": "Offline" + }, + "emby": { + "playing": "Playing", + "transcoding": "Transcoding", + "bitrate": "Bitrate", + "no_active": "No Active Streams" + }, + "tautulli": { + "playing": "Playing", + "transcoding": "Transcoding", + "bitrate": "Bitrate", + "no_active": "No Active Streams" + }, + "nzbget": { + "rate": "Rate", + "remaining": "Remaining", + "downloaded": "Downloaded" + }, + "sabnzbd": { + "rate": "Rate", + "queue": "Queue", + "timeleft": "Time Left" + }, + "rutorrent": { + "active": "Active", + "upload": "Upload", + "download": "Download" + }, + "radarr": { + "wanted": "Wanted", + "queued": "Queued", + "movies": "Movies" + }, + "readarr": { + "wanted": "Wanted", + "queued": "Queued", + "books": "Books" + }, + "ombi": { + "pending": "Pending", + "approved": "Approved", + "available": "Available" + }, + "jellyseerr": { + "pending": "Pending", + "approved": "Approved", + "available": "Available" + }, + "overseerr": { + "pending": "Pending", + "approved": "Approved", + "available": "Available" + }, + "pihole": { + "queries": "Queries", + "blocked": "Blocked", + "gravity": "Gravity" + }, + "portainer": { + "running": "Running", + "stopped": "Stopped", + "total": "Total" + }, + "traefik": { + "routers": "Routers", + "services": "Services", + "middleware": "Middleware" + }, + "npm": { + "total": "Total", + "enabled": "Enabled", + "disabled": "Disabled" + }, + "coinmarketcap": { + "configure": "Configure one or more crypto currencies to track", + "1hour": "1 Hour", + "1day": "1 Day", + "7days": "7 Days", + "30days": "30 Days" + }, + "gotify": { + "apps": "Applications", + "clients": "Clients", + "messages": "Messages" + }, + "prowlarr": { + "enableIndexers": "Indexers", + "numberOfGrabs": "Grabs", + "numberOfQueries": "Queries", + "numberOfFailGrabs": "Fail Grabs", + "numberOfFailQueries": "Fail Queries" + } +} diff --git a/public/locales/de/common.json b/public/locales/de/common.json index bbb5ff666..74d79bb86 100644 --- a/public/locales/de/common.json +++ b/public/locales/de/common.json @@ -109,7 +109,11 @@ "downloaded": "Downloaded" }, "coinmarketcap": { - "configure": "Configure one or more crypto currencies to track" + "configure": "Configure one or more crypto currencies to track", + "1hour": "1 Hour", + "1day": "1 Day", + "7days": "7 Days", + "30days": "30 Days" }, "gotify": { "apps": "Applications", diff --git a/public/locales/en/common.json b/public/locales/en/common.json index 9d92e66e9..b81009351 100644 --- a/public/locales/en/common.json +++ b/public/locales/en/common.json @@ -126,7 +126,11 @@ "total": "Total" }, "coinmarketcap": { - "configure": "Configure one or more crypto currencies to track" + "configure": "Configure one or more crypto currencies to track", + "1hour": "1 Hour", + "1day": "1 Day", + "7days": "7 Days", + "30days": "30 Days" }, "gotify": { "apps": "Applications", diff --git a/public/locales/es/common.json b/public/locales/es/common.json index d61bda0e9..c184907e0 100644 --- a/public/locales/es/common.json +++ b/public/locales/es/common.json @@ -11,7 +11,7 @@ "total": "Total", "free": "Libre", "used": "Usado", - "load": "Load" + "load": "Carga" }, "docker": { "rx": "Recibido", @@ -34,8 +34,8 @@ }, "rutorrent": { "active": "Activo", - "upload": "Subir", - "download": "Descargar" + "upload": "Subida", + "download": "Descarga" }, "sonarr": { "wanted": "Más deseado", @@ -69,7 +69,7 @@ }, "speedtest": { "upload": "Subir", - "download": "Descargar", + "download": "Descarga", "ping": "Ping" }, "portainer": { @@ -109,7 +109,11 @@ "downloaded": "Descargado" }, "coinmarketcap": { - "configure": "Configurar una o varias criptomonedas para su seguimiento" + "configure": "Configurar una o varias criptomonedas para su seguimiento", + "1hour": "1 Hour", + "1day": "1 Day", + "7days": "7 Days", + "30days": "30 Days" }, "gotify": { "apps": "Aplicaciones", @@ -117,16 +121,16 @@ "messages": "Mensajes" }, "prowlarr": { - "enableIndexers": "Indexers", - "numberOfGrabs": "Grabs", - "numberOfQueries": "Queries", - "numberOfFailGrabs": "Fail Grabs", - "numberOfFailQueries": "Fail Queries" + "enableIndexers": "Indexadores", + "numberOfGrabs": "Capturas", + "numberOfQueries": "Consultas", + "numberOfFailGrabs": "Capturas Fallidas", + "numberOfFailQueries": "Consultas Fallidas" }, "transmission": { - "download": "Download", - "upload": "Upload", - "leech": "Leech", - "seed": "Seed" + "download": "Descarga", + "upload": "Subida", + "leech": "Egoístas (Leech)", + "seed": "Semillas" } } diff --git a/public/locales/fr/common.json b/public/locales/fr/common.json index 924d88a61..f7d77f88f 100644 --- a/public/locales/fr/common.json +++ b/public/locales/fr/common.json @@ -120,7 +120,11 @@ "rate": "Évaluer" }, "coinmarketcap": { - "configure": "Configurer une ou plusieurs crypto-monnaies à suivre" + "configure": "Configurer une ou plusieurs crypto-monnaies à suivre", + "1hour": "1 Hour", + "1day": "1 Day", + "7days": "7 Days", + "30days": "30 Days" }, "gotify": { "apps": "Applications", @@ -135,8 +139,8 @@ "numberOfFailQueries": "Demande échouée" }, "transmission": { - "download": "Download", - "upload": "Upload", + "download": "Réception", + "upload": "Envoi", "leech": "Leech", "seed": "Seed" } diff --git a/public/locales/it/common.json b/public/locales/it/common.json index 585aae1e0..62658ca91 100644 --- a/public/locales/it/common.json +++ b/public/locales/it/common.json @@ -109,7 +109,11 @@ "downloaded": "Downloaded" }, "coinmarketcap": { - "configure": "Configure one or more crypto currencies to track" + "configure": "Configure one or more crypto currencies to track", + "1day": "1 Day", + "7days": "7 Days", + "1hour": "1 Hour", + "30days": "30 Days" }, "gotify": { "apps": "Applications", diff --git a/public/locales/nb-NO/common.json b/public/locales/nb-NO/common.json index 141378e8b..33894cdf0 100644 --- a/public/locales/nb-NO/common.json +++ b/public/locales/nb-NO/common.json @@ -109,7 +109,11 @@ "remaining": "Gjenstående" }, "coinmarketcap": { - "configure": "Sett opp én eller flere kryptovalutaer å holde øye med" + "configure": "Sett opp én eller flere kryptovalutaer å holde øye med", + "1hour": "1 Hour", + "1day": "1 Day", + "7days": "7 Days", + "30days": "30 Days" }, "gotify": { "apps": "Programmer", diff --git a/public/locales/nl/common.json b/public/locales/nl/common.json index d2975cd2e..0259d05ca 100644 --- a/public/locales/nl/common.json +++ b/public/locales/nl/common.json @@ -109,7 +109,11 @@ "downloaded": "Downloaded" }, "coinmarketcap": { - "configure": "Configure one or more crypto currencies to track" + "configure": "Configure one or more crypto currencies to track", + "1hour": "1 Hour", + "7days": "7 Days", + "1day": "1 Day", + "30days": "30 Days" }, "gotify": { "apps": "Applications", diff --git a/public/locales/pt/common.json b/public/locales/pt/common.json index 4dafc19f2..be261b448 100644 --- a/public/locales/pt/common.json +++ b/public/locales/pt/common.json @@ -1,6 +1,6 @@ { "widget": { - "missing_type": "Tipo de widget ausente: {{type}}", + "missing_type": "Widget ausente: {{type}}", "api_error": "Erro da API", "status": "Status" }, @@ -10,7 +10,7 @@ "resources": { "total": "Total", "free": "Livre", - "used": "Usada", + "used": "Usado", "load": "Load" }, "docker": { @@ -18,22 +18,22 @@ "tx": "Tx", "mem": "Mem", "cpu": "CPU", - "offline": "Desligada" + "offline": "Desligado" }, "emby": { "playing": "A reproduzir", "transcoding": "Transcodificação", - "bitrate": "Taxa de bits", - "no_active": "No Active Streams" + "bitrate": "Bitrate", + "no_active": "Sem streams ativas" }, "tautulli": { "playing": "Reproduzindo", "transcoding": "Transcodificação", "bitrate": "Taxa de bits", - "no_active": "No Active Streams" + "no_active": "Sem streams ativas" }, "rutorrent": { - "active": "Ativa", + "active": "Ativo", "upload": "Envio", "download": "ReceçãoDownload" }, @@ -44,13 +44,13 @@ }, "radarr": { "wanted": "Desejado", - "queued": "Enfileiradas", + "queued": "Fila", "movies": "Filmes" }, "readarr": { "wanted": "Wanted", - "queued": "Queued", - "books": "Books" + "queued": "Em fila", + "books": "Livros" }, "ombi": { "pending": "Pendente", @@ -65,7 +65,7 @@ "pihole": { "queries": "Consultas", "blocked": "Bloqueado", - "gravity": "Gravidade" + "gravity": "Gravity" }, "speedtest": { "upload": "Envio", @@ -73,18 +73,18 @@ "ping": "Ping" }, "portainer": { - "running": "Corrida", - "stopped": "Parou", + "running": "A correr", + "stopped": "Parado", "total": "Total" }, "traefik": { - "routers": "Roteadores", + "routers": "Routers", "services": "Serviços", "middleware": "Middleware" }, "npm": { - "enabled": "Habilitada", - "disabled": "Desabilitada", + "enabled": "Ativo", + "disabled": "Desabilitado", "total": "Total" }, "common": { @@ -105,22 +105,26 @@ "wait": "Por favor aguarde" }, "overseerr": { - "pending": "Pending", - "approved": "Approved", - "available": "Available" + "pending": "Pendente", + "approved": "Aprovado", + "available": "Disponível" }, "sabnzbd": { "rate": "Rate", - "queue": "Queue", - "timeleft": "Time Left" + "queue": "Fila", + "timeleft": "Tempo restante" }, "nzbget": { "rate": "Rate", - "remaining": "Remaining", + "remaining": "Restante", "downloaded": "Downloaded" }, "coinmarketcap": { - "configure": "Configure one or more crypto currencies to track" + "configure": "Configurar uma ou mais moedas", + "1hour": "1 Hour", + "1day": "1 Day", + "7days": "7 Days", + "30days": "30 Days" }, "gotify": { "apps": "Aplicações", @@ -131,12 +135,12 @@ "enableIndexers": "Indexers", "numberOfGrabs": "Grabs", "numberOfQueries": "Queries", - "numberOfFailGrabs": "Fail Grabs", - "numberOfFailQueries": "Fail Queries" + "numberOfFailGrabs": "Falhados", + "numberOfFailQueries": "Pesquisas falhadas" }, "transmission": { "download": "Download", - "upload": "Upload", + "upload": "Envio", "leech": "Leech", "seed": "Seed" } diff --git a/public/locales/ru/common.json b/public/locales/ru/common.json index 0f4ae8af4..c8d956725 100644 --- a/public/locales/ru/common.json +++ b/public/locales/ru/common.json @@ -109,7 +109,11 @@ "downloaded": "Downloaded" }, "coinmarketcap": { - "configure": "Configure one or more crypto currencies to track" + "configure": "Configure one or more crypto currencies to track", + "1hour": "1 Hour", + "1day": "1 Day", + "7days": "7 Days", + "30days": "30 Days" }, "gotify": { "apps": "Applications", diff --git a/public/locales/vi/common.json b/public/locales/vi/common.json index ab6122f76..1d15ff9d0 100644 --- a/public/locales/vi/common.json +++ b/public/locales/vi/common.json @@ -109,7 +109,11 @@ "downloaded": "Downloaded" }, "coinmarketcap": { - "configure": "Configure one or more crypto currencies to track" + "configure": "Configure one or more crypto currencies to track", + "1hour": "1 Hour", + "1day": "1 Day", + "7days": "7 Days", + "30days": "30 Days" }, "gotify": { "apps": "Applications", diff --git a/public/locales/zh-CN/common.json b/public/locales/zh-CN/common.json index b324f35bf..723776aaa 100644 --- a/public/locales/zh-CN/common.json +++ b/public/locales/zh-CN/common.json @@ -109,7 +109,11 @@ "downloaded": "下载" }, "coinmarketcap": { - "configure": "配置一个或多个需要追踪的加密" + "configure": "配置一个或多个需要追踪的加密", + "1hour": "1 Hour", + "1day": "1 Day", + "7days": "7 Days", + "30days": "30 Days" }, "gotify": { "apps": "应用", diff --git a/public/locales/zh-Hant/common.json b/public/locales/zh-Hant/common.json index 63df53691..e0f03e295 100644 --- a/public/locales/zh-Hant/common.json +++ b/public/locales/zh-Hant/common.json @@ -114,7 +114,11 @@ "total": "Total" }, "coinmarketcap": { - "configure": "Configure one or more crypto currencies to track" + "configure": "Configure one or more crypto currencies to track", + "1hour": "1 Hour", + "1day": "1 Day", + "7days": "7 Days", + "30days": "30 Days" }, "prowlarr": { "enableIndexers": "Indexers", diff --git a/src/components/services/dropdown.jsx b/src/components/services/dropdown.jsx new file mode 100644 index 000000000..4bc25a8fd --- /dev/null +++ b/src/components/services/dropdown.jsx @@ -0,0 +1,48 @@ +import { Fragment } from "react"; +import { Menu, Transition } from "@headlessui/react"; +import { BiCog } from "react-icons/bi"; +import classNames from "classnames"; + +export default function Dropdown({ options, value, setValue }) { + return ( + +
+ + {options.find((option) => option.value === value).label} + +
+ + + +
+ {options.map((option) => ( + + + + ))} +
+
+
+
+ ); +} diff --git a/src/components/services/widget.jsx b/src/components/services/widget.jsx index b47b4fdfe..0bb5c08d5 100644 --- a/src/components/services/widget.jsx +++ b/src/components/services/widget.jsx @@ -47,7 +47,7 @@ const widgetMappings = { tautulli: Tautulli, gotify: Gotify, prowlarr: Prowlarr, - jackett: Jackett + jackett: Jackett, }; export default function Widget({ service }) { diff --git a/src/components/services/widgets/service/coinmarketcap.jsx b/src/components/services/widgets/service/coinmarketcap.jsx index c5e66ebc8..a34e6e924 100644 --- a/src/components/services/widgets/service/coinmarketcap.jsx +++ b/src/components/services/widgets/service/coinmarketcap.jsx @@ -1,15 +1,26 @@ import useSWR from "swr"; +import { useState } from "react"; import { useTranslation } from "react-i18next"; -import getSymbolFromCurrency from "currency-symbol-map"; +import classNames from "classnames"; import Widget from "../widget"; import Block from "../block"; +import Dropdown from "components/services/dropdown"; import { formatApiUrl } from "utils/api-helpers"; export default function CoinMarketCap({ service }) { const { t } = useTranslation(); + const dateRangeOptions = [ + { label: t("coinmarketcap.1hour"), value: "1h" }, + { label: t("coinmarketcap.1day"), value: "24h" }, + { label: t("coinmarketcap.7days"), value: "7d" }, + { label: t("coinmarketcap.30days"), value: "30d" }, + ]; + + const [dateRange, setDateRange] = useState(dateRangeOptions[0].value); + const config = service.widget; const currencyCode = config.currency ?? "USD"; const { symbols } = config; @@ -30,7 +41,7 @@ export default function CoinMarketCap({ service }) { return ; } - if (!statsData) { + if (!statsData || !dateRange) { return ( @@ -39,28 +50,36 @@ export default function CoinMarketCap({ service }) { } const { data } = statsData; - const currencySymbol = getSymbolFromCurrency(currencyCode); return ( +
+ +
+
- {symbols.map((key) => ( + {symbols.map((symbol) => (
-
{data[key].name}
+
{data[symbol].name}
- {currencySymbol} - {data[key].quote[currencyCode].price.toFixed(2)} + {t("common.number", { + value: data[symbol].quote[currencyCode].price, + style: "currency", + currency: currencyCode, + })}
0 ? "text-emerald-300" : "text-rose-300" + data[symbol].quote[currencyCode][`percent_change_${dateRange}`] > 0 + ? "text-emerald-300" + : "text-rose-300" }`} > - {data[key].quote[currencyCode].percent_change_1h.toFixed(2)}% + {data[symbol].quote[currencyCode][`percent_change_${dateRange}`].toFixed(2)}%
diff --git a/src/components/services/widgets/service/tautulli.jsx b/src/components/services/widgets/service/tautulli.jsx index 3902d4fc5..4a97b8d79 100644 --- a/src/components/services/widgets/service/tautulli.jsx +++ b/src/components/services/widgets/service/tautulli.jsx @@ -48,10 +48,10 @@ function SingleSessionEntry({ session }) { />
{state === "paused" && ( - + )} {state !== "paused" && ( - + )}
@@ -76,10 +76,10 @@ function SessionEntry({ session }) { />
{state === "paused" && ( - + )} {state !== "paused" && ( - + )} {full_title}
diff --git a/src/components/services/widgets/widget.jsx b/src/components/services/widgets/widget.jsx index 98e4683eb..12202c05f 100644 --- a/src/components/services/widgets/widget.jsx +++ b/src/components/services/widgets/widget.jsx @@ -7,5 +7,5 @@ export default function Widget({ error = false, children }) { ); } - return
{children}
; + return
{children}
; } diff --git a/src/components/widgets/resources/resources.jsx b/src/components/widgets/resources/resources.jsx index 72933a024..a1bf7dfc4 100644 --- a/src/components/widgets/resources/resources.jsx +++ b/src/components/widgets/resources/resources.jsx @@ -3,7 +3,6 @@ import Cpu from "./cpu"; import Memory from "./memory"; export default function Resources({ options }) { - console.log(options); const { expanded } = options; return (
diff --git a/src/pages/index.jsx b/src/pages/index.jsx index 2a33872b4..2a1901b53 100644 --- a/src/pages/index.jsx +++ b/src/pages/index.jsx @@ -46,6 +46,8 @@ export default function Home({ settings }) { {settings.title || "Homepage"} + {settings.base && } + {settings.favicon && }