Compare commits

...
Author SHA1 Message Date
François-X. T. 7e1c332905 fix(labrinth): fix routing config for /v3/content 2026-07-07 12:38:56 -04:00
ProspectorandGitHub df8ebbd3e0 feat: add /build route (#6644) 2026-07-07 15:43:26 +00:00
François-Xavier TalbotandGitHub 517c3d2d72 fix(labrinth): fix prefix stripping in mrpack scanning (#6646) 2026-07-07 01:31:07 +00:00
Prospector 7f15772f59 changelog 2026-07-06 15:19:29 -07:00
ProspectorandGitHub 0905ea72f6 fix: project page in app not receiving instance context & port version page to app (#6618)
* fix: project page in app not receiving instance context

* prepr

* feat: port version page to app

* commonize keys

* whoops bring those back
2026-07-06 15:17:25 -07:00
8d20fd82db fix: moderation/projects endpoint slow (#6639)
* fix: moderation/projects endpoint slow

* fix: re-add tech rev toggle off by default

* fix: i18n

* prepare

---------

Co-authored-by: aecsocket <43144841+aecsocket@users.noreply.github.com>
2026-07-06 19:16:52 +00:00
aecsocketandGitHub c831e38e32 fix: file scans only consider published files as on-platform (#6638) 2026-07-06 18:13:21 +00:00
Calum H.andGitHub 40b8fb3a4a fix: use tanstack for server pinging (#6631) 2026-07-06 18:09:51 +00:00
François-Xavier TalbotandGitHub 977bb2ff58 ci: fix (#6640)
* ci: use apt

* fix(ci): sudo

* bruhj
2026-07-06 17:51:09 +00:00
Calum H.andGitHub 732bdfc79b fix: warm middleware on server-side (#6636) 2026-07-06 17:39:43 +00:00
Calum H.andGitHub 1cce1eb248 fix: strip runtime filters to be authoratative (#6635) 2026-07-06 17:39:17 +00:00
Calum H.andGitHub 76320f227f fix: dont prefetch file contents if it's not editable/viewable (#6632) 2026-07-06 17:06:41 +00:00
Calum H.andGitHub 34228a5b6c fix: use next tick in delete confirm (#6633) 2026-07-06 17:06:10 +00:00
Calum H.andGitHub 6d66aee4ec fix: properly select correct databack versions (#6634) 2026-07-06 16:59:49 +00:00
SychicandGitHub fc7be043c7 fix(labrinth): add invited_by field (#6625) 2026-07-06 16:33:00 +00:00
7fa88e5d4d feat: moderation modpack scan button (#6627)
* feat: moderation modpack scan button

* fix: ui

* fix: lint

---------

Co-authored-by: Calum H. (IMB11) <contact@cal.engineer>
2026-07-06 13:19:39 +00:00
ThatGravyBoatandGitHub 21508e0637 feat: move tech quick actions to dedicated buttons (#6628) 2026-07-06 08:31:51 +00:00
Prospector ad4912d64d changelog + one more fix 2026-07-04 19:09:58 -07:00
ProspectorandGitHub 0002ae2479 fix: env filter showing in hosting search (#6612) 2026-07-04 18:47:30 -07:00
Prospector e4568330a7 changelog 2026-07-04 16:16:02 -07:00
ProspectorandGitHub b0108e0624 fix: environment filters (#6611) 2026-07-04 16:15:28 -07:00
Prospector ac63abadb7 changelog 2026-07-04 16:00:11 -07:00
fa749b5aff fix: respect height attribute on images in markdown body (#6506)
Co-authored-by: Truman Gao <106889354+tdgao@users.noreply.github.com>
2026-07-04 22:47:17 +00:00
a2adbe18c4 Request: Add cdn/workflow.serilum.com to allowedHostnames whitelist to bypass wsrv.nl caching (#6567)
* Add cdn/workflow.serilum.com to allowedHostnames whitelist

Signed-off-by: Rick South <rick@natamus.com>

* Update parse.ts

Signed-off-by: Prospector <6166773+Prospector@users.noreply.github.com>

---------

Signed-off-by: Rick South <rick@natamus.com>
Signed-off-by: Prospector <6166773+Prospector@users.noreply.github.com>
Co-authored-by: Prospector <6166773+Prospector@users.noreply.github.com>
2026-07-04 22:40:34 +00:00
Truman GaoandGitHub 0fcbe51816 fix: version table overflow issues (#6583)
* feat: shorten ModLoader

* fix: game version and platform tag overflow issues

* feat: add table version row below and move version files to version row below

* fix: platform plural

* pnpm prepr
2026-07-04 22:06:09 +00:00
Truman GaoandGitHub 23cfeca91d feat: project download modal (#6602)
* refactor: componentize project download modal

* feat: implement new project download modal

* fix: button trigger placeholder text styles

* feat: dependency download button

* refactor: move project download modal into folder

* refactor: separate out download dependencies section

* refactor: split out download project and install with modrinth app sections

* feat+refactor: add nested dependencies route and move logic into related subcomponents

* feat: handle download project dependencies recursively and properly pass all game versions/platforms compatible on the selected version

* feat: if only dependency project is listed, find latest compatible dependency version to download in version page

* refactor: use ts and also have modal own get project/versions queries

* feat: implement opening project download modal in place in version page

* feat: implement incompatible options due to base project

* feat: auto select loader after selecting a game version, if only one loader is left compatible

* feat: add prop to stop route selection being persisted in url param

* pnpm prepr

* feat: update tooltip copy

* feat: polish some styles

* fix: fabric dependency showing when quilt is selected

* fix: tooltip hover area

* fix: when there are multiple compatible of same game version + loader, give latest

* feat: add link to version page

* feat: add truncated tooltip

* pnpm prepr

* feat: add warning icon for incompatible selection

* feat: polish loading state and tooltip

* feat: implement download all dependencies

* pnpm prepr

* fix: light theme card

* fix: additional files label

* refactor: move additional files into download dependencies section

* feat: move download all button in heading with compatible version

* fix color

* fix: dependencies not appearing when open modal second time

* fix: dependency lines when 3 nested

* feat: remove duplicated dependencies

* feat: add download count indicateor on download all button

* feat: add tooltip for downloading file with filename and size

* pnpm prepr

* feat: only show duplicate tooltip if there are duplicates
2026-07-04 21:45:34 +00:00
Truman GaoandGitHub db830ef65c feat: prevent .mrpack being uploaded as additional file (#6582) 2026-07-04 21:35:08 +00:00
ArthurandGitHub 08f44b3582 fix: make update pill button size to content clean (#6574)
* Fix update pill sizing

* Refactor as component
2026-07-04 21:33:36 +00:00
ArthurandGitHub 8ffc4e2599 chore: add modfolio to allowed hostnames (#6584)
Add modfolio to allowed hostnames
2026-07-04 21:33:24 +00:00
coolbotandGitHub 58a5619073 add alt keybind for resetting moderation progress. (#6606) 2026-07-04 21:28:08 +00:00
4a6fa9fc3d feat: better api docs (#6586)
* feat: docs

* fix tombi

* chore: fix some of the routes rendering with missing /

* response schemas

* fix: restore labrinth docs routes

* Fix path parameter docs in routes

* remove utoipa-actix-web

* consistency

* improve version intros

* improve formatting, examples

* better hash examples, move openapi stuff to openapi.rs

* more utoipa param fixes

* request body docs

* chore: remove moderation route from v2, remove ingest & webhooks from v3 spec

* fixes

* chore: tweak sources titles

* fix

* fix test

* improve examples

* increase compiler spawned thread stack size

* remove unused tests & script

* test

* bro what

* fix

---------

Co-authored-by: aecsocket <43144841+aecsocket@users.noreply.github.com>
2026-07-04 14:19:21 +00:00
aecsocketandGitHub b26d048a63 Remove AutoMod code (#6604)
* 🦀 automod is gone 🦀

* prepare
2026-07-03 21:32:11 +00:00
François-Xavier TalbotandGitHub d5be2bd739 fix(labrinth): include SharedInstanceInvite notifications for ws (#6603)
* fix(labrinth): include SharedInstanceInvite notifications for ws

* chore: fmt
2026-07-03 17:06:58 +00:00
Prospector 0dac5684af changelog 2026-07-03 08:16:29 -07:00
coolbotandGitHub ca0b8d5ca4 add excessive languages warning nag (#6587) 2026-07-03 12:12:07 +00:00
coolbotandGitHub b6651efe52 Moderation Fix: Handle more license cases (#6590)
Apply correct behavior in edge cases
2026-07-02 17:26:10 +00:00
aecsocketandGitHub eb28121c0a fix: scan logic file whitelist + rescan route (#6585)
* explicitly only scan jar/zip/disabled files for attributions

* add route to force scan file

* prepare
2026-07-02 16:33:16 +00:00
SychicandGitHub a5ebc85356 refactor(labrinth): combine logic for external notification endpoints (#6578)
* refactor(labrinth): combine logic for external notification endpoints

also introduce new notification that doesn't send an email

* style(labrinth): derive default

* feat(labrinth): return more detailed failure information for external
notifications
2026-07-02 15:44:47 +00:00
Prospector c530671be1 fix collection widget on mobile 2026-07-01 18:09:12 -07:00
Prospector bb6d8a6fc4 changelog 2026-07-01 17:44:29 -07:00
ProspectorandGitHub 256e8f946a chore: pride month fundraiser conclusion (#6588)
* pride end blog post

* Fix drago link

* prepr oops
2026-07-01 17:43:44 -07:00
Calum H.andGitHub 7e5590b8b9 fix: improve observability during fetch failure (#6555)
* fix: improve observability during fetch failure

+ remove analytics log spam

* fix: rev comments
2026-07-01 15:58:20 +00:00
SychicandGitHub d20f05fb04 feat(labrinth): instance share notification (#6581) 2026-07-01 14:21:56 +00:00
Truman GaoandGitHub a00a7971d1 feat: add tooltip for unknown dependents (#6572) 2026-07-01 05:21:42 +00:00
aecsocketandGitHub 26e98b7155 fix: change Tiltify campaign errors to quieter log level v2 (#6576)
import
2026-06-30 21:36:47 +02:00
aecsocketandGitHub 77b06f679e fix: change Tiltify campaign errors to quieter log level (#6575) 2026-06-30 21:34:37 +02:00
Truman GaoandGitHub 50e9472dd9 fix: cannot set owner for creating projects (#6573) 2026-06-30 17:00:10 +00:00
ThatGravyBoatandGitHub b569354793 fix: packs not being validated correctly (#6533) 2026-06-30 14:02:58 +00:00
Michael H. b667b3ae9e fix: remove sccache s3 2026-06-30 11:41:08 +02:00
coolbotandGitHub 16de6182e4 Add nag for custom license info. (#6564)
* add nag for custom license info

* preppr
2026-06-30 02:25:13 +00:00
Calum H.andGitHub 364fed52dd feat: changelog (#6563) 2026-06-30 01:57:11 +02:00
Calum H.andGitHub 0fe695721a fix: try fix app freezing on instance page load (#6562)
* fix: app freezing fix

* fix: fmt
2026-06-30 01:55:55 +02:00
Calum H.andGitHub 692f22b749 feat: changelog 0.15.3 (#6560)
feat: changlog 0.15.3
2026-06-30 00:54:16 +02:00
Calum H.andGitHub ed7792097d fix: better handling of larger instances for ExportModal (#6559) 2026-06-30 00:51:25 +02:00
Prospector c56ce6c9ee changelog 2026-06-29 13:45:04 -07:00
Calum H.andGitHub 91bc58b8ee fix: cleanup stale db entry on rename instance file (#6549)
fix: race on renaming instance file
2026-06-29 17:36:46 +00:00
Truman GaoandGitHub 38d757b66a fix: analytics colour pick is not excluding unknown (#6552)
* fix: analytics colour picking not excluding unknown

* feat: improve colours, better accessibility
2026-06-29 17:17:03 +00:00
Calum H.andGitHub 862b54f00d refactor: instance export modal (#6543)
* refactor: export modal w the design system

* fix: lint

* fix: rev

* fix: lint

* fix: qa
2026-06-29 17:01:00 +00:00
Calum H.andGitHub c2f4835fe7 fix: spacing + friends (#6550) 2026-06-29 17:00:59 +00:00
ThatGravyBoatandGitHub b97c191d75 fix(docs): create version endpoint missing file_types field (#6551) 2026-06-29 16:22:08 +00:00
Truman GaoandGitHub b0c6a06909 feat: update versions table (#6502)
* feat: add new versions table, move environments column to be feature flag toggled, and add header/cell class props to Table.vue

* feat: implement much better table column widths

* feat: update version filter control to use multiselect

* feat: implement clicking table row to go to version

* feat: mobile pass on versions table

* feat: use multiselect for platform, and fix game version show all versions when dont exist

* pnpm prepr

* feat: replace dashboard projects table with new table

* feat: update projects so its out of card

* fix: version actions buttons column width

* feat: implement overflow on loaders cell

* update platform and version width

* feat: update project icon

* feat: change edit links to use floating action bar

* pnpm prepr
2026-06-29 15:01:07 +00:00
ThatGravyBoatandGitHub fc3e384f54 fix: tech review card not refreshing on status change (#6508)
fix: tech rev card not refreshing on status change
2026-06-29 14:40:20 +00:00
Calum H.andGitHub 87ff8fd4d9 fix: server panel not using correct endpoint for mrpack reupload (#6539)
fix: server panel not using correct endpoint for local modpack reupload
2026-06-29 14:39:03 +00:00
Calum H.andGitHub 288c1fb970 fix: reduce ping timeout in app to 5 sec not 30 sec (#6545)
* fix: reduce ping timeout in app to 5 sec not 30 sec

* feat: readd comment
2026-06-29 14:38:51 +00:00
Calum H.andGitHub f6e6ac28d4 fix: change fs watcher to rely more on instance ids than path (#6547)
* fix: change fs watcher to rely more on instance ids than path

* fix: fmt
2026-06-29 14:38:44 +00:00
Calum H.andGitHub 4a972bca73 fix: change logic when selecting filters in Worlds.vue (#6548) 2026-06-29 14:38:37 +00:00
Calum H.andGitHub b09c26f616 fix: console sizing issues (#6540)
fix: console sizing issues (for good)
2026-06-29 14:38:30 +00:00
ArthurandGitHub 204bd52a5a fix: modpack content modal toggle state (#6532)
Fix modpack content modal toggle state
2026-06-29 14:04:55 +00:00
Calum H.andGitHub b59f327b04 feat: add chaos cubed skins (#6463) 2026-06-29 12:18:15 +00:00
Modrinth BotandGitHub 89e643fa50 New translations from Crowdin (main) (#6542) 2026-06-29 12:04:10 +00:00
Calum H.andGitHub cee25fdbbc fix: unlinking local mrpack does not show content afterwards (#6541) 2026-06-29 11:58:43 +00:00
Calum H.andGitHub b95a2d875a feat: changelog app 0.15.1 (#6522) 2026-06-26 16:42:19 +00:00
380 changed files with 27418 additions and 7166 deletions
-7
View File
@@ -76,13 +76,6 @@ jobs:
env:
SCCACHE_DIR: ${{ needs.skip-if-clean.outputs.internal == 'true' && '/mnt/sccache' || '' }}
SCCACHE_CACHE_SIZE: ${{ needs.skip-if-clean.outputs.internal == 'true' && '10G' || '' }}
SCCACHE_MULTILEVEL_CHAIN: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'disk,s3' || '' }}
SCCACHE_S3_KEY_PREFIX: ${{ needs.skip-if-clean.outputs.internal == 'true' && format('{0}/', github.repository) || '' }}
SCCACHE_BUCKET: ${{ secrets.SCCACHE_BUCKET }}
SCCACHE_REGION: ${{ secrets.SCCACHE_REGION }}
SCCACHE_ENDPOINT: ${{ secrets.SCCACHE_ENDPOINT }}
AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_S3_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_S3_SECRET_ACCESS_KEY }}
RUSTC_WRAPPER: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'sccache' || '' }}
needs: [skip-if-clean]
if: ${{ needs.skip-if-clean.outputs.skip != 'true' }}
+6 -11
View File
@@ -78,14 +78,8 @@ jobs:
GIT_HASH: ${{ github.sha }}
SCCACHE_DIR: ${{ needs.skip-if-clean.outputs.internal == 'true' && '/mnt/sccache' || '' }}
SCCACHE_CACHE_SIZE: ${{ needs.skip-if-clean.outputs.internal == 'true' && '10G' || '' }}
SCCACHE_MULTILEVEL_CHAIN: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'disk,s3' || '' }}
SCCACHE_S3_KEY_PREFIX: ${{ needs.skip-if-clean.outputs.internal == 'true' && format('{0}/', github.repository) || '' }}
SCCACHE_BUCKET: ${{ secrets.SCCACHE_BUCKET }}
SCCACHE_REGION: ${{ secrets.SCCACHE_REGION }}
SCCACHE_ENDPOINT: ${{ secrets.SCCACHE_ENDPOINT }}
AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_S3_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_S3_SECRET_ACCESS_KEY }}
RUSTC_WRAPPER: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'sccache' || '' }}
RUST_MIN_STACK: '16777216'
steps:
- name: Check out code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
@@ -100,10 +94,11 @@ jobs:
uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1 / Mold 2.41.0
- name: Install build dependencies
uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # v1.6.0
with:
packages: cmake libcurl4-openssl-dev
version: v2 # cache key
run: sudo apt-get update && sudo apt-get install -y --no-install-recommends cmake libcurl4-openssl-dev
#uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # v1.6.0
#with:
# packages: cmake libcurl4-openssl-dev
# version: v2 # cache key
- name: Cache Cargo registry and index
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
-7
View File
@@ -81,13 +81,6 @@ jobs:
# blacksmith runner)
SCCACHE_DIR: ${{ needs.skip-if-clean.outputs.internal == 'true' && '/mnt/sccache' || '' }}
SCCACHE_CACHE_SIZE: ${{ needs.skip-if-clean.outputs.internal == 'true' && '10G' || '' }}
SCCACHE_MULTILEVEL_CHAIN: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'disk,s3' || '' }}
SCCACHE_S3_KEY_PREFIX: ${{ needs.skip-if-clean.outputs.internal == 'true' && format('{0}/', github.repository) || '' }}
SCCACHE_BUCKET: ${{ secrets.SCCACHE_BUCKET }}
SCCACHE_REGION: ${{ secrets.SCCACHE_REGION }}
SCCACHE_ENDPOINT: ${{ secrets.SCCACHE_ENDPOINT }}
AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_S3_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_S3_SECRET_ACCESS_KEY }}
RUSTC_WRAPPER: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'sccache' || '' }}
steps:
Generated
+147 -64
View File
@@ -59,9 +59,9 @@ dependencies = [
[[package]]
name = "actix-http"
version = "3.11.2"
version = "3.13.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7926860314cbe2fb5d1f13731e387ab43bd32bca224e82e6e2db85de0a3dba49"
checksum = "48e2faa3e7418ed780cca54829d32782a4008a077230f67457caa063415e99c2"
dependencies = [
"actix-codec",
"actix-rt",
@@ -75,7 +75,7 @@ dependencies = [
"derive_more 2.1.1",
"encoding_rs",
"flate2",
"foldhash 0.1.5",
"foldhash 0.2.0",
"futures-core",
"h2 0.3.27",
"http 0.2.12",
@@ -87,8 +87,8 @@ dependencies = [
"mime",
"percent-encoding",
"pin-project-lite",
"rand 0.9.2",
"sha1",
"rand 0.10.1",
"sha1 0.11.0",
"smallvec",
"tokio",
"tokio-util",
@@ -146,9 +146,9 @@ dependencies = [
[[package]]
name = "actix-router"
version = "0.5.3"
version = "0.5.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "13d324164c51f63867b57e73ba5936ea151b8a41a1d23d1031eeb9f70d0236f8"
checksum = "14f8c75c51892f18d9c46150c5ac7beb81c95f78c8b83a634d49f4ca32551fe7"
dependencies = [
"bytestring",
"cfg-if",
@@ -209,9 +209,9 @@ dependencies = [
[[package]]
name = "actix-web"
version = "4.11.0"
version = "4.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a597b77b5c6d6a1e1097fddde329a83665e25c5437c696a3a9a4aa514a614dea"
checksum = "df09e2d9239703dd64056359c920c7f3fba6535ec61a0059e0f44e095ffe02b4"
dependencies = [
"actix-codec",
"actix-http",
@@ -228,7 +228,7 @@ dependencies = [
"cookie 0.16.2",
"derive_more 2.1.1",
"encoding_rs",
"foldhash 0.1.5",
"foldhash 0.2.0",
"futures-core",
"futures-util",
"impl-more",
@@ -244,7 +244,7 @@ dependencies = [
"serde_json",
"serde_urlencoded",
"smallvec",
"socket2 0.5.10",
"socket2 0.6.1",
"time",
"tracing",
"url",
@@ -1127,7 +1127,7 @@ dependencies = [
"http-body-util",
"md-5",
"pin-project-lite",
"sha1",
"sha1 0.10.6",
"sha2",
"tracing",
]
@@ -1499,7 +1499,7 @@ version = "0.10.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "46502ad458c9a52b69d4d4d32775c788b7a1b85e8bc9d482d92250fc0e3f8efe"
dependencies = [
"digest",
"digest 0.10.7",
]
[[package]]
@@ -1511,6 +1511,15 @@ dependencies = [
"generic-array",
]
[[package]]
name = "block-buffer"
version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa"
dependencies = [
"hybrid-array",
]
[[package]]
name = "block2"
version = "0.5.1"
@@ -2224,6 +2233,12 @@ version = "0.9.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8"
[[package]]
name = "const-oid"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c"
[[package]]
name = "const-random"
version = "0.1.18"
@@ -2424,7 +2439,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd92aca2c6001b1bf5ba0ff84ee74ec8501b52bbef0cac80bf25a6c1d87a83d"
dependencies = [
"crc",
"digest",
"digest 0.10.7",
"rustversion",
"spin 0.10.0",
]
@@ -2515,6 +2530,15 @@ dependencies = [
"typenum",
]
[[package]]
name = "crypto-common"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453"
dependencies = [
"hybrid-array",
]
[[package]]
name = "cssparser"
version = "0.29.6"
@@ -2791,7 +2815,7 @@ version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e7c1832837b905bbfb5101e07cc24c8deddf52f93225eee6ead5f4d63d53ddcb"
dependencies = [
"const-oid",
"const-oid 0.9.6",
"pem-rfc7468",
"zeroize",
]
@@ -2904,12 +2928,23 @@ version = "0.10.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292"
dependencies = [
"block-buffer",
"const-oid",
"crypto-common",
"block-buffer 0.10.4",
"const-oid 0.9.6",
"crypto-common 0.1.6",
"subtle",
]
[[package]]
name = "digest"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2"
dependencies = [
"block-buffer 0.12.1",
"const-oid 0.10.2",
"crypto-common 0.2.2",
]
[[package]]
name = "directories"
version = "6.0.0"
@@ -3127,7 +3162,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
dependencies = [
"der",
"digest",
"digest 0.10.7",
"elliptic-curve",
"rfc6979",
"signature",
@@ -3151,7 +3186,7 @@ checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47"
dependencies = [
"base16ct",
"crypto-bigint",
"digest",
"digest 0.10.7",
"ff",
"generic-array",
"group",
@@ -4402,7 +4437,7 @@ version = "0.12.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e"
dependencies = [
"digest",
"digest 0.10.7",
]
[[package]]
@@ -4532,6 +4567,15 @@ version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9"
[[package]]
name = "hybrid-array"
version = "0.4.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "818356c5132c1fede50f837ca96afbe78ff42413047f4abb886217845e1b6c8c"
dependencies = [
"typenum",
]
[[package]]
name = "hyper"
version = "0.14.32"
@@ -4893,9 +4937,9 @@ checksum = "e7c5cedc30da3a610cac6b4ba17597bdf7152cf974e8aab3afb3d54455e371c8"
[[package]]
name = "impl-more"
version = "0.1.9"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e8a5a9a0ff0086c7a148acb942baaabeadf9504d10400b5a05645853729b9cd2"
checksum = "35a84fd5aa25fae5c0f4a33d9cac2ca017fc622cbd089be2229993514990f870"
[[package]]
name = "indenter"
@@ -5390,11 +5434,12 @@ dependencies = [
"rust_iso3166",
"rustls 0.23.32",
"rusty-money",
"scalar_api_reference",
"sentry",
"serde",
"serde_json",
"serde_with",
"sha1",
"sha1 0.10.6",
"sha2",
"spdx",
"sqlx",
@@ -5411,8 +5456,6 @@ dependencies = [
"url",
"urlencoding",
"utoipa",
"utoipa-actix-web",
"utoipa-scalar",
"uuid 1.23.3",
"validator",
"webauthn-rs",
@@ -5822,7 +5865,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf"
dependencies = [
"cfg-if",
"digest",
"digest 0.10.7",
]
[[package]]
@@ -8494,8 +8537,8 @@ version = "0.9.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b"
dependencies = [
"const-oid",
"digest",
"const-oid 0.9.6",
"digest 0.10.7",
"num-bigint-dig",
"num-integer",
"num-traits",
@@ -8508,6 +8551,40 @@ dependencies = [
"zeroize",
]
[[package]]
name = "rust-embed"
version = "8.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "04113cb9355a377d83f06ef1f0a45b8ab8cd7d8b1288160717d66df5c7988d27"
dependencies = [
"rust-embed-impl",
"rust-embed-utils",
"walkdir",
]
[[package]]
name = "rust-embed-impl"
version = "8.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da0902e4c7c8e997159ab384e6d0fc91c221375f6894346ae107f47dd0f3ccaa"
dependencies = [
"proc-macro2",
"quote",
"rust-embed-utils",
"syn 2.0.106",
"walkdir",
]
[[package]]
name = "rust-embed-utils"
version = "8.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1"
dependencies = [
"sha2",
"walkdir",
]
[[package]]
name = "rust-ini"
version = "0.21.3"
@@ -8827,6 +8904,18 @@ dependencies = [
"winapi-util",
]
[[package]]
name = "scalar_api_reference"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d67c85edd56c41f364603eff688a330f01dee99bdfc84c005d3bc3d0721d6b2"
dependencies = [
"actix-web",
"rust-embed",
"serde",
"serde_json",
]
[[package]]
name = "scc"
version = "2.4.0"
@@ -9252,15 +9341,15 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.145"
version = "1.0.150"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "402a6f66d8c709116cf22f558eab210f5a50187f702eb4d7e5ef38d9a7f1c79c"
checksum = "e8014e44b4736ed0538adeecded0fce2a272f22dc9578a7eb6b2d9993c74cfb9"
dependencies = [
"itoa",
"memchr",
"ryu",
"serde",
"serde_core",
"zmij",
]
[[package]]
@@ -9455,7 +9544,18 @@ checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba"
dependencies = [
"cfg-if",
"cpufeatures 0.2.17",
"digest",
"digest 0.10.7",
]
[[package]]
name = "sha1"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aacc4cc499359472b4abe1bf11d0b12e688af9a805fa5e3016f9a386dc2d0214"
dependencies = [
"cfg-if",
"cpufeatures 0.3.0",
"digest 0.11.3",
]
[[package]]
@@ -9472,7 +9572,7 @@ checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283"
dependencies = [
"cfg-if",
"cpufeatures 0.2.17",
"digest",
"digest 0.10.7",
]
[[package]]
@@ -9505,7 +9605,7 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
"digest",
"digest 0.10.7",
"rand_core 0.6.4",
]
@@ -9782,7 +9882,7 @@ dependencies = [
"bytes",
"chrono",
"crc",
"digest",
"digest 0.10.7",
"dotenvy",
"either",
"futures-channel",
@@ -9803,7 +9903,7 @@ dependencies = [
"rsa",
"rust_decimal",
"serde",
"sha1",
"sha1 0.10.6",
"sha2",
"smallvec",
"sqlx-core",
@@ -11290,7 +11390,7 @@ dependencies = [
"constant_time_eq",
"hmac",
"rand 0.9.2",
"sha1",
"sha1 0.10.6",
"sha2",
]
@@ -11505,7 +11605,7 @@ dependencies = [
"rand 0.9.2",
"rustls 0.23.32",
"rustls-pki-types",
"sha1",
"sha1 0.10.6",
"thiserror 2.0.17",
"utf-8",
]
@@ -11524,9 +11624,9 @@ checksum = "bc7d623258602320d5c55d1bc22793b57daff0ec7efc270ea7d55ce1d5f5471c"
[[package]]
name = "typenum"
version = "1.19.0"
version = "1.20.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb"
checksum = "b6f5e870be6c3b371b77fe0ee0bafb859fa4964b4404c27de1d380043c4dda20"
[[package]]
name = "uds_windows"
@@ -11757,17 +11857,6 @@ dependencies = [
"utoipa-gen",
]
[[package]]
name = "utoipa-actix-web"
version = "0.1.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7eda9c23c05af0fb812f6a177514047331dac4851a2c8e9c4b895d6d826967f"
dependencies = [
"actix-service",
"actix-web",
"utoipa",
]
[[package]]
name = "utoipa-gen"
version = "5.4.0"
@@ -11782,18 +11871,6 @@ dependencies = [
"uuid 1.23.3",
]
[[package]]
name = "utoipa-scalar"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "59559e1509172f6b26c1cdbc7247c4ddd1ac6560fe94b584f81ee489b141f719"
dependencies = [
"actix-web",
"serde",
"serde_json",
"utoipa",
]
[[package]]
name = "uuid"
version = "0.8.2"
@@ -13450,6 +13527,12 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f06ae92f42f5e5c42443fd094f245eb656abf56dd7cce9b8b263236565e00f2"
[[package]]
name = "zmij"
version = "1.0.21"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b8848ee67ecc8aedbaf3e4122217aff892639231befc6a1b58d29fff4c2cabaa"
[[package]]
name = "zopfli"
version = "0.8.2"
+1 -2
View File
@@ -158,6 +158,7 @@ rust-s3 = { version = "0.37.0", default-features = false, features = [
] }
rustls = "0.23.32"
rusty-money = "0.4.1"
scalar_api_reference = { version = "0.2.2", default-features = false }
secrecy = "0.10.3"
sentry = { version = "0.45.0", default-features = false, features = [
"backtrace",
@@ -217,8 +218,6 @@ typed-path = "0.12.0"
url = "2.5.7"
urlencoding = "2.1.3"
utoipa = { version = "5.4.0", features = ["actix_extras", "chrono", "decimal"] }
utoipa-actix-web = { version = "0.1.2" }
utoipa-scalar = { version = "0.3.0", default-features = false }
uuid = "1.18.1"
validator = "0.20.0"
webauthn-rs = "0.5.5"
@@ -14,31 +14,7 @@
<UnplugIcon class="text-secondary" />
<span class="text-sm text-contrast"> {{ formatMessage(messages.offline) }} </span>
</div>
<ButtonStyled color="brand" type="outlined" hover-color-fill="background">
<button
v-if="showUpdatePill"
type="button"
class="!h-[34px] overflow-hidden text-sm !transition-[width,opacity,transform,background-color,color,filter] !duration-200 ease-out"
:class="[
updatePillWidthClass,
{
'update-pill-ready-hidden': finishedDownloading && !animateReadyPill,
'update-pill-ready-visible': finishedDownloading && animateReadyPill,
},
]"
:disabled="isUpdateDownloading"
:aria-busy="isUpdateDownloading"
@click="handleUpdateClick"
>
<RefreshCwIcon v-if="finishedDownloading" :class="{ 'animate-spin': restarting }" />
<DownloadIcon v-else />
<span v-if="isUpdateDownloading">
{{ formatMessage(messages.downloadingUpdate) }}
<span class="inline-block w-[3ch] text-right tabular-nums">{{ downloadPercent }}%</span>
</span>
<span v-else>{{ updateLabel }}</span>
</button>
</ButtonStyled>
<AppUpdateButton />
<div
class="flex border-solid border-surface-5 text-sm items-center gap-2 py-1.5 px-3 rounded-xl border"
>
@@ -144,7 +120,6 @@ import {
DownloadIcon,
DropdownIcon,
OnlineIndicatorIcon,
RefreshCwIcon,
StarIcon,
StopCircleIcon,
TerminalSquareIcon,
@@ -161,9 +136,10 @@ import {
} from '@modrinth/ui'
import { convertFileSrc } from '@tauri-apps/api/core'
import { Dropdown } from 'floating-vue'
import { computed, nextTick, onBeforeUnmount, onMounted, ref, watch } from 'vue'
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import AppUpdateButton from '@/components/ui/app-update-button/index.vue'
import { useInstallJobNotifications } from '@/composables/browse/install-job-notifications'
import { trackEvent } from '@/helpers/analytics'
import { loading_listener, process_listener } from '@/helpers/events'
@@ -172,11 +148,6 @@ import { get_all as getRunningProcesses, kill as killProcess } from '@/helpers/p
import type { LoadingBar } from '@/helpers/state'
import { progress_bars_list } from '@/helpers/state'
import type { GameInstance } from '@/helpers/types'
import {
appUpdateState,
downloadAvailableAppUpdate,
installAvailableAppUpdate,
} from '@/providers/app-update'
const { handleError } = injectNotificationManager()
const popupNotificationManager = injectPopupNotificationManager()
@@ -241,96 +212,8 @@ const messages = defineMessages({
id: 'app.action-bar.view-active-downloads',
defaultMessage: 'View active downloads',
},
update: {
id: 'app.action-bar.update',
defaultMessage: 'Update',
},
downloadingUpdate: {
id: 'app.action-bar.downloading-update',
defaultMessage: 'Downloading update',
},
reloadToUpdate: {
id: 'app.action-bar.reload-to-update',
defaultMessage: 'Reload to update',
},
})
const {
downloading,
downloadPercent,
downloadProgress,
finishedDownloading,
isVisible: isUpdateVisible,
metered,
restarting,
} = appUpdateState
const isUpdateDownloading = computed(
() =>
downloading.value ||
(downloadProgress.value > 0 && downloadProgress.value < 1 && !finishedDownloading.value),
)
const showUpdatePill = computed(
() => isUpdateVisible.value && (finishedDownloading.value || metered.value),
)
const animateReadyPill = ref(false)
const updateLabel = computed(() => {
if (isUpdateDownloading.value) {
return formatMessage(messages.downloadingUpdate)
}
if (finishedDownloading.value) {
return formatMessage(messages.reloadToUpdate)
}
return formatMessage(messages.update)
})
const updatePillWidthClass = computed(() => {
if (isUpdateDownloading.value) {
return 'w-[219px]'
}
if (finishedDownloading.value) {
return 'w-[166px]'
}
return '!w-[96px]'
})
let readyPillAnimationFrame: number | null = null
watch([showUpdatePill, finishedDownloading], async ([show, ready], [wasShown, wasReady]) => {
if (readyPillAnimationFrame !== null) {
cancelAnimationFrame(readyPillAnimationFrame)
readyPillAnimationFrame = null
}
if (!show || !ready) {
animateReadyPill.value = false
return
}
if (wasShown && wasReady) {
return
}
animateReadyPill.value = false
await nextTick()
readyPillAnimationFrame = requestAnimationFrame(() => {
animateReadyPill.value = true
readyPillAnimationFrame = null
})
})
async function handleUpdateClick() {
if (isUpdateDownloading.value) {
return
}
if (finishedDownloading.value) {
await installAvailableAppUpdate()
} else {
await downloadAvailableAppUpdate()
}
}
const currentProcesses = ref<RunningProcess[]>([])
const selectedProcess = ref<RunningProcess | undefined>()
@@ -619,20 +502,5 @@ onBeforeUnmount(() => {
unlistenProcess()
unlistenLoading()
installJobNotifications.dispose()
if (readyPillAnimationFrame !== null) {
cancelAnimationFrame(readyPillAnimationFrame)
}
})
</script>
<style scoped>
.update-pill-ready-hidden {
opacity: 0;
transform: scale(0.96);
}
.update-pill-ready-visible {
opacity: 1;
transform: scale(1);
}
</style>
@@ -1,28 +1,32 @@
<script setup>
import { WrenchIcon, XIcon } from '@modrinth/assets'
import { XIcon } from '@modrinth/assets'
import {
Accordion,
ButtonStyled,
Checkbox,
commonMessages,
defineMessages,
FileTreeSelect,
injectNotificationManager,
NewModal,
StyledInput,
useVIntl,
} from '@modrinth/ui'
import { save } from '@tauri-apps/plugin-dialog'
import { readDir, stat } from '@tauri-apps/plugin-fs'
import { ref } from 'vue'
import { PackageIcon, VersionIcon } from '@/assets/icons'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import { export_instance_mrpack, get_pack_export_candidates } from '@/helpers/instance'
import { PackageIcon } from '@/assets/icons'
import {
export_instance_mrpack,
get_full_path,
get_pack_export_candidates,
} from '@/helpers/instance'
const { handleError } = injectNotificationManager()
const { formatMessage } = useVIntl()
const messages = defineMessages({
header: { id: 'app.export-modal.header', defaultMessage: 'Export modpack' },
modpackNameLabel: { id: 'app.export-modal.modpack-name-label', defaultMessage: 'Modpack Name' },
modpackNameLabel: { id: 'app.export-modal.modpack-name-label', defaultMessage: 'Modpack name' },
modpackNamePlaceholder: {
id: 'app.export-modal.modpack-name-placeholder',
defaultMessage: 'Modpack name',
@@ -39,15 +43,7 @@ const messages = defineMessages({
id: 'app.export-modal.description-placeholder',
defaultMessage: 'Enter modpack description...',
},
selectFilesLabel: {
id: 'app.export-modal.select-files-label',
defaultMessage: 'Configure which files are included in this export',
},
exportButton: { id: 'app.export-modal.export-button', defaultMessage: 'Export' },
includeFile: {
id: 'app.export-modal.include-file-accessibility-label',
defaultMessage: 'Include "{file}"?',
},
})
const props = defineProps({
@@ -59,8 +55,9 @@ const props = defineProps({
defineExpose({
show: () => {
resetExportState()
exportModal.value.show()
initFiles()
void initFiles().catch(handleError)
},
})
@@ -69,62 +66,33 @@ const nameInput = ref(props.instance.name)
const exportDescription = ref('')
const versionInput = ref('1.0.0')
const files = ref([])
const folders = ref([])
const selectedFilePaths = ref([])
const fileTreeKey = ref(0)
const filesLoadId = ref(0)
const instanceRoot = ref('')
const loadedDirectories = ref(new Set())
const initFiles = async () => {
const newFolders = new Map()
const sep = '/'
files.value = []
await get_pack_export_candidates(props.instance.id).then((filePaths) =>
filePaths
.map((folder) => ({
path: folder,
name: folder.split(sep).pop(),
selected:
folder.startsWith('mods') ||
folder.startsWith('datapacks') ||
folder.startsWith('resourcepacks') ||
folder.startsWith('shaderpacks') ||
folder.startsWith('config'),
disabled:
folder === 'profile.json' ||
folder.startsWith('modrinth_logs') ||
folder.startsWith('.fabric') ||
folder.startsWith('__MACOSX'),
}))
.forEach((pathData) => {
const parent = pathData.path.split(sep).slice(0, -1).join(sep)
if (parent !== '') {
if (newFolders.has(parent)) {
newFolders.get(parent).push(pathData)
} else {
newFolders.set(parent, [pathData])
}
} else {
files.value.push(pathData)
}
}),
)
folders.value = [...newFolders.entries()].map(([name, value]) => [
{
name,
showingMore: false,
},
value,
async function initFiles() {
const loadId = ++filesLoadId.value
const [filePaths, root] = await Promise.all([
get_pack_export_candidates(props.instance.id),
get_full_path(props.instance.id),
])
if (loadId !== filesLoadId.value) return
instanceRoot.value = root
const exportCandidates = await Promise.all(
filePaths.map((path) => buildExportCandidateItem(root, path)),
)
if (loadId !== filesLoadId.value) return
files.value = exportCandidates
selectedFilePaths.value = files.value
.filter((file) => !file.disabled && isDefaultSelectedExportCandidate(file.path))
.map((file) => file.path)
}
await initFiles()
const exportPack = async () => {
const filesToExport = files.value.filter((file) => file.selected).map((file) => file.path)
folders.value.forEach((args) => {
args[1].forEach((child) => {
if (child.selected) {
filesToExport.push(child.path)
}
})
})
const outputPath = await save({
defaultPath: `${nameInput.value} ${versionInput.value}.mrpack`,
filters: [
@@ -139,7 +107,7 @@ const exportPack = async () => {
export_instance_mrpack(
props.instance.id,
outputPath,
filesToExport,
selectedFilePaths.value,
versionInput.value,
exportDescription.value,
nameInput.value,
@@ -147,94 +115,176 @@ const exportPack = async () => {
exportModal.value.hide()
}
}
function resetExportState() {
nameInput.value = props.instance.name
exportDescription.value = ''
versionInput.value = '1.0.0'
files.value = []
selectedFilePaths.value = []
fileTreeKey.value += 1
instanceRoot.value = ''
loadedDirectories.value = new Set()
}
async function loadExportDirectory(path) {
if (!path || !instanceRoot.value || loadedDirectories.value.has(path)) return
const loadId = filesLoadId.value
loadedDirectories.value.add(path)
try {
const entries = await readDir(`${instanceRoot.value}/${path}`)
const childItems = await Promise.all(
entries.map((entry) => buildExportDirectoryChildItem(instanceRoot.value, path, entry)),
)
if (loadId !== filesLoadId.value) return
appendExportItems(childItems)
} catch {
loadedDirectories.value.delete(path)
}
}
async function buildExportCandidateItem(instanceRoot, path) {
try {
const entries = await readDir(`${instanceRoot}/${path}`)
const metadata = await getExportCandidateMetadata(instanceRoot, path)
return {
path,
type: 'directory',
disabled: isExportCandidateDisabled(path),
modified: metadata.modified,
count: entries.length,
}
} catch {
return buildExportFileItem(instanceRoot, path)
}
}
async function buildExportDirectoryChildItem(instanceRoot, parentPath, entry) {
const path = `${parentPath}/${entry.name}`
if (entry.isDirectory) {
const metadata = await getExportCandidateMetadata(instanceRoot, path)
return {
path,
type: 'directory',
disabled: isExportCandidateDisabled(path),
modified: metadata.modified,
}
}
return buildExportFileItem(instanceRoot, path)
}
async function buildExportFileItem(instanceRoot, path) {
const metadata = await getExportCandidateMetadata(instanceRoot, path)
return {
path,
type: 'file',
disabled: isExportCandidateDisabled(path),
size: metadata.size,
modified: metadata.modified,
}
}
function appendExportItems(items) {
const nextFiles = new Map(files.value.map((file) => [normalizeExportPath(file.path), file]))
for (const item of items) {
nextFiles.set(normalizeExportPath(item.path), item)
}
files.value = [...nextFiles.values()]
}
async function getExportCandidateMetadata(instanceRoot, path) {
try {
const metadata = await stat(`${instanceRoot}/${path}`)
return {
size: metadata.size,
modified: metadata.mtime ? Math.floor(metadata.mtime.getTime() / 1000) : undefined,
}
} catch {
return {}
}
}
function normalizeExportPath(path) {
return path.replaceAll('\\', '/').split('/').filter(Boolean).join('/')
}
function isDefaultSelectedExportCandidate(path) {
return (
path.startsWith('mods') ||
path.startsWith('datapacks') ||
path.startsWith('resourcepacks') ||
path.startsWith('shaderpacks') ||
path.startsWith('config')
)
}
function isExportCandidateDisabled(path) {
return (
path === 'profile.json' ||
path.startsWith('modrinth_logs') ||
path.startsWith('.fabric') ||
path.startsWith('__MACOSX')
)
}
</script>
<template>
<ModalWrapper ref="exportModal" :header="formatMessage(messages.header)">
<div class="flex flex-col gap-4 w-[40rem]">
<NewModal
ref="exportModal"
:header="formatMessage(messages.header)"
scrollable
width="46rem"
max-width="calc(100vw - 2rem)"
>
<div class="flex flex-col gap-4">
<div class="grid grid-cols-2 gap-4">
<div class="labeled_input">
<p>{{ formatMessage(messages.modpackNameLabel) }}</p>
<div class="labeled_input w-full">
<p class="text-contrast font-semibold">{{ formatMessage(messages.modpackNameLabel) }}</p>
<StyledInput
v-model="nameInput"
:icon="PackageIcon"
type="text"
:placeholder="formatMessage(messages.modpackNamePlaceholder)"
clearable
wrapper-class="w-full"
/>
</div>
<div class="labeled_input">
<p>{{ formatMessage(messages.versionNumberLabel) }}</p>
<div class="labeled_input w-full">
<p class="text-contrast font-semibold">
{{ formatMessage(messages.versionNumberLabel) }}
</p>
<StyledInput
v-model="versionInput"
:icon="VersionIcon"
type="text"
:placeholder="formatMessage(messages.versionNumberPlaceholder)"
clearable
wrapper-class="w-full"
/>
</div>
</div>
<div class="flex flex-col gap-2">
<p class="m-0">{{ formatMessage(commonMessages.descriptionLabel) }}</p>
<div class="flex flex-col gap-2 min-w-0">
<p class="m-0 text-contrast font-semibold">
{{ formatMessage(commonMessages.descriptionLabel) }}
</p>
<StyledInput
v-model="exportDescription"
multiline
:placeholder="formatMessage(messages.descriptionPlaceholder)"
wrapper-class="w-full"
/>
</div>
<Accordion
class="w-full bg-surface-4 border border-solid border-surface-5 rounded-2xl overflow-clip"
button-class="p-4 w-full border-b border-solid border-b-surface-5 bg-surface-2 -mb-px hover:brightness-[--hover-brightness] group"
>
<template #title>
<span class="flex items-center gap-3 text-contrast group-active:scale-[0.98]">
<WrenchIcon aria-hidden="true" class="size-5 text-secondary" />
Configure which files are included in this export
</span>
</template>
<div class="flex flex-col [&>*:nth-child(even)]:bg-surface-3">
<div v-for="[path, children] in folders" :key="path.name" class="flex flex-col">
<Accordion
class="flex flex-col"
button-class="flex gap-3 pr-4 hover:bg-surface-5 group"
>
<template #title>
<Checkbox
:model-value="children.every((child) => child.selected)"
:indeterminate="
!children.every((child) => child.selected) &&
children.some((child) => child.selected)
"
:description="formatMessage(messages.includeFile, { file: path.name })"
class="pl-4 py-2"
:disabled="children.every((x) => x.disabled)"
@update:model-value="
(newValue) => children.forEach((child) => (child.selected = newValue))
"
@click.stop
/>
<span class="ml-2 group-active:scale-95">{{ path.name }}/</span>
</template>
<div v-for="child in children" :key="child.path">
<Checkbox
v-model="child.selected"
:label="child.name"
class="w-full px-8 py-2 hover:bg-surface-4 text-primary"
:disabled="child.disabled"
/>
</div>
</Accordion>
</div>
<Checkbox
v-for="file in files"
:key="file.path"
v-model="file.selected"
:label="file.name"
:disabled="file.disabled"
class="w-full px-4 py-2 hover:bg-surface-4 text-primary"
/>
</div>
</Accordion>
<FileTreeSelect
:key="fileTreeKey"
v-model="selectedFilePaths"
class="min-w-0"
:items="files"
@navigate="loadExportDirectory"
/>
</div>
<template #actions>
<div class="flex items-center justify-end gap-2">
<ButtonStyled type="outlined">
<button @click="exportModal.hide">
@@ -249,6 +299,6 @@ const exportPack = async () => {
</button>
</ButtonStyled>
</div>
</div>
</ModalWrapper>
</template>
</NewModal>
</template>
@@ -0,0 +1,124 @@
<template>
<ButtonStyled color="brand" type="outlined" hover-color-fill="background">
<button
v-if="showUpdatePill"
type="button"
class="!h-[34px] text-sm !transition-[opacity,transform,background-color,color,filter] !duration-200 ease-out"
:class="{
'opacity-0 scale-[0.96]': finishedDownloading && !animateReadyPill,
'opacity-100 scale-100': finishedDownloading && animateReadyPill,
}"
:disabled="isUpdateDownloading"
:aria-busy="isUpdateDownloading"
@click="handleUpdateClick"
>
<RefreshCwIcon v-if="finishedDownloading" :class="{ 'animate-spin': restarting }" />
<DownloadIcon v-else />
<span v-if="isUpdateDownloading">
{{ formatMessage(messages.downloadingUpdate) }}
<span class="inline-block w-[3ch] text-right tabular-nums">{{ downloadPercent }}%</span>
</span>
<span v-else>{{ updateLabel }}</span>
</button>
</ButtonStyled>
</template>
<script setup lang="ts">
import { DownloadIcon, RefreshCwIcon } from '@modrinth/assets'
import { ButtonStyled, defineMessages, useVIntl } from '@modrinth/ui'
import { computed, nextTick, onBeforeUnmount, ref, watch } from 'vue'
import {
appUpdateState,
downloadAvailableAppUpdate,
installAvailableAppUpdate,
} from '@/providers/app-update'
const { formatMessage } = useVIntl()
const messages = defineMessages({
update: {
id: 'app.action-bar.update',
defaultMessage: 'Update',
},
downloadingUpdate: {
id: 'app.action-bar.downloading-update',
defaultMessage: 'Downloading update',
},
reloadToUpdate: {
id: 'app.action-bar.reload-to-update',
defaultMessage: 'Reload to update',
},
})
const {
downloading,
downloadPercent,
downloadProgress,
finishedDownloading,
isVisible: isUpdateVisible,
metered,
restarting,
} = appUpdateState
const isUpdateDownloading = computed(
() =>
downloading.value ||
(downloadProgress.value > 0 && downloadProgress.value < 1 && !finishedDownloading.value),
)
const showUpdatePill = computed(
() => isUpdateVisible.value && (finishedDownloading.value || metered.value),
)
const animateReadyPill = ref(false)
const updateLabel = computed(() => {
if (isUpdateDownloading.value) {
return formatMessage(messages.downloadingUpdate)
}
if (finishedDownloading.value) {
return formatMessage(messages.reloadToUpdate)
}
return formatMessage(messages.update)
})
let readyPillAnimationFrame: number | null = null
watch([showUpdatePill, finishedDownloading], async ([show, ready], [wasShown, wasReady]) => {
if (readyPillAnimationFrame !== null) {
cancelAnimationFrame(readyPillAnimationFrame)
readyPillAnimationFrame = null
}
if (!show || !ready) {
animateReadyPill.value = false
return
}
if (wasShown && wasReady) {
return
}
animateReadyPill.value = false
await nextTick()
readyPillAnimationFrame = requestAnimationFrame(() => {
animateReadyPill.value = true
readyPillAnimationFrame = null
})
})
async function handleUpdateClick() {
if (isUpdateDownloading.value) {
return
}
if (finishedDownloading.value) {
await installAvailableAppUpdate()
} else {
await downloadAvailableAppUpdate()
}
}
onBeforeUnmount(() => {
if (readyPillAnimationFrame !== null) {
cancelAnimationFrame(readyPillAnimationFrame)
}
})
</script>
@@ -1,5 +1,5 @@
<script setup lang="ts">
import { MailIcon, SendIcon, UserIcon, UserPlusIcon, XIcon } from '@modrinth/assets'
import { MailIcon, SearchIcon, SendIcon, UserIcon, UserPlusIcon, XIcon } from '@modrinth/assets'
import {
Avatar,
ButtonStyled,
@@ -301,11 +301,12 @@ const messages = defineMessages({
</ButtonStyled>
<StyledInput
v-model="search"
:icon="SearchIcon"
type="text"
:placeholder="formatMessage(messages.searchFriends)"
clearable
variant="outlined"
wrapper-class="flex-1"
input-class="!bg-transparent !border !border-solid !border-button-bg !text-primary !placeholder:text-primary"
wrapper-class="flex-1 [&>svg]:!text-primary [&>svg]:!opacity-100"
@keyup.esc="search = ''"
/>
</template>
@@ -8,13 +8,18 @@ import type { ComputedRef, Ref } from 'vue'
import { onUnmounted, ref, shallowRef } from 'vue'
import type { Router } from 'vue-router'
import {
fetchCachedServerStatus,
getFreshCachedServerStatus,
} from '@/composables/instances/use-server-status-query'
import { process_listener } from '@/helpers/events'
import { kill, list as listInstances } from '@/helpers/instance'
import { get_by_instance_id } from '@/helpers/process'
import type { GameInstance } from '@/helpers/types'
import { add_server_to_instance, getServerAddress, getServerLatency } from '@/helpers/worlds'
import { add_server_to_instance, getServerAddress } from '@/helpers/worlds'
interface BrowseServerInstance {
id: string
name: string
path: string
}
@@ -68,12 +73,10 @@ export function useAppServerBrowse(options: UseAppServerBrowseOptions) {
const queryClient = useQueryClient()
const debugLog = useDebugLogger('BrowseServer')
const serverPings = shallowRef<Record<string, number | undefined>>({})
const serverPingCache = new Map<string, number | undefined>()
const pendingServerPings = new Map<string, Promise<number | undefined>>()
const runningServerProjects = ref<Record<string, string>>({})
const lastServerHits = shallowRef<Labrinth.Search.v3.ResultSearchProject[]>([])
const contextMenuRef = ref<ContextMenuHandle | null>(null)
let serverPingCacheActive = true
let serverPingsActive = true
let unlistenProcesses: (() => void) | null = null
async function checkServerRunningStates(hits: Labrinth.Search.v3.ResultSearchProject[]) {
@@ -146,37 +149,26 @@ export function useAppServerBrowse(options: UseAppServerBrowseOptions) {
})
const nextPings = { ...serverPings.value }
for (const { hit, address } of pingsToFetch) {
if (serverPingCache.has(address)) {
nextPings[hit.project_id] = serverPingCache.get(address)
const cachedStatus = getFreshCachedServerStatus(queryClient, address)
if (cachedStatus) {
nextPings[hit.project_id] = cachedStatus.ping
}
}
serverPings.value = nextPings
await Promise.all(
pingsToFetch.map(async ({ hit, address }) => {
if (serverPingCache.has(address)) return
if (getFreshCachedServerStatus(queryClient, address)) return
let pending = pendingServerPings.get(address)
if (!pending) {
pending = getServerLatency(address)
.then((latency) => {
if (serverPingCacheActive) serverPingCache.set(address, latency)
return latency
})
.catch((error) => {
console.error(`Failed to ping server ${address}:`, error)
if (serverPingCacheActive) serverPingCache.set(address, undefined)
return undefined
})
.finally(() => {
pendingServerPings.delete(address)
})
pendingServerPings.set(address, pending)
try {
const status = await fetchCachedServerStatus(queryClient, address)
if (!serverPingsActive) return
serverPings.value = { ...serverPings.value, [hit.project_id]: status.ping }
} catch (error) {
console.error(`Failed to ping server ${address}:`, error)
if (!serverPingsActive) return
serverPings.value = { ...serverPings.value, [hit.project_id]: undefined }
}
const latency = await pending
if (!serverPingCacheActive) return
serverPings.value = { ...serverPings.value, [hit.project_id]: latency }
}),
)
}
@@ -308,10 +300,8 @@ export function useAppServerBrowse(options: UseAppServerBrowseOptions) {
.catch(options.handleError)
onUnmounted(() => {
serverPingCacheActive = false
serverPingsActive = false
unlistenProcesses?.()
serverPingCache.clear()
pendingServerPings.clear()
})
return {
@@ -0,0 +1,50 @@
import type { QueryClient } from '@tanstack/vue-query'
import {
get_server_status,
normalizeServerAddress,
type ProtocolVersion,
type ServerStatus,
} from '@/helpers/worlds'
export const SERVER_STATUS_CACHE_MS = 10 * 60 * 1000
function getProtocolVersionKey(protocolVersion: ProtocolVersion | null) {
if (!protocolVersion) return 'default'
return `${protocolVersion.version}:${protocolVersion.legacy ? 'legacy' : 'modern'}`
}
export function getServerStatusQueryKey(
address: string,
protocolVersion: ProtocolVersion | null = null,
) {
return [
'minecraft-server-status',
normalizeServerAddress(address) || address.trim().toLowerCase(),
getProtocolVersionKey(protocolVersion),
] as const
}
export function getFreshCachedServerStatus(
queryClient: QueryClient,
address: string,
protocolVersion: ProtocolVersion | null = null,
) {
const queryKey = getServerStatusQueryKey(address, protocolVersion)
const updatedAt = queryClient.getQueryState(queryKey)?.dataUpdatedAt ?? 0
if (!updatedAt || Date.now() - updatedAt >= SERVER_STATUS_CACHE_MS) return undefined
return queryClient.getQueryData<ServerStatus>(queryKey)
}
export async function fetchCachedServerStatus(
queryClient: QueryClient,
address: string,
protocolVersion: ProtocolVersion | null = null,
) {
return await queryClient.fetchQuery({
queryKey: getServerStatusQueryKey(address, protocolVersion),
queryFn: () => get_server_status(address, protocolVersion),
staleTime: SERVER_STATUS_CACHE_MS,
gcTime: SERVER_STATUS_CACHE_MS,
})
}
+30 -23
View File
@@ -404,28 +404,35 @@ export async function refreshServerData(
): Promise<void> {
const refreshTime = Date.now()
serverData.refreshing = true
await get_server_status(address, protocolVersion)
.then((status) => {
if (serverData.lastSuccessfulRefresh && serverData.lastSuccessfulRefresh > refreshTime) {
// Don't update if there was a more recent successful refresh
return
}
serverData.lastSuccessfulRefresh = Date.now()
serverData.status = status
if (status.description) {
serverData.rawMotd = status.description
serverData.renderedMotd = autoToHTML(status.description)
}
})
.finally(() => {
serverData.refreshing = false
})
.catch((err) => {
console.error(`Refreshing addr ${address}`, protocolVersion, err)
if (!protocolVersion?.legacy) {
refreshServerData(serverData, { version: 74, legacy: true }, address)
}
})
try {
const status = await get_server_status(address, protocolVersion)
if (serverData.lastSuccessfulRefresh && serverData.lastSuccessfulRefresh > refreshTime) {
// Don't update if there was a more recent successful refresh
return
}
serverData.lastSuccessfulRefresh = Date.now()
serverData.status = status
if (status.description) {
serverData.rawMotd = status.description
serverData.renderedMotd = autoToHTML(status.description)
} else {
delete serverData.rawMotd
delete serverData.renderedMotd
}
} catch (err) {
console.error(`Refreshing addr ${address}`, protocolVersion, err)
if (!protocolVersion?.legacy) {
await refreshServerData(serverData, { version: 74, legacy: true }, address)
return
}
if (!serverData.lastSuccessfulRefresh || serverData.lastSuccessfulRefresh <= refreshTime) {
delete serverData.status
delete serverData.rawMotd
delete serverData.renderedMotd
}
} finally {
serverData.refreshing = false
}
}
export function refreshServers(
@@ -444,7 +451,7 @@ export function refreshServers(
}
})
// noinspection ES6MissingAwait - handled with .then by refreshServerData already
// noinspection ES6MissingAwait - handled by refreshServerData
Object.keys(serverData).forEach((address) =>
refreshServerData(serverData[address], protocolVersion, address),
)
@@ -122,9 +122,6 @@
"app.export-modal.modpack-name-placeholder": {
"message": "إسم حزمة التعديل"
},
"app.export-modal.select-files-label": {
"message": "أختيار الملفات التي سيتم تصديرها"
},
"app.export-modal.version-number-label": {
"message": "رقم الإصدار"
},
+139 -22
View File
@@ -11,6 +11,33 @@
"app.action-bar.hide-more-running-instances": {
"message": "Skrýt více spuštěných instancí"
},
"app.action-bar.install.dismiss": {
"message": "Zavřít"
},
"app.action-bar.install.failed": {
"message": "Instalace selhala"
},
"app.action-bar.install.failed-app-closed": {
"message": "Instalace selhala kvůli zavření aplikace."
},
"app.action-bar.install.failed-network": {
"message": "Instalace selhala kvůli chybě sítě."
},
"app.action-bar.install.failed-unknown": {
"message": "Instalace selhala kvůli neznámé chybě."
},
"app.action-bar.install.open-instance": {
"message": "Otevřít instanci"
},
"app.action-bar.install.retry": {
"message": "Zkusit znovu"
},
"app.action-bar.install.unknown-instance": {
"message": "Neznámá instance"
},
"app.action-bar.installs": {
"message": "Instalace"
},
"app.action-bar.make-primary-instance": {
"message": "Nastavit jako primární instanci"
},
@@ -33,7 +60,7 @@
"message": "Zastavit instanci"
},
"app.action-bar.update": {
"message": "Aktualizace"
"message": "Aktualizovat"
},
"app.action-bar.view-active-downloads": {
"message": "Zobrazit probíhající stahování"
@@ -101,8 +128,14 @@
"app.appearance-settings.show-play-time.title": {
"message": "Zobrazit odehraný čas"
},
"app.appearance-settings.skip-non-essential-warnings.description": {
"message": "Automaticky přeskočí nízko riziková potrvzení jako duplicitní instalace modpacků, běžné mazání obsahu, hromadné aktualizace, odpojování modpacků a výzvy k opravě. Nebezpečná upozornění se budou nadále zobrazovat."
},
"app.appearance-settings.skip-non-essential-warnings.title": {
"message": "Přeskočit nedůležitá upozornění"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Umožní přepínat zobrazení postranního panelu."
"message": "Umožňí přepínat zobrazení postranního panelu."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "Přepnout postranní panel"
@@ -141,10 +174,10 @@
"message": "Zpět k instanci"
},
"app.browse.discover-content": {
"message": "Objevovat obsah"
"message": "Objevit obsah"
},
"app.browse.discover-servers": {
"message": "Objevovat servery"
"message": "Objevit servery"
},
"app.browse.hide-added-servers": {
"message": "Skrýt již přidané servery"
@@ -159,7 +192,7 @@
"message": "Instalování"
},
"app.content-install.no-compatible-versions": {
"message": "Žádná dostupná verze se neshoduje s verzí {compatibilityLabel}. Vyber verzi, abys ji i přesto nainstaloval/a. Závislosti nebudou automaticky nainstalovány."
"message": "Žádné dostupné verze se neshodují s {compatibilityLabel}. Vyberte verzi, kterou chcete přesto nainstalovat. Závislosti nebudou nainstalovány automaticky."
},
"app.export-modal.description-placeholder": {
"message": "Zadej popis modpacku..."
@@ -170,24 +203,72 @@
"app.export-modal.header": {
"message": "Exportovat modpack"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Zahrnout \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Název modpacku"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Název modpacku"
},
"app.export-modal.select-files-label": {
"message": "Nastavte, které soubory mají být do tohoto exportu zahrnuty"
},
"app.export-modal.version-number-label": {
"message": "Číslo verze"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.install.phase.downloading_content": {
"message": "Stahování obsahu"
},
"app.install.phase.downloading_minecraft": {
"message": "Stahování Minecraftu"
},
"app.install.phase.downloading_pack_file": {
"message": "Stahování pack souboru"
},
"app.install.phase.extracting_overrides": {
"message": "Rozbalování souborů overrides"
},
"app.install.phase.finalizing": {
"message": "Dokončení instalace"
},
"app.install.phase.preparing_instance": {
"message": "Příprava instance"
},
"app.install.phase.preparing_java": {
"message": "Příprava Javy"
},
"app.install.phase.preparing_java.downloading": {
"message": "Stahování Javy {version}"
},
"app.install.phase.preparing_java.extracting": {
"message": "Rozbalování Javy {version}"
},
"app.install.phase.preparing_java.fetching-metadata": {
"message": "Získávání Javy {version}"
},
"app.install.phase.preparing_java.resolving": {
"message": "Připravení Javy {version}"
},
"app.install.phase.preparing_java.validating": {
"message": "Validace Javy {version}"
},
"app.install.phase.reading_pack_manifest": {
"message": "Čtení pack manifestu"
},
"app.install.phase.resolving_loader": {
"message": "Vyhodnocování loaderu"
},
"app.install.phase.resolving_minecraft": {
"message": "Vyhodnocování Minecraftu"
},
"app.install.phase.resolving_pack": {
"message": "Vyhodnocování obsahu"
},
"app.install.phase.rolling_back": {
"message": "Obnovování do předchozího stavu"
},
"app.install.phase.running_loader_processors": {
"message": "Spuštění loader procesů"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Všechna data tvé instance budou trvale smazána, včetně světů, konfigurací a veškerého nainstalovaného obsahu."
},
@@ -195,7 +276,7 @@
"message": "Tato akce nemůže být vrácena"
},
"app.instance.confirm-delete.delete-button": {
"message": "Odstranit instanci"
"message": "Smazat instanci"
},
"app.instance.confirm-delete.header": {
"message": "Odstranění instance"
@@ -212,6 +293,15 @@
"app.instance.modpack-already-installed.instance": {
"message": "Instance"
},
"app.instance.mods.bulk-update.downloading-projects": {
"message": "Stahování {current, number}/{total, number} projektů..."
},
"app.instance.mods.bulk-update.finishing": {
"message": "Dokončení aktualizace..."
},
"app.instance.mods.bulk-update.resolving-versions": {
"message": "Vyhodnocování verzí..."
},
"app.instance.mods.content-type-project": {
"message": "projekt"
},
@@ -236,8 +326,20 @@
"app.instance.worlds.browse-servers": {
"message": "Procházet servery"
},
"app.instance.worlds.delete-world-modal.delete-button": {
"message": "Smazat svět"
},
"app.instance.worlds.delete-world-modal.title": {
"message": "Smazat svět"
},
"app.instance.worlds.delete-world-modal.warning-body": {
"message": "Tento svět bude trvale smazán z této instance. Tuto akci nelze vrátit zpět."
},
"app.instance.worlds.delete-world-modal.warning-header": {
"message": "Mazání {name}"
},
"app.instance.worlds.filter-modded": {
"message": "Módovaný"
"message": "Módované"
},
"app.instance.worlds.filter-offline": {
"message": "Offline"
@@ -249,10 +351,22 @@
"message": "Vanilla"
},
"app.instance.worlds.no-worlds-description": {
"message": "Přidej server nebo začni procházet"
"message": "Začněte přidáním serveru nebo procházením obsahu"
},
"app.instance.worlds.no-worlds-heading": {
"message": "Žádné servery nebo světy nebyly přidány"
"message": "Nejsou přidané žádné servery nebo světy"
},
"app.instance.worlds.remove-server-modal.remove-button": {
"message": "Odebrat server"
},
"app.instance.worlds.remove-server-modal.title": {
"message": "Odebrat server"
},
"app.instance.worlds.remove-server-modal.warning-body": {
"message": "Tento server bude odebrán z vašeho seznamu serverů i ze seznamu serverů ve hře. Pokud znáte jeho adresu, můžete ho později znovu přidat."
},
"app.instance.worlds.remove-server-modal.warning-header": {
"message": "Odebírání {name}"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Hledat v {count} světech..."
@@ -339,7 +453,7 @@
"message": "Smazat skin"
},
"app.skins.delete-modal.description": {
"message": "Tahle akce navždy smaže vybraný skin a nejde vrátit zpět."
"message": "Tímto dojde k trvalému smazání vybreného skinu. Tuto akci nelze vrátit zpět."
},
"app.skins.delete-modal.title": {
"message": "Opravdu chceš smazat tenhle skin?"
@@ -468,19 +582,19 @@
"message": "Nadšený Modrinth Bot"
},
"app.skins.sign-in.title": {
"message": "Přihlas se prosím"
"message": "Přihlaš se prosím"
},
"app.skins.title": {
"message": "Výběr skinu"
},
"app.update-popup.body.download-complete": {
"message": "Stahování aplikace Modrinth v{version} bylo dokončeno. Aktualizujte ji znovunačtením nebo se automaticky aktualizuje po zavření."
"message": "Stahování Modrinth App v{version} bylo dokončeno. Aktualizujte ji znovunačtením nebo se automaticky aktualizuje po zavření."
},
"app.update-popup.body.linux": {
"message": "Aplikace Modrinth v{version} je k dispozici. Aktualizujte ji pomocí svého správce balíčků, abyste získali nejnovější funkce a opravy!"
"message": "Modrinth App v{version} je k dispozici. Aktualizujte ji pomocí svého správce balíčků, abyste získali nejnovější funkce a opravy!"
},
"app.update-popup.body.metered": {
"message": "Aplikace Modrinth v{version} je nyní k dispozici! Protože jste v měřené síti, nebyla stažena automaticky."
"message": "Modrinth App v{version} je nyní k dispozici! Protože jste v měřené síti, nebyla stažena automaticky."
},
"app.update-popup.changelog": {
"message": "Seznam změn"
@@ -693,13 +807,13 @@
"message": "Jméno"
},
"instance.settings.tabs.general.update-channel": {
"message": "Aktualizační kanál"
"message": "Kanál aktualiza"
},
"instance.settings.tabs.general.update-channel.alpha": {
"message": "Alfa"
},
"instance.settings.tabs.general.update-channel.alpha.description": {
"message": "Vydané, beta a alfa verze se zobrazí jako dostupné aktualizace."
"message": "Verze typu release, beta a alpha se budou zobrazovat jako dostupné aktualizace."
},
"instance.settings.tabs.general.update-channel.beta": {
"message": "Beta"
@@ -839,6 +953,9 @@
"instance.worlds.copy_address": {
"message": "Kopírovat adresu"
},
"instance.worlds.create_shortcut": {
"message": "Vytvořit záložku"
},
"instance.worlds.dont_show_on_home": {
"message": "Nezobrazovat na domovské stránce"
},
@@ -164,18 +164,12 @@
"app.export-modal.header": {
"message": "Eksporter modpack"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Inkludere \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Modpack Navn"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Modpack navn"
},
"app.export-modal.select-files-label": {
"message": "Konfigurer hvilke filer inkludere i denne eksport"
},
"app.export-modal.version-number-label": {
"message": "Versionsnummer"
},
+123 -6
View File
@@ -11,6 +11,33 @@
"app.action-bar.hide-more-running-instances": {
"message": "Weitere laufende Instanzen ausblenden"
},
"app.action-bar.install.dismiss": {
"message": "Ignorieren"
},
"app.action-bar.install.failed": {
"message": "Installation fehlgeschlagen"
},
"app.action-bar.install.failed-app-closed": {
"message": "Installation aufgrund des Schließens der App fehlgeschlagen."
},
"app.action-bar.install.failed-network": {
"message": "Installation aufgrund eines Netzwerkfehlers fehlgeschlagen."
},
"app.action-bar.install.failed-unknown": {
"message": "Installation aufgrund eines unbekannten Fehlers fehlgeschlagen."
},
"app.action-bar.install.open-instance": {
"message": "Instanz öffnen"
},
"app.action-bar.install.retry": {
"message": "Wiederholen"
},
"app.action-bar.install.unknown-instance": {
"message": "Unbekannte Instanz"
},
"app.action-bar.installs": {
"message": "Installationen"
},
"app.action-bar.make-primary-instance": {
"message": "Zur primären Instanz machen"
},
@@ -101,6 +128,12 @@
"app.appearance-settings.show-play-time.title": {
"message": "Spielzeit anzeigen"
},
"app.appearance-settings.skip-non-essential-warnings.description": {
"message": "Überspringt automatisch Bestätigungen mit geringem Risiko, wie z. B. die doppelte Installation von Modpacks, das Löschen normaler Inhalte, Massenaktualisierungen, das Trennen von Modpacks und Reparaturen. Warnungen bei gefährlichen Aktionen werden weiterhin angezeigt."
},
"app.appearance-settings.skip-non-essential-warnings.title": {
"message": "Nicht essenzielle Warnungen überspringen"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Ermöglicht das Umschalten der Seitenleiste."
},
@@ -170,24 +203,72 @@
"app.export-modal.header": {
"message": "Modpack exportieren"
},
"app.export-modal.include-file-accessibility-label": {
"message": "\"{file}\" einschliessen?"
},
"app.export-modal.modpack-name-label": {
"message": "Modpaketname"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Modpaketname"
},
"app.export-modal.select-files-label": {
"message": "Konfiguriere, welche Dateien in diesem Export miteinbezogen werden"
},
"app.export-modal.version-number-label": {
"message": "Versionsnummer"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.install.phase.downloading_content": {
"message": "Lade Inhalte herunter"
},
"app.install.phase.downloading_minecraft": {
"message": "Lade Minecraft herunter"
},
"app.install.phase.downloading_pack_file": {
"message": "Lade Packdatei herunter"
},
"app.install.phase.extracting_overrides": {
"message": "Überschreibungen extrahieren"
},
"app.install.phase.finalizing": {
"message": "Abschliessen"
},
"app.install.phase.preparing_instance": {
"message": "Instanz präparieren"
},
"app.install.phase.preparing_java": {
"message": "Java präparieren"
},
"app.install.phase.preparing_java.downloading": {
"message": "Java {version} herunterladen"
},
"app.install.phase.preparing_java.extracting": {
"message": "Java {version} extrahieren"
},
"app.install.phase.preparing_java.fetching-metadata": {
"message": "Java {version} wird heruntergeladen"
},
"app.install.phase.preparing_java.resolving": {
"message": "Java {version} präparieren"
},
"app.install.phase.preparing_java.validating": {
"message": "Java {version} validieren"
},
"app.install.phase.reading_pack_manifest": {
"message": "Paketmanifest wird gelesen"
},
"app.install.phase.resolving_loader": {
"message": "Loader wird ermittelt"
},
"app.install.phase.resolving_minecraft": {
"message": "Minecraft wird ermittelt"
},
"app.install.phase.resolving_pack": {
"message": "Inhalte werden ermittelt"
},
"app.install.phase.rolling_back": {
"message": "Wird rückgängig gemacht"
},
"app.install.phase.running_loader_processors": {
"message": "Loader-Prozesse werden ausgeführt"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Alle Daten deiner Instanz werden permanent gelöscht, inlusive deiner Welten, Konfigurationen und allen installierten Inhalten."
},
@@ -212,6 +293,15 @@
"app.instance.modpack-already-installed.instance": {
"message": "Instanz"
},
"app.instance.mods.bulk-update.downloading-projects": {
"message": "Lade {current, number}/{total, number} Projekte..."
},
"app.instance.mods.bulk-update.finishing": {
"message": "Update abschliessen..."
},
"app.instance.mods.bulk-update.resolving-versions": {
"message": "Versionen werden ermittelt..."
},
"app.instance.mods.content-type-project": {
"message": "Projekt"
},
@@ -236,6 +326,18 @@
"app.instance.worlds.browse-servers": {
"message": "Server durchsuchen"
},
"app.instance.worlds.delete-world-modal.delete-button": {
"message": "Welt löschen"
},
"app.instance.worlds.delete-world-modal.title": {
"message": "Welt löschen"
},
"app.instance.worlds.delete-world-modal.warning-body": {
"message": "Diese Welt wird permanent gelöscht von dieser Instanz, dies kann nicht rückgängig gemacht werden."
},
"app.instance.worlds.delete-world-modal.warning-header": {
"message": "Lösche {name}"
},
"app.instance.worlds.filter-modded": {
"message": "Modifiziert"
},
@@ -254,6 +356,18 @@
"app.instance.worlds.no-worlds-heading": {
"message": "Keine Server oder Welten hinzugefügt"
},
"app.instance.worlds.remove-server-modal.remove-button": {
"message": "Server entfernen"
},
"app.instance.worlds.remove-server-modal.title": {
"message": "Server entfernen"
},
"app.instance.worlds.remove-server-modal.warning-body": {
"message": "Dieser Server wird aus deiner Serverliste und aus der Serverliste im Spiel entfernt. Du kannst ihn später wieder hinzufügen, wenn du die Adresse kennst."
},
"app.instance.worlds.remove-server-modal.warning-header": {
"message": "Entferne {name}"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Durchsuche {count} Welten..."
},
@@ -839,6 +953,9 @@
"instance.worlds.copy_address": {
"message": "Adresse kopieren"
},
"instance.worlds.create_shortcut": {
"message": "Shortcut erstellen"
},
"instance.worlds.dont_show_on_home": {
"message": "Nicht auf Startseite anzeigen"
},
+123 -6
View File
@@ -11,6 +11,33 @@
"app.action-bar.hide-more-running-instances": {
"message": "Weitere laufende Instanzen ausblenden"
},
"app.action-bar.install.dismiss": {
"message": "Ausblenden"
},
"app.action-bar.install.failed": {
"message": "Installation fehlgeschlagen"
},
"app.action-bar.install.failed-app-closed": {
"message": "Installation aufgrund des Schließens der App fehlgeschlagen."
},
"app.action-bar.install.failed-network": {
"message": "Installation aufgrund eines Netzwerkfehlers fehlgeschlagen."
},
"app.action-bar.install.failed-unknown": {
"message": "Installation aufgrund eines unbekannten Fehlers fehlgeschlagen."
},
"app.action-bar.install.open-instance": {
"message": "Instanz öffnen"
},
"app.action-bar.install.retry": {
"message": "Erneut versuchen"
},
"app.action-bar.install.unknown-instance": {
"message": "Unbekannte Instanz"
},
"app.action-bar.installs": {
"message": "Installationen"
},
"app.action-bar.make-primary-instance": {
"message": "Zur primären Instanz machen"
},
@@ -101,6 +128,12 @@
"app.appearance-settings.show-play-time.title": {
"message": "Spielzeit anzeigen"
},
"app.appearance-settings.skip-non-essential-warnings.description": {
"message": "Überspringt automatisch Bestätigungen mit geringem Risiko, wie z. B. die doppelte Installation von Modpacks, das Löschen normaler Inhalte, Massenaktualisierungen, das Trennen von Modpacks und Reparaturen. Warnungen bei gefährlichen Aktionen werden weiterhin angezeigt."
},
"app.appearance-settings.skip-non-essential-warnings.title": {
"message": "Unwichtige Warnungen überspringen"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Ermöglicht das Umschalten der Seitenleiste."
},
@@ -170,24 +203,72 @@
"app.export-modal.header": {
"message": "Modpack exportieren"
},
"app.export-modal.include-file-accessibility-label": {
"message": "\"{file}\" einschließen?"
},
"app.export-modal.modpack-name-label": {
"message": "Modpackname"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Modpackname"
},
"app.export-modal.select-files-label": {
"message": "Konfiguriere, welche Dateien in diesen Export enthalten sind"
},
"app.export-modal.version-number-label": {
"message": "Versionsnummer"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.install.phase.downloading_content": {
"message": "Inhalte werden heruntergeladen"
},
"app.install.phase.downloading_minecraft": {
"message": "Minecraft wird heruntergeladen"
},
"app.install.phase.downloading_pack_file": {
"message": "Paketdatei wird herunterladen"
},
"app.install.phase.extracting_overrides": {
"message": "Überschreibungen werden extrahiert"
},
"app.install.phase.finalizing": {
"message": "Wird finalisiert"
},
"app.install.phase.preparing_instance": {
"message": "Instanz wird vorbereitet"
},
"app.install.phase.preparing_java": {
"message": "Java wird vorbereitet"
},
"app.install.phase.preparing_java.downloading": {
"message": "Java {version} wird heruntergeladen"
},
"app.install.phase.preparing_java.extracting": {
"message": "Java {version} wird extrahiert"
},
"app.install.phase.preparing_java.fetching-metadata": {
"message": "Java {version} wird heruntergeladen"
},
"app.install.phase.preparing_java.resolving": {
"message": "Java {version} wird vorbereitet"
},
"app.install.phase.preparing_java.validating": {
"message": "Java {version} wird validiert"
},
"app.install.phase.reading_pack_manifest": {
"message": "Paketmanifest wird gelesen"
},
"app.install.phase.resolving_loader": {
"message": "Loader wird ermittelt"
},
"app.install.phase.resolving_minecraft": {
"message": "Minecraft wird ermittelt"
},
"app.install.phase.resolving_pack": {
"message": "Inhalte werden ermittelt"
},
"app.install.phase.rolling_back": {
"message": "Wird rückgängig gemacht"
},
"app.install.phase.running_loader_processors": {
"message": "Loader-Prozesse werden ausgeführt"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Alle Daten deiner Instanz werden permanent gelöscht, einschließlich deiner Welten, Konfigurationen und allen installierten Inhalten."
},
@@ -212,6 +293,15 @@
"app.instance.modpack-already-installed.instance": {
"message": "Instanz"
},
"app.instance.mods.bulk-update.downloading-projects": {
"message": "{current, number}/{total, number} Projekte werden heruntergelanden..."
},
"app.instance.mods.bulk-update.finishing": {
"message": "Update wird fertiggestellt..."
},
"app.instance.mods.bulk-update.resolving-versions": {
"message": "Versionen werden ermittelt..."
},
"app.instance.mods.content-type-project": {
"message": "Projekt"
},
@@ -236,6 +326,18 @@
"app.instance.worlds.browse-servers": {
"message": "Server durchsuchen"
},
"app.instance.worlds.delete-world-modal.delete-button": {
"message": "Welt löschen"
},
"app.instance.worlds.delete-world-modal.title": {
"message": "Welt löschen"
},
"app.instance.worlds.delete-world-modal.warning-body": {
"message": "Die Welt wird permanent von der Instanz gelöscht. Diese Aktion kann nicht rückgängig gemacht werden."
},
"app.instance.worlds.delete-world-modal.warning-header": {
"message": "{name} wird gelöscht"
},
"app.instance.worlds.filter-modded": {
"message": "Modifiziert"
},
@@ -254,6 +356,18 @@
"app.instance.worlds.no-worlds-heading": {
"message": "Keine Server oder Welten hinzugefügt"
},
"app.instance.worlds.remove-server-modal.remove-button": {
"message": "Server entfernen"
},
"app.instance.worlds.remove-server-modal.title": {
"message": "Server entfernen"
},
"app.instance.worlds.remove-server-modal.warning-body": {
"message": "Dieser Server wird aus deiner Serverliste und aus der Serverliste im Spiel entfernt. Du kannst ihn später wieder hinzufügen, wenn du die Adresse kennst."
},
"app.instance.worlds.remove-server-modal.warning-header": {
"message": "{name} wird entfernt"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Durchsuche {count} Welten..."
},
@@ -839,6 +953,9 @@
"instance.worlds.copy_address": {
"message": "Adresse kopieren"
},
"instance.worlds.create_shortcut": {
"message": "Verknüpfung erstellen"
},
"instance.worlds.dont_show_on_home": {
"message": "Nicht auf der Startseite anzeigen"
},
+20 -8
View File
@@ -180,7 +180,7 @@
"message": "Discover servers"
},
"app.browse.hide-added-servers": {
"message": "Hide already added servers"
"message": "Hide servers already added"
},
"app.browse.project-type.modpacks": {
"message": "Modpacks"
@@ -203,18 +203,12 @@
"app.export-modal.header": {
"message": "Export modpack"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Include \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Modpack Name"
"message": "Modpack name"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Modpack name"
},
"app.export-modal.select-files-label": {
"message": "Configure which files are included in this export"
},
"app.export-modal.version-number-label": {
"message": "Version number"
},
@@ -416,12 +410,27 @@
"app.project.install-button.already-installed": {
"message": "This project is already installed"
},
"app.project.install-button.switch-version": {
"message": "Switch version"
},
"app.project.install-context.back-to-browse": {
"message": "Back to discover"
},
"app.project.install-context.install-content-to-instance": {
"message": "Install content to instance"
},
"app.project.version.all-versions": {
"message": "All versions"
},
"app.project.version.download-in-browser": {
"message": "Download in browser"
},
"app.project.version.installing": {
"message": "Installing"
},
"app.project.versions.already-installed": {
"message": "Already installed"
},
"app.settings.developer-mode-enabled": {
"message": "Developer mode enabled."
},
@@ -542,6 +551,9 @@
"app.skins.section.builders-and-biomes": {
"message": "Builders & Biomes"
},
"app.skins.section.chaos-cubed": {
"message": "Chaos Cubed"
},
"app.skins.section.chase-the-skies": {
"message": "Chase the Skies"
},
+123 -6
View File
@@ -11,6 +11,33 @@
"app.action-bar.hide-more-running-instances": {
"message": "Ocultar más instancias en ejecución"
},
"app.action-bar.install.dismiss": {
"message": "Descartar"
},
"app.action-bar.install.failed": {
"message": "La instalación falló"
},
"app.action-bar.install.failed-app-closed": {
"message": "La instalación falló porque la aplicación se cerró."
},
"app.action-bar.install.failed-network": {
"message": "La instalación falló debido a un error de red."
},
"app.action-bar.install.failed-unknown": {
"message": "La instalación falló debido a un error desconocido."
},
"app.action-bar.install.open-instance": {
"message": "Abrir instancia"
},
"app.action-bar.install.retry": {
"message": "Reintentar"
},
"app.action-bar.install.unknown-instance": {
"message": "Instancia desconocida"
},
"app.action-bar.installs": {
"message": "Instalaciones"
},
"app.action-bar.make-primary-instance": {
"message": "Hacer instancia principal"
},
@@ -101,6 +128,12 @@
"app.appearance-settings.show-play-time.title": {
"message": "Mostrar tiempo de juego"
},
"app.appearance-settings.skip-non-essential-warnings.description": {
"message": "Omite automáticamente las confirmaciones de bajo riesgo, como las instalaciones duplicadas de paquetes de mods, la eliminación de contenido normal, las actualizaciones masivas, la desvinculación de paquetes de mods y las solicitudes de reparación. Las advertencias peligrosas seguirán mostrándose."
},
"app.appearance-settings.skip-non-essential-warnings.title": {
"message": "Omitir advertencias que no sean esenciales"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Permite mostrar u ocultar la barra lateral."
},
@@ -170,24 +203,72 @@
"app.export-modal.header": {
"message": "Exportar modpack"
},
"app.export-modal.include-file-accessibility-label": {
"message": "¿Incluir \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Nombre del modpack"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Nombre del modpack"
},
"app.export-modal.select-files-label": {
"message": "Configura que archivos incluir en esta exportación"
},
"app.export-modal.version-number-label": {
"message": "Número de la versión"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.install.phase.downloading_content": {
"message": "Descargando contenido"
},
"app.install.phase.downloading_minecraft": {
"message": "Descargando Minecraft"
},
"app.install.phase.downloading_pack_file": {
"message": "Descargando el archivo del paquete"
},
"app.install.phase.extracting_overrides": {
"message": "Extracción de anulaciones"
},
"app.install.phase.finalizing": {
"message": "Finalizando"
},
"app.install.phase.preparing_instance": {
"message": "Preparando la instancia"
},
"app.install.phase.preparing_java": {
"message": "Preparando Java"
},
"app.install.phase.preparing_java.downloading": {
"message": "Descargando Java {version}"
},
"app.install.phase.preparing_java.extracting": {
"message": "Descomprimiendo Java {version}"
},
"app.install.phase.preparing_java.fetching-metadata": {
"message": "Obteniendo Java {version}"
},
"app.install.phase.preparing_java.resolving": {
"message": "Preparando Java {version}"
},
"app.install.phase.preparing_java.validating": {
"message": "Validación de Java {version}"
},
"app.install.phase.reading_pack_manifest": {
"message": "Leer el manifiesto del paquete"
},
"app.install.phase.resolving_loader": {
"message": "Resolviendo el cargador"
},
"app.install.phase.resolving_minecraft": {
"message": "Resolviendo Minecraft"
},
"app.install.phase.resolving_pack": {
"message": "Resolviendo el contenido"
},
"app.install.phase.rolling_back": {
"message": "Revertir"
},
"app.install.phase.running_loader_processors": {
"message": "Ejecutando los procesadores del cargador"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Todos los datos de tu instancia se eliminarán permanentemente, incluidos tus mundos, configuraciones y todo el contenido instalado."
},
@@ -212,6 +293,15 @@
"app.instance.modpack-already-installed.instance": {
"message": "Instancia"
},
"app.instance.mods.bulk-update.downloading-projects": {
"message": "Descargando {current, number}/{total, number} proyectos..."
},
"app.instance.mods.bulk-update.finishing": {
"message": "Finalizando la actualización..."
},
"app.instance.mods.bulk-update.resolving-versions": {
"message": "Resolviendo versiones..."
},
"app.instance.mods.content-type-project": {
"message": "proyecto"
},
@@ -236,6 +326,18 @@
"app.instance.worlds.browse-servers": {
"message": "Explorar servidores"
},
"app.instance.worlds.delete-world-modal.delete-button": {
"message": "Eliminar mundo"
},
"app.instance.worlds.delete-world-modal.title": {
"message": "Eliminar mundo"
},
"app.instance.worlds.delete-world-modal.warning-body": {
"message": "Este mundo se eliminará de forma permanente de esta instancia. Esta acción no se puede deshacer."
},
"app.instance.worlds.delete-world-modal.warning-header": {
"message": "Eliminando {name}"
},
"app.instance.worlds.filter-modded": {
"message": "Con mods"
},
@@ -254,6 +356,18 @@
"app.instance.worlds.no-worlds-heading": {
"message": "No hay servidores ni mundos añadidos"
},
"app.instance.worlds.remove-server-modal.remove-button": {
"message": "Eliminar servidor"
},
"app.instance.worlds.remove-server-modal.title": {
"message": "Eliminar servidor"
},
"app.instance.worlds.remove-server-modal.warning-body": {
"message": "Este servidor se eliminará de tu lista de servidores y de la lista de servidores del juego. Puedes volver a agregarlo más adelante si conoces la dirección."
},
"app.instance.worlds.remove-server-modal.warning-header": {
"message": "Se está eliminando {name}"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Buscar en {count} mundos..."
},
@@ -839,6 +953,9 @@
"instance.worlds.copy_address": {
"message": "Copiar dirección"
},
"instance.worlds.create_shortcut": {
"message": "Crear un acceso directo"
},
"instance.worlds.dont_show_on_home": {
"message": "No mostrar en la página de inicio"
},
+12 -6
View File
@@ -11,6 +11,18 @@
"app.action-bar.hide-more-running-instances": {
"message": "Ocultar más instancias en ejecución"
},
"app.action-bar.install.dismiss": {
"message": "Descartar"
},
"app.action-bar.install.failed": {
"message": "La instalación falló"
},
"app.action-bar.install.failed-app-closed": {
"message": "La instalación falló porque la aplicación se cerró."
},
"app.action-bar.install.failed-network": {
"message": "La instalación falló debido a un error de red."
},
"app.action-bar.make-primary-instance": {
"message": "Establecer como instancia principal"
},
@@ -170,18 +182,12 @@
"app.export-modal.header": {
"message": "Exportar modpack"
},
"app.export-modal.include-file-accessibility-label": {
"message": "¿Incluir \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Nombre del modpack"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Nombre del modpack"
},
"app.export-modal.select-files-label": {
"message": "Configura que archivos se incluirán en esta instancia"
},
"app.export-modal.version-number-label": {
"message": "Número de versión"
},
+285 -6
View File
@@ -2,12 +2,42 @@
"app.action-bar.downloading-java": {
"message": "Ladataan Java-versiota {version}"
},
"app.action-bar.downloading-update": {
"message": "Ladataan päivitystä"
},
"app.action-bar.downloads": {
"message": "Lataukset"
},
"app.action-bar.hide-more-running-instances": {
"message": "Piilota enemmän käynnissä olevia instansseja"
},
"app.action-bar.install.dismiss": {
"message": "Hylkää"
},
"app.action-bar.install.failed": {
"message": "Asennus epäonnistui"
},
"app.action-bar.install.failed-app-closed": {
"message": "Asennus epäonnistui sovelluksen sulkeutumisen vuoksi."
},
"app.action-bar.install.failed-network": {
"message": "Asennus epäonnistui verkkovirheen vuoksi."
},
"app.action-bar.install.failed-unknown": {
"message": "Asennus epäonnistui tuntemattoman virheen vuoksi."
},
"app.action-bar.install.open-instance": {
"message": "Avaa instanssi"
},
"app.action-bar.install.retry": {
"message": "Yritä uudelleen"
},
"app.action-bar.install.unknown-instance": {
"message": "Tuntematon instanssi"
},
"app.action-bar.installs": {
"message": "Asennukset"
},
"app.action-bar.make-primary-instance": {
"message": "Aseta ensisijaiseksi instanssiksi"
},
@@ -20,12 +50,18 @@
"app.action-bar.primary-instance": {
"message": "Ensisijainen instanssi"
},
"app.action-bar.reload-to-update": {
"message": "Lataa uudelleen päivittääksesi"
},
"app.action-bar.show-more-running-instances": {
"message": "Näytä enemmän käynnissä olevia instansseja"
},
"app.action-bar.stop-instance": {
"message": "Pysäytä instanssi"
},
"app.action-bar.update": {
"message": "Päivitä"
},
"app.action-bar.view-active-downloads": {
"message": "Näytä aktiiviset lataukset"
},
@@ -86,6 +122,18 @@
"app.appearance-settings.select-option": {
"message": "Valitse vaihtoehto"
},
"app.appearance-settings.show-play-time.description": {
"message": "Näyttää, kuinka paljon aikaa olet käyttänyt instanssin pelaamiseen."
},
"app.appearance-settings.show-play-time.title": {
"message": "Näyttää peliaika"
},
"app.appearance-settings.skip-non-essential-warnings.description": {
"message": "Ohittaa automaattisesti vähäriskiset vahvistukset, kuten modpackien kaksoisasennukset, tavallisen sisällön poistamisen, massapäivitykset, modpackien linkityksen poistamisen ja korjauskehotteet. Vaaralliset varoitukset näytetään silti."
},
"app.appearance-settings.skip-non-essential-warnings.title": {
"message": "Ohita ei olennaiset varoitukset"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Laittaa päälle mahdollisuuden kytkeä sivupalkkia."
},
@@ -155,24 +203,72 @@
"app.export-modal.header": {
"message": "Vie modipaketti"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Sisällytä \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Modipaketin nimi"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Modipaketin nimi"
},
"app.export-modal.select-files-label": {
"message": "Muuta mitkä tiedostot sisältyvät tähän vientiin"
},
"app.export-modal.version-number-label": {
"message": "Versio numero"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.install.phase.downloading_content": {
"message": "Ladataan sisältöä"
},
"app.install.phase.downloading_minecraft": {
"message": "Ladataan Minecraftia"
},
"app.install.phase.downloading_pack_file": {
"message": "Ladataan paketti tiedostoja"
},
"app.install.phase.extracting_overrides": {
"message": "Puretaan ohituksia"
},
"app.install.phase.finalizing": {
"message": "Viimeistellään"
},
"app.install.phase.preparing_instance": {
"message": "Valmistellaan instanssia"
},
"app.install.phase.preparing_java": {
"message": "Valmistellaan Javaa"
},
"app.install.phase.preparing_java.downloading": {
"message": "Ladataan Java {version}"
},
"app.install.phase.preparing_java.extracting": {
"message": "Puretaan Java {version}"
},
"app.install.phase.preparing_java.fetching-metadata": {
"message": "Haetaan Java {version}"
},
"app.install.phase.preparing_java.resolving": {
"message": "Valmistellaan Java {version}"
},
"app.install.phase.preparing_java.validating": {
"message": "Tarkistetaan Java {version}"
},
"app.install.phase.reading_pack_manifest": {
"message": "Luetaan paketin manifestia"
},
"app.install.phase.resolving_loader": {
"message": "Ratkaistaan lataajaa"
},
"app.install.phase.resolving_minecraft": {
"message": "Ratkaistaan Minecraftia"
},
"app.install.phase.resolving_pack": {
"message": "Ratkaistaan sisältöä"
},
"app.install.phase.rolling_back": {
"message": "Palautetaan muutoksia"
},
"app.install.phase.running_loader_processors": {
"message": "Suoritetaan lataajan käsittelijöitä"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Kaikki sinun instanssisi data poistetaan pysyvästi, sisältäen maailmasi, konfiguraatiosi ja asennetun sisällön."
},
@@ -197,6 +293,15 @@
"app.instance.modpack-already-installed.instance": {
"message": "Instanssi"
},
"app.instance.mods.bulk-update.downloading-projects": {
"message": "Ladataan {current, number}/{total, number} projekteja..."
},
"app.instance.mods.bulk-update.finishing": {
"message": "Viimeistellään päivitystä..."
},
"app.instance.mods.bulk-update.resolving-versions": {
"message": "Selvitetään versioita..."
},
"app.instance.mods.content-type-project": {
"message": "projekti"
},
@@ -221,6 +326,18 @@
"app.instance.worlds.browse-servers": {
"message": "Selaa palvelimia"
},
"app.instance.worlds.delete-world-modal.delete-button": {
"message": "Poista maailma"
},
"app.instance.worlds.delete-world-modal.title": {
"message": "Poista maailma"
},
"app.instance.worlds.delete-world-modal.warning-body": {
"message": "Tämä maailma poistetaan pysyvästi tästä instanssista. Tätä toimintoa ei voi kumota."
},
"app.instance.worlds.delete-world-modal.warning-header": {
"message": "Poistetaan {name}"
},
"app.instance.worlds.filter-modded": {
"message": "Modattu"
},
@@ -239,6 +356,18 @@
"app.instance.worlds.no-worlds-heading": {
"message": "Ei palvelimia tai maailmoja lisättynä"
},
"app.instance.worlds.remove-server-modal.remove-button": {
"message": "Poista palvelin"
},
"app.instance.worlds.remove-server-modal.title": {
"message": "Poista palvelin"
},
"app.instance.worlds.remove-server-modal.warning-body": {
"message": "Tämä palvelin poistetaan palvelinluettelostasi ja pelin sisäisestä palvelinluettelosta. Voit lisätä sen myöhemmin uudelleen, jos tiedät osoitteen."
},
"app.instance.worlds.remove-server-modal.warning-header": {
"message": "Poistetaan {name}"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Hae {count} maailmasta..."
},
@@ -311,15 +440,147 @@
"app.settings.tabs.resource-management": {
"message": "Resurssien hallinta"
},
"app.skins.add-button": {
"message": "Lisää ulkoasu"
},
"app.skins.add-button.drag-and-drop": {
"message": "Raahaa ja pudota"
},
"app.skins.apply-button": {
"message": "Käytä"
},
"app.skins.delete-button": {
"message": "Poista ulkoasu"
},
"app.skins.delete-modal.description": {
"message": "Tämä poistaa valitun skinin pysyvästi. Tätä toimintoa ei voi kumota."
},
"app.skins.delete-modal.title": {
"message": "Haluatko varmasti poistaa ulkoasun?"
},
"app.skins.dropped-file-error.text": {
"message": "Tiedoston lukeminen epäonnistui."
},
"app.skins.dropped-file-error.title": {
"message": "Virhe prosessoidessa tiedostoa"
},
"app.skins.edit-button": {
"message": "Muokkaa ulkoasua"
},
"app.skins.modal.add-skin-button": {
"message": "Lisää ulkoasu"
},
"app.skins.modal.add-title": {
"message": "Lisätään ulkoasua"
},
"app.skins.modal.arm-style-section": {
"message": "Käsien tyyli"
},
"app.skins.modal.arm-style-slim": {
"message": "Ohut"
},
"app.skins.modal.arm-style-wide": {
"message": "Paksu"
},
"app.skins.modal.cape-fallback-name": {
"message": "Viitta"
},
"app.skins.modal.cape-section": {
"message": "Viitta"
},
"app.skins.modal.edit-title": {
"message": "Muokataan ulkoasua"
},
"app.skins.modal.make-edit-first-tooltip": {
"message": "Tee muokkaus ulkoasuun ensin!"
},
"app.skins.modal.no-cape-tooltip": {
"message": "Ei viittaa"
},
"app.skins.modal.none-cape-option": {
"message": "Ei mitään"
},
"app.skins.modal.replace-texture-button": {
"message": "Korvaa tekstuuri"
},
"app.skins.modal.save-skin-button": {
"message": "Tallenna ulkoasu"
},
"app.skins.modal.saving-tooltip": {
"message": "Tallennetaan..."
},
"app.skins.modal.texture-section": {
"message": "Tekstuuri"
},
"app.skins.modal.upload-skin-first-tooltip": {
"message": "Lataa ulkoasu ensin!"
},
"app.skins.preview.edit-button": {
"message": "Muokkaa ulkoasua"
},
"app.skins.previewing-badge": {
"message": "Esikatsellaan"
},
"app.skins.rate-limit.text": {
"message": "Vaihdat ulkoasua liian usein. Mojangin palvelimet ovat estäneet uudet pyynnöt väliaikaisesti. Yritä hetken kuluttua uudelleen."
},
"app.skins.rate-limit.title": {
"message": "Hidasta vähän!"
},
"app.skins.reorder-error.text": {
"message": "Ulkoasujen järjestystä ei voitu tallentaa."
},
"app.skins.reorder-error.title": {
"message": "Skinien järjestyksen muuttaminen epäonnistui"
},
"app.skins.section.builders-and-biomes": {
"message": "Builders & Biomes"
},
"app.skins.section.chase-the-skies": {
"message": "Chase the Skies"
},
"app.skins.section.default-skins": {
"message": "Oletus ulkoasut"
},
"app.skins.section.minecon-earth-2017": {
"message": "MINECON Earth 2017"
},
"app.skins.section.modrinth": {
"message": "Modrinth"
},
"app.skins.section.modrinth-pride": {
"message": "Modrinth Pride"
},
"app.skins.section.modrinth-pride.tooltip": {
"message": "Sait nämä skinit lahjoittamalla Modrinthin Pride-keräykseen Pride-kuukauden aikana."
},
"app.skins.section.mounts-of-mayhem": {
"message": "Sekasorron ratsut"
},
"app.skins.section.saved-skins": {
"message": "Tallennetut ulkoasut"
},
"app.skins.section.striding-hero": {
"message": "Striding Hero"
},
"app.skins.section.the-copper-age": {
"message": "The Copper Age"
},
"app.skins.section.the-garden-awakens": {
"message": "The Garden Awakens"
},
"app.skins.section.tiny-takeover": {
"message": "Pienten vallankumous"
},
"app.skins.sign-in.button": {
"message": "Kirjaudu sisään"
},
"app.skins.sign-in.description": {
"message": "Kirjaudu Minecraft-tilillesi käyttääksesi Modrinth-sovelluksen ulkoasujen hallintaominaisuuksia."
},
"app.skins.sign-in.rinthbot-alt": {
"message": "Innostunut Modrinth Botti"
},
"app.skins.sign-in.title": {
"message": "Kirjaudu sisään"
},
@@ -545,15 +806,30 @@
"instance.settings.tabs.general.name": {
"message": "Nimi"
},
"instance.settings.tabs.general.update-channel": {
"message": "Päivitys kanava"
},
"instance.settings.tabs.general.update-channel.alpha": {
"message": "Alfa"
},
"instance.settings.tabs.general.update-channel.alpha.description": {
"message": "Release-, beta- ja alpha-versiot näytetään saatavilla olevina päivityksinä."
},
"instance.settings.tabs.general.update-channel.beta": {
"message": "Beta"
},
"instance.settings.tabs.general.update-channel.beta.description": {
"message": "Release- ja beta-versiot näytetään saatavilla olevina päivityksinä."
},
"instance.settings.tabs.general.update-channel.release": {
"message": "Julkaisu"
},
"instance.settings.tabs.general.update-channel.release.description": {
"message": "Vain release-versiot näytetään saatavilla olevina päivityksinä."
},
"instance.settings.tabs.general.update-channel.select": {
"message": "Valitse päivitys kanava"
},
"instance.settings.tabs.hooks": {
"message": "Aloitustoiminnot"
},
@@ -677,6 +953,9 @@
"instance.worlds.copy_address": {
"message": "Kopioi osoite"
},
"instance.worlds.create_shortcut": {
"message": "Luo pikakuvake"
},
"instance.worlds.dont_show_on_home": {
"message": "Älä näytä koti näkymässä"
},
@@ -164,18 +164,12 @@
"app.export-modal.header": {
"message": "Iluwas ang modpack"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Salihin ang \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Pangalan ng Modpack"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Pangalan ng modpack"
},
"app.export-modal.select-files-label": {
"message": "Isaayos kung anong mga file ang isasali sa pagluwas"
},
"app.export-modal.version-number-label": {
"message": "Numero ng bersiyon"
},
+123 -6
View File
@@ -11,6 +11,33 @@
"app.action-bar.hide-more-running-instances": {
"message": "Masquer plus d'instances en exécution"
},
"app.action-bar.install.dismiss": {
"message": "Rejeter"
},
"app.action-bar.install.failed": {
"message": "Échec de l'installation"
},
"app.action-bar.install.failed-app-closed": {
"message": "Échec de l'installation dû à la fermeture de l'app."
},
"app.action-bar.install.failed-network": {
"message": "Échec de l'installation dû à une erreur réseau."
},
"app.action-bar.install.failed-unknown": {
"message": "Échec de l'installation dû à une erreur inconnue."
},
"app.action-bar.install.open-instance": {
"message": "Ouvrir l'instance"
},
"app.action-bar.install.retry": {
"message": "Réessayer"
},
"app.action-bar.install.unknown-instance": {
"message": "Instance inconnue"
},
"app.action-bar.installs": {
"message": "Installations"
},
"app.action-bar.make-primary-instance": {
"message": "Définir en tante qu'instance première"
},
@@ -101,6 +128,12 @@
"app.appearance-settings.show-play-time.title": {
"message": "Afficher le temps de jeu"
},
"app.appearance-settings.skip-non-essential-warnings.description": {
"message": "Ignore automatiquement les confirmations à faible risque, comme l'installation de modpacks en double, la suppression de contenu standard, les mises à jour groupées, la dissociation des modpacks et les demandes de réparation. Les avertissements concernant les actions dangereuses continueront d'être affichés."
},
"app.appearance-settings.skip-non-essential-warnings.title": {
"message": "Cacher les alertes non essentielles"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Permet d'ouvrir ou de fermer la barre latérale."
},
@@ -170,24 +203,72 @@
"app.export-modal.header": {
"message": "Exporter le modpack"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Inclure « {file} » ?"
},
"app.export-modal.modpack-name-label": {
"message": "Nom du modpack"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Nom du modpack"
},
"app.export-modal.select-files-label": {
"message": "Configurez quels fichiers sont inclus dans cette exportation"
},
"app.export-modal.version-number-label": {
"message": "Numéro de version"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.install.phase.downloading_content": {
"message": "Téléchargement du contenu"
},
"app.install.phase.downloading_minecraft": {
"message": "Téléchargement de Minecraft"
},
"app.install.phase.downloading_pack_file": {
"message": "Téléchargement du fichier de pack"
},
"app.install.phase.extracting_overrides": {
"message": "Extraction des fichiers personnalisés"
},
"app.install.phase.finalizing": {
"message": "Finalisation"
},
"app.install.phase.preparing_instance": {
"message": "Préparation de l'instance"
},
"app.install.phase.preparing_java": {
"message": "Préparation de Java"
},
"app.install.phase.preparing_java.downloading": {
"message": "Téléchargement de Java {version}"
},
"app.install.phase.preparing_java.extracting": {
"message": "Extraction de Java {version}"
},
"app.install.phase.preparing_java.fetching-metadata": {
"message": "Récupération de Java {version}"
},
"app.install.phase.preparing_java.resolving": {
"message": "Préparation de Java {version}"
},
"app.install.phase.preparing_java.validating": {
"message": "Validation de Java {version}"
},
"app.install.phase.reading_pack_manifest": {
"message": "Lecture du manifeste du pack"
},
"app.install.phase.resolving_loader": {
"message": "Résolution du loader"
},
"app.install.phase.resolving_minecraft": {
"message": "Résolution de Minecraft"
},
"app.install.phase.resolving_pack": {
"message": "Résolution du contenu"
},
"app.install.phase.rolling_back": {
"message": "Annulation"
},
"app.install.phase.running_loader_processors": {
"message": "Exécution des processeurs du chargeur"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Toutes les données pour votre instance seront supprimées à jamais, y compris vos mondes, vos configurations, et le contenu installé."
},
@@ -212,6 +293,15 @@
"app.instance.modpack-already-installed.instance": {
"message": "Instance"
},
"app.instance.mods.bulk-update.downloading-projects": {
"message": "Téléchargement de {current, number}/{total, number} projets..."
},
"app.instance.mods.bulk-update.finishing": {
"message": "Finalisation de la mise à jour..."
},
"app.instance.mods.bulk-update.resolving-versions": {
"message": "Résolution des versions..."
},
"app.instance.mods.content-type-project": {
"message": "projet"
},
@@ -236,6 +326,18 @@
"app.instance.worlds.browse-servers": {
"message": "Parcourir des serveurs"
},
"app.instance.worlds.delete-world-modal.delete-button": {
"message": "Supprimer le monde"
},
"app.instance.worlds.delete-world-modal.title": {
"message": "Supprimer le monde"
},
"app.instance.worlds.delete-world-modal.warning-body": {
"message": "Ce monde sera définitivement supprimé de cette instance. Cette action est irréversible."
},
"app.instance.worlds.delete-world-modal.warning-header": {
"message": "Suppression de {name}"
},
"app.instance.worlds.filter-modded": {
"message": "Moddé"
},
@@ -254,6 +356,18 @@
"app.instance.worlds.no-worlds-heading": {
"message": "Aucun serveur ou monde ajoutés"
},
"app.instance.worlds.remove-server-modal.remove-button": {
"message": "Enlever le serveur"
},
"app.instance.worlds.remove-server-modal.title": {
"message": "Enlever le serveur"
},
"app.instance.worlds.remove-server-modal.warning-body": {
"message": "Ce serveur sera enlevé de votre liste de serveur et de la liste de serveur en jeu. Vous pourrez le rajouter plus tard si vous connaissez son adresse."
},
"app.instance.worlds.remove-server-modal.warning-header": {
"message": "Retrait de {name}"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Rechercher {count} mondes..."
},
@@ -836,6 +950,9 @@
"instance.worlds.copy_address": {
"message": "Copier l'adresse"
},
"instance.worlds.create_shortcut": {
"message": "Créer un raccourci"
},
"instance.worlds.dont_show_on_home": {
"message": "Ne pas montrer dans l'Accueil"
},
@@ -11,6 +11,12 @@
"app.action-bar.hide-more-running-instances": {
"message": "További futó példányok elrejtése"
},
"app.action-bar.install.retry": {
"message": "Újra"
},
"app.action-bar.install.unknown-instance": {
"message": "Ismeretlen profil"
},
"app.action-bar.make-primary-instance": {
"message": "Beállítás elsődleges példányként"
},
@@ -170,24 +176,21 @@
"app.export-modal.header": {
"message": "Modcsomag exportálása"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Tartalmaz „{file}” fájlokat?"
},
"app.export-modal.modpack-name-label": {
"message": "A modcsomag neve"
},
"app.export-modal.modpack-name-placeholder": {
"message": "A modcsomag neve"
},
"app.export-modal.select-files-label": {
"message": "Állítsd be, hogy mely fájlok kerüljenek bele az exportba"
},
"app.export-modal.version-number-label": {
"message": "Verziószám"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.install.phase.resolving_loader": {
"message": ""
},
"app.instance.confirm-delete.admonition-body": {
"message": "Az profilodhoz tartozó összes adat véglegesen törlődik, beleértve a világokat, a beállításokat és az összes telepített tartalmat."
},
@@ -170,18 +170,12 @@
"app.export-modal.header": {
"message": "Ekspor paket mod"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Sertakan \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Nama Paket Mod"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Nama paket mod"
},
"app.export-modal.select-files-label": {
"message": "Konfigurasikan berkas mana yang disertakan dalam pengeksporan ini"
},
"app.export-modal.version-number-label": {
"message": "Nomor versi"
},
+123 -6
View File
@@ -11,6 +11,33 @@
"app.action-bar.hide-more-running-instances": {
"message": "Mostra meno istanze in esecuzione"
},
"app.action-bar.install.dismiss": {
"message": "Ignora"
},
"app.action-bar.install.failed": {
"message": "Installazione fallita"
},
"app.action-bar.install.failed-app-closed": {
"message": "Installazione fallita: l'app è stata chiusa."
},
"app.action-bar.install.failed-network": {
"message": "Installazione fallita: errore di rete."
},
"app.action-bar.install.failed-unknown": {
"message": "Installazione fallita: errore sconosciuto."
},
"app.action-bar.install.open-instance": {
"message": "Apri istanza"
},
"app.action-bar.install.retry": {
"message": "Riprova"
},
"app.action-bar.install.unknown-instance": {
"message": "Istanza sconosciuta"
},
"app.action-bar.installs": {
"message": "Installazioni"
},
"app.action-bar.make-primary-instance": {
"message": "Rendi primaria"
},
@@ -101,6 +128,12 @@
"app.appearance-settings.show-play-time.title": {
"message": "Mostra le ore di gioco"
},
"app.appearance-settings.skip-non-essential-warnings.description": {
"message": "Salta automaticamente le conferme a basso rischio, come l'installazione di pacchetti di mod duplicati, la normale eliminazione di contenuti, gli aggiornamenti simultanei, lo scollegare i pacchetti di mod e le richieste di riparazione. Le avvertenze verranno comunque mostrate."
},
"app.appearance-settings.skip-non-essential-warnings.title": {
"message": "Salta le conferme poco importanti"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Mostra o nascondi la barra laterale."
},
@@ -170,24 +203,72 @@
"app.export-modal.header": {
"message": "Esporta pacchetto"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Includere \"{file}\" nell'esportazione?"
},
"app.export-modal.modpack-name-label": {
"message": "Nome del pacchetto"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Nome del pacchetto"
},
"app.export-modal.select-files-label": {
"message": "Seleziona i file da includere in questa esportazione"
},
"app.export-modal.version-number-label": {
"message": "Numero di versione"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.install.phase.downloading_content": {
"message": "Download dei contenuti"
},
"app.install.phase.downloading_minecraft": {
"message": "Download di Minecraft"
},
"app.install.phase.downloading_pack_file": {
"message": "Download del pacchetto"
},
"app.install.phase.extracting_overrides": {
"message": "Estrazione degli override"
},
"app.install.phase.finalizing": {
"message": "Finalizzazione"
},
"app.install.phase.preparing_instance": {
"message": "Preparazione dell'istanza"
},
"app.install.phase.preparing_java": {
"message": "Preparazione di Java"
},
"app.install.phase.preparing_java.downloading": {
"message": "Download di Java {version}"
},
"app.install.phase.preparing_java.extracting": {
"message": "Estrazione di Java {version}"
},
"app.install.phase.preparing_java.fetching-metadata": {
"message": "Recupero di Java {version}"
},
"app.install.phase.preparing_java.resolving": {
"message": "Preparazione di Java {version}"
},
"app.install.phase.preparing_java.validating": {
"message": "Validazione di Java {version}"
},
"app.install.phase.reading_pack_manifest": {
"message": "Lettura del manifesto"
},
"app.install.phase.resolving_loader": {
"message": "Risoluzione del loader"
},
"app.install.phase.resolving_minecraft": {
"message": "Risoluzione di Minecraft"
},
"app.install.phase.resolving_pack": {
"message": "Risoluzione dei contenuti"
},
"app.install.phase.rolling_back": {
"message": "Tornando indietro"
},
"app.install.phase.running_loader_processors": {
"message": "Esecuzione dei processori del loader"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Tutti i dati della tua istanza verranno eliminati permanentemente, inclusi i tuoi mondi, configurazioni e tutti i contenuti installati."
},
@@ -212,6 +293,15 @@
"app.instance.modpack-already-installed.instance": {
"message": "Istanza"
},
"app.instance.mods.bulk-update.downloading-projects": {
"message": "{current, number}/{total, number} progetti scaricati..."
},
"app.instance.mods.bulk-update.finishing": {
"message": "Finalizzando l'aggiornamento..."
},
"app.instance.mods.bulk-update.resolving-versions": {
"message": "Risolvendo le versioni..."
},
"app.instance.mods.content-type-project": {
"message": "progetto"
},
@@ -233,6 +323,18 @@
"app.instance.worlds.browse-servers": {
"message": "Esplora i server"
},
"app.instance.worlds.delete-world-modal.delete-button": {
"message": "Elimina mondo"
},
"app.instance.worlds.delete-world-modal.title": {
"message": "Eliminare il mondo"
},
"app.instance.worlds.delete-world-modal.warning-body": {
"message": "Questo mondo verrà eliminato permanentemente da questa istanza. Questa azione non può essere annullata."
},
"app.instance.worlds.delete-world-modal.warning-header": {
"message": "Eliminare {name}"
},
"app.instance.worlds.filter-modded": {
"message": "Moddato"
},
@@ -251,6 +353,18 @@
"app.instance.worlds.no-worlds-heading": {
"message": "Nessun server o mondo aggiunto"
},
"app.instance.worlds.remove-server-modal.remove-button": {
"message": "Rimuovi server"
},
"app.instance.worlds.remove-server-modal.title": {
"message": "Rimuovere il server"
},
"app.instance.worlds.remove-server-modal.warning-body": {
"message": "Questo server verrà rimosso dalla tua lista di server nell'app e nel gioco. Potrai aggiungerlo nuovamente se conosci l'indirizzo."
},
"app.instance.worlds.remove-server-modal.warning-header": {
"message": "Rimuovere {name}"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Cerca tra {count} mondi..."
},
@@ -836,6 +950,9 @@
"instance.worlds.copy_address": {
"message": "Copia indirizzo"
},
"instance.worlds.create_shortcut": {
"message": "Crea collegamento"
},
"instance.worlds.dont_show_on_home": {
"message": "Non mostrare nella home"
},
@@ -306,7 +306,7 @@
"message": "マントなし"
},
"app.skins.modal.replace-texture-button": {
"message": "置きかえる"
"message": "アップロード"
},
"app.skins.modal.texture-section": {
"message": "テクスチャ"
@@ -164,18 +164,12 @@
"app.export-modal.header": {
"message": "모드팩 내보내기"
},
"app.export-modal.include-file-accessibility-label": {
"message": "\"{file}\"(을)를 포함할까요?"
},
"app.export-modal.modpack-name-label": {
"message": "모드팩 이름"
},
"app.export-modal.modpack-name-placeholder": {
"message": "모드팩 이름"
},
"app.export-modal.select-files-label": {
"message": "내보내기에 어느 파일이 포함될지 구성"
},
"app.export-modal.version-number-label": {
"message": "버전 구분"
},
@@ -155,18 +155,12 @@
"app.export-modal.header": {
"message": "Eksport pek mod"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Sertakan \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Nama Pek Mod"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Nama pek mod"
},
"app.export-modal.select-files-label": {
"message": "Konfigurasikan fail yang disertakan dalam eksport ini"
},
"app.export-modal.version-number-label": {
"message": "Nombor versi"
},
@@ -33,7 +33,7 @@
"message": "Stop instantie"
},
"app.action-bar.update": {
"message": "Updaten"
"message": "Bijwerken"
},
"app.action-bar.view-active-downloads": {
"message": "Bekijk actieve downloads"
@@ -60,7 +60,7 @@
"message": "Wijzig de pagina waarop de launcher opent."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Home"
"message": "Start"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Bibliotheek"
@@ -170,18 +170,12 @@
"app.export-modal.header": {
"message": "Exporteer modpack"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Betrek \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Modpack Naam"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Modpack naam"
},
"app.export-modal.select-files-label": {
"message": "Configureer welke bestanden bij deze export zijn betrokken"
},
"app.export-modal.version-number-label": {
"message": "Versie nummer"
},
+125 -8
View File
@@ -11,6 +11,33 @@
"app.action-bar.hide-more-running-instances": {
"message": "Ukryj włączone instancje"
},
"app.action-bar.install.dismiss": {
"message": "Odrzuć"
},
"app.action-bar.install.failed": {
"message": "Instalacja nie powiodła się"
},
"app.action-bar.install.failed-app-closed": {
"message": "Instalacja nie powiodła się z powodu zamknięcia aplikacji."
},
"app.action-bar.install.failed-network": {
"message": "Instalacja nie powiodła się z powodu problemów z połączeniem."
},
"app.action-bar.install.failed-unknown": {
"message": "Instalacja nie powiodła się z nieznanych przyczyn."
},
"app.action-bar.install.open-instance": {
"message": "Otwórz instancję"
},
"app.action-bar.install.retry": {
"message": "Spróbuj ponownie"
},
"app.action-bar.install.unknown-instance": {
"message": "Nieznana instancja"
},
"app.action-bar.installs": {
"message": "Instalacje"
},
"app.action-bar.make-primary-instance": {
"message": "Ustaw jako główną instancję"
},
@@ -51,7 +78,7 @@
"message": "Zaawansowane renderowanie"
},
"app.appearance-settings.color-theme.description": {
"message": "Wybierz preferowany motyw w Modrinth App."
"message": "Wybierz preferowany motyw w Modrinth app."
},
"app.appearance-settings.color-theme.title": {
"message": "Motyw"
@@ -101,6 +128,12 @@
"app.appearance-settings.show-play-time.title": {
"message": "Pokaż czas gry"
},
"app.appearance-settings.skip-non-essential-warnings.description": {
"message": "Automatycznie pomija mało znaczące potwierdzenia takie jak duplikaty instalacji paczek modów, usuwanie zwykłej zawartości, masowe aktualizacje, odłączanie paczek modów i naprawianie. Ostrzeżenia o potencjalnie niebezpiecznych akcjach będą nadal pokazywane."
},
"app.appearance-settings.skip-non-essential-warnings.title": {
"message": "Pomiń mało znaczące ostrzeżenia"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Umożliwia przełączenie paska bocznego."
},
@@ -170,24 +203,72 @@
"app.export-modal.header": {
"message": "Eksportuj paczkę modów"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Dołączyć \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Nazwa paczki modów"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Nazwa paczki modów"
},
"app.export-modal.select-files-label": {
"message": "Skonfiguruje jakie pliki zostaną załączone w tym eksporcie"
},
"app.export-modal.version-number-label": {
"message": "Numer wersji"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.install.phase.downloading_content": {
"message": "Pobieranie zawartości"
},
"app.install.phase.downloading_minecraft": {
"message": "Pobieranie Minecraft"
},
"app.install.phase.downloading_pack_file": {
"message": "Pobieranie pliku paczki"
},
"app.install.phase.extracting_overrides": {
"message": "Wyodrębnianie nadpisań"
},
"app.install.phase.finalizing": {
"message": "Finalizowanie"
},
"app.install.phase.preparing_instance": {
"message": "Przygotowywanie instancji"
},
"app.install.phase.preparing_java": {
"message": "Przygotowywanie środowiska Java"
},
"app.install.phase.preparing_java.downloading": {
"message": "Pobieranie Java {version}"
},
"app.install.phase.preparing_java.extracting": {
"message": "Wypakowywanie Javy {version}"
},
"app.install.phase.preparing_java.fetching-metadata": {
"message": "Pobieranie Javy {version}"
},
"app.install.phase.preparing_java.resolving": {
"message": "Przygotowywanie Java {version}"
},
"app.install.phase.preparing_java.validating": {
"message": "Sprawdzanie Java {version}"
},
"app.install.phase.reading_pack_manifest": {
"message": "Ustalanie manifestu paczki"
},
"app.install.phase.resolving_loader": {
"message": "Ustalanie programu ładującego"
},
"app.install.phase.resolving_minecraft": {
"message": "Ustalanie wersji Minecraft"
},
"app.install.phase.resolving_pack": {
"message": "Ustalanie treści"
},
"app.install.phase.rolling_back": {
"message": "Przywracanie"
},
"app.install.phase.running_loader_processors": {
"message": "Uruchamianie procesorów programu ładującego"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Wszystkie dane z Twojej instancji zostaną trwale usunięte, w tym Twoje światy, pliki konfiguracji i jakakolwiek dodana zawartość."
},
@@ -212,6 +293,15 @@
"app.instance.modpack-already-installed.instance": {
"message": "Instalacja"
},
"app.instance.mods.bulk-update.downloading-projects": {
"message": "Pobieranie {current, number}/{total, number} projektów..."
},
"app.instance.mods.bulk-update.finishing": {
"message": "Kończenie aktualizacji..."
},
"app.instance.mods.bulk-update.resolving-versions": {
"message": "Sprawdzanie wersji..."
},
"app.instance.mods.content-type-project": {
"message": "projekt"
},
@@ -233,6 +323,18 @@
"app.instance.worlds.browse-servers": {
"message": "Szukaj serwerów"
},
"app.instance.worlds.delete-world-modal.delete-button": {
"message": "Usuń świat"
},
"app.instance.worlds.delete-world-modal.title": {
"message": "Usuń świat"
},
"app.instance.worlds.delete-world-modal.warning-body": {
"message": "Ten świat zostanie trwale usunięty z tej instancji. Tej akcji nie będzie można cofnąć."
},
"app.instance.worlds.delete-world-modal.warning-header": {
"message": "Usuwanie {name}"
},
"app.instance.worlds.filter-modded": {
"message": "Zmodowany"
},
@@ -251,6 +353,18 @@
"app.instance.worlds.no-worlds-heading": {
"message": "Nie dodano żadnych światów ani serwerów"
},
"app.instance.worlds.remove-server-modal.remove-button": {
"message": "Usuń serwer"
},
"app.instance.worlds.remove-server-modal.title": {
"message": "Usuń serwer"
},
"app.instance.worlds.remove-server-modal.warning-body": {
"message": "Ten serwer zostanie trwale usunięty z tej instancji. Tej akcji nie będzie można cofnąć."
},
"app.instance.worlds.remove-server-modal.warning-header": {
"message": "Usuwanie {name}"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Szukaj wśród {count} światów..."
},
@@ -339,7 +453,7 @@
"message": "To trwale usunie wybraną skórkę. Tej akcji nie można odwrócić."
},
"app.skins.delete-modal.title": {
"message": "Czy na pewno chcesz usunąć tą skórkę?"
"message": "Czy na pewno chcesz usunąć tę skórkę?"
},
"app.skins.dropped-file-error.text": {
"message": "Nie udało się odczytać wybranego pliku."
@@ -836,6 +950,9 @@
"instance.worlds.copy_address": {
"message": "Kopiuj adres"
},
"instance.worlds.create_shortcut": {
"message": "Utwórz skrót"
},
"instance.worlds.dont_show_on_home": {
"message": "Nie pokazuj na stronie głównej"
},
+123 -6
View File
@@ -11,6 +11,33 @@
"app.action-bar.hide-more-running-instances": {
"message": "Ocultar mais instâncias em execução"
},
"app.action-bar.install.dismiss": {
"message": "Dispensar"
},
"app.action-bar.install.failed": {
"message": "Instalação falha"
},
"app.action-bar.install.failed-app-closed": {
"message": "A instalação falhou devido ao aplicativo ter fechado."
},
"app.action-bar.install.failed-network": {
"message": "A instalação falhou devido a um erro na rede."
},
"app.action-bar.install.failed-unknown": {
"message": "A instalação falhou devido a um erro desconhecido."
},
"app.action-bar.install.open-instance": {
"message": "Abrir instância"
},
"app.action-bar.install.retry": {
"message": "Tentar novamente"
},
"app.action-bar.install.unknown-instance": {
"message": "Instância desconhecida"
},
"app.action-bar.installs": {
"message": "Instalações"
},
"app.action-bar.make-primary-instance": {
"message": "Tornar instância principal"
},
@@ -101,6 +128,12 @@
"app.appearance-settings.show-play-time.title": {
"message": "Exibir tempo jogado"
},
"app.appearance-settings.skip-non-essential-warnings.description": {
"message": "Pula automaticamente as confirmações desnecessárias como duplica de instalação de pacotes de mods, exclusão de conteúdo normal, atualizações em massa, desvinculo de pacotes de mods e diálogos de reparo. Os avisos de perigo ainda serão exibidos."
},
"app.appearance-settings.skip-non-essential-warnings.title": {
"message": "Pular avisos desnecessários"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Permite alternar a barra lateral."
},
@@ -170,24 +203,72 @@
"app.export-modal.header": {
"message": "Exportar pacote de mods"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Incluir \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Nome do pacote de mods"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Nome do pacote de mods"
},
"app.export-modal.select-files-label": {
"message": "Configure quais arquivos serão incluídos na exportação"
},
"app.export-modal.version-number-label": {
"message": "Número da versão"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.install.phase.downloading_content": {
"message": "Instalando conteúdo"
},
"app.install.phase.downloading_minecraft": {
"message": "Instalando Minecraft"
},
"app.install.phase.downloading_pack_file": {
"message": "Instalando arquivo de pacote"
},
"app.install.phase.extracting_overrides": {
"message": "Extraindo substitutos"
},
"app.install.phase.finalizing": {
"message": "Finalizando"
},
"app.install.phase.preparing_instance": {
"message": "Preparando instância"
},
"app.install.phase.preparing_java": {
"message": "Preparando Java"
},
"app.install.phase.preparing_java.downloading": {
"message": "Baixando Java {version}"
},
"app.install.phase.preparing_java.extracting": {
"message": "Extraindo Java {version}"
},
"app.install.phase.preparing_java.fetching-metadata": {
"message": "Obtendo Java {version}"
},
"app.install.phase.preparing_java.resolving": {
"message": "Preparando Java {version}"
},
"app.install.phase.preparing_java.validating": {
"message": "Validando Java {version}"
},
"app.install.phase.reading_pack_manifest": {
"message": "Lendo manifestação de pacote"
},
"app.install.phase.resolving_loader": {
"message": "Resolvendo loader"
},
"app.install.phase.resolving_minecraft": {
"message": "Resolvendo Minecraft"
},
"app.install.phase.resolving_pack": {
"message": "Resolvendo conteúdo"
},
"app.install.phase.rolling_back": {
"message": "Indo de volta"
},
"app.install.phase.running_loader_processors": {
"message": "Executando processadores de loader"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Todos os dados para sua instância serão excluídos permanentemente, incluindo seus mundos, configs e todo o conteúdo instalado."
},
@@ -212,6 +293,15 @@
"app.instance.modpack-already-installed.instance": {
"message": "Instância"
},
"app.instance.mods.bulk-update.downloading-projects": {
"message": "Instalando {current, number}/{total, number} projeto(s)..."
},
"app.instance.mods.bulk-update.finishing": {
"message": "Finalizando atualização..."
},
"app.instance.mods.bulk-update.resolving-versions": {
"message": "Resolvendo versões..."
},
"app.instance.mods.content-type-project": {
"message": "projeto"
},
@@ -236,6 +326,18 @@
"app.instance.worlds.browse-servers": {
"message": "Explorar servidores"
},
"app.instance.worlds.delete-world-modal.delete-button": {
"message": "Excluir mundo"
},
"app.instance.worlds.delete-world-modal.title": {
"message": "Excluir mundo"
},
"app.instance.worlds.delete-world-modal.warning-body": {
"message": "Este mundo será permanentemente excluído desta instância. Esta ação não pode ser desfeita."
},
"app.instance.worlds.delete-world-modal.warning-header": {
"message": "Excluindo {name}"
},
"app.instance.worlds.filter-modded": {
"message": "Modificado"
},
@@ -254,6 +356,18 @@
"app.instance.worlds.no-worlds-heading": {
"message": "Nenhum servidor ou mundo adicionado"
},
"app.instance.worlds.remove-server-modal.remove-button": {
"message": "Remover servidor"
},
"app.instance.worlds.remove-server-modal.title": {
"message": "Remover servidor"
},
"app.instance.worlds.remove-server-modal.warning-body": {
"message": "O servidor será removido da lista de servidores e da lista de servidores no jogo. Você pode re-adicioná-lo depois se souber o endereço."
},
"app.instance.worlds.remove-server-modal.warning-header": {
"message": "Removendo {name}"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Buscar {count} mundos..."
},
@@ -839,6 +953,9 @@
"instance.worlds.copy_address": {
"message": "Copiar endereço"
},
"instance.worlds.create_shortcut": {
"message": "Criar atalho"
},
"instance.worlds.dont_show_on_home": {
"message": "Não exibir na página inicial"
},
+120 -6
View File
@@ -11,6 +11,33 @@
"app.action-bar.hide-more-running-instances": {
"message": "Скрыть другие активные сборки"
},
"app.action-bar.install.dismiss": {
"message": "Закрыть"
},
"app.action-bar.install.failed": {
"message": "Установка не удалась"
},
"app.action-bar.install.failed-app-closed": {
"message": "Установка не удалась из-за закрытия приложения."
},
"app.action-bar.install.failed-network": {
"message": "Установка не удалась из-за сетевой ошибки."
},
"app.action-bar.install.failed-unknown": {
"message": "Установка не удалась из-за неизвестной ошибки."
},
"app.action-bar.install.open-instance": {
"message": "Открыть сборку"
},
"app.action-bar.install.retry": {
"message": "Повторить"
},
"app.action-bar.install.unknown-instance": {
"message": "Неизвестная сборка"
},
"app.action-bar.installs": {
"message": "Установки"
},
"app.action-bar.make-primary-instance": {
"message": "Сделать основной сборкой"
},
@@ -101,6 +128,12 @@
"app.appearance-settings.show-play-time.title": {
"message": "Время игры"
},
"app.appearance-settings.skip-non-essential-warnings.description": {
"message": "Автоматически пропускает подтверждения с низким уровнем риска, такие как установка дубликатов сборок, обычное удаление контента, массовые обновления, отключение сборок и запросы на восстановление. Опасные предупреждения по-прежнему будут отображаться."
},
"app.appearance-settings.skip-non-essential-warnings.title": {
"message": "Пропустить несущественные предупреждения"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Показывать кнопку скрытия боковой панели."
},
@@ -170,24 +203,69 @@
"app.export-modal.header": {
"message": "Экспорт сборки"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Добавить «{file}» в экспорт?"
},
"app.export-modal.modpack-name-label": {
"message": "Название сборки"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Название сборки"
},
"app.export-modal.select-files-label": {
"message": "Выберите файлы для экспорта"
},
"app.export-modal.version-number-label": {
"message": "Номер версии"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.install.phase.downloading_content": {
"message": "Скачивание контента"
},
"app.install.phase.downloading_minecraft": {
"message": "Скачивание Minecraft"
},
"app.install.phase.downloading_pack_file": {
"message": "Скачивание файла сборки"
},
"app.install.phase.extracting_overrides": {
"message": "Извлечение переопределений"
},
"app.install.phase.finalizing": {
"message": "Завершение"
},
"app.install.phase.preparing_instance": {
"message": "Подготовка сборки"
},
"app.install.phase.preparing_java": {
"message": "Подготовка Java"
},
"app.install.phase.preparing_java.downloading": {
"message": "Скачивание Java {version}"
},
"app.install.phase.preparing_java.extracting": {
"message": "Распаковка Java {version}"
},
"app.install.phase.preparing_java.fetching-metadata": {
"message": "Получение Java {version}"
},
"app.install.phase.preparing_java.resolving": {
"message": "Подготовка Java {version}"
},
"app.install.phase.preparing_java.validating": {
"message": "Проверка Java {version}"
},
"app.install.phase.reading_pack_manifest": {
"message": "Чтение манифеста сборки"
},
"app.install.phase.resolving_minecraft": {
"message": "Загрузка версий"
},
"app.install.phase.resolving_pack": {
"message": "Загрузка контента"
},
"app.install.phase.rolling_back": {
"message": "Откат"
},
"app.install.phase.running_loader_processors": {
"message": "Запуск процессоров загрузчика"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Все данные сборки будут удалены навсегда, в том числе миры, настройки и весь установленный контент."
},
@@ -212,6 +290,15 @@
"app.instance.modpack-already-installed.instance": {
"message": "Сборка"
},
"app.instance.mods.bulk-update.downloading-projects": {
"message": "Скачивание {current, number}/{total, number} проектов..."
},
"app.instance.mods.bulk-update.finishing": {
"message": "Завершение обновления..."
},
"app.instance.mods.bulk-update.resolving-versions": {
"message": "Загрузка версий..."
},
"app.instance.mods.content-type-project": {
"message": "проект"
},
@@ -233,6 +320,18 @@
"app.instance.worlds.browse-servers": {
"message": "Найти серверы"
},
"app.instance.worlds.delete-world-modal.delete-button": {
"message": "Удалить"
},
"app.instance.worlds.delete-world-modal.title": {
"message": "Удаление мира"
},
"app.instance.worlds.delete-world-modal.warning-body": {
"message": "Этот мир будет удалён навсегда из этой сборки. Отменить это действие нельзя."
},
"app.instance.worlds.delete-world-modal.warning-header": {
"message": "Удаление {name}"
},
"app.instance.worlds.filter-modded": {
"message": "Модовые"
},
@@ -251,6 +350,18 @@
"app.instance.worlds.no-worlds-heading": {
"message": "Нет серверов и миров"
},
"app.instance.worlds.remove-server-modal.remove-button": {
"message": "Удалить"
},
"app.instance.worlds.remove-server-modal.title": {
"message": "Удаление сервера"
},
"app.instance.worlds.remove-server-modal.warning-body": {
"message": "Этот сервер будет удалён из списка серверов, в том числе и в игре. Его можно вернуть, зная адрес."
},
"app.instance.worlds.remove-server-modal.warning-header": {
"message": "Удаление {name}"
},
"app.modal.install-to-play.content-required": {
"message": "Требуется дополнительный контент"
},
@@ -830,6 +941,9 @@
"instance.worlds.copy_address": {
"message": "Копировать адрес"
},
"instance.worlds.create_shortcut": {
"message": "Создать ярлык"
},
"instance.worlds.dont_show_on_home": {
"message": "Не показывать на главной"
},
+10 -1
View File
@@ -1,4 +1,10 @@
{
"app.action-bar.install.failed": {
"message": "Neuspešna instalacija"
},
"app.action-bar.install.failed-app-closed": {
"message": "Neuspešna instalacija zbog zatvaranja aplikacije."
},
"app.auth-servers.unreachable.body": {
"message": "Minecraft serveri za autentifikaciju su možda trenutno nedostupni. Molimo vas da proverite vašu internet vezu i pokušajte ponovo kasnije."
},
@@ -156,11 +162,14 @@
"message": "Minecraft svet"
},
"instance.edit-world.title": {
"message": "Izmeni svet"
"message": "Promeni svet"
},
"instance.server-modal.placeholder-name": {
"message": "Minecraft Server"
},
"instance.settings.tabs.general": {
"message": "Generalno"
},
"instance.settings.tabs.general.deleting.button": {
"message": "Brisanje..."
},
+133 -7
View File
@@ -11,6 +11,33 @@
"app.action-bar.hide-more-running-instances": {
"message": "Göm fler aktiva instanser"
},
"app.action-bar.install.dismiss": {
"message": "Avvisa"
},
"app.action-bar.install.failed": {
"message": "Installationen misslyckades"
},
"app.action-bar.install.failed-app-closed": {
"message": "Installationen misslyckades för att appen stängdes."
},
"app.action-bar.install.failed-network": {
"message": "Installationen misslyckades av ett nätverksfel."
},
"app.action-bar.install.failed-unknown": {
"message": "Installationen misslyckades med ett okänt fel."
},
"app.action-bar.install.open-instance": {
"message": "Öppna instans"
},
"app.action-bar.install.retry": {
"message": "Försök igen"
},
"app.action-bar.install.unknown-instance": {
"message": "Okänd instans"
},
"app.action-bar.installs": {
"message": "Installationer"
},
"app.action-bar.make-primary-instance": {
"message": "Gör till primärinstans"
},
@@ -24,7 +51,7 @@
"message": "Primärinstans"
},
"app.action-bar.reload-to-update": {
"message": "Ladda om för att uppdatera"
"message": "Uppdatera (ladda om)"
},
"app.action-bar.show-more-running-instances": {
"message": "Visa fler aktiva instanser"
@@ -74,9 +101,15 @@
"app.appearance-settings.hide-nametag.title": {
"message": "Dölj namnskylt"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Inkluderar de senaste världarna i \"Hoppa tillbaka i världar\" på hemsidan."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Hoppa tillbaka i världar"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Minimerar launchern när Minecraft startas."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Minimera programstartare"
},
@@ -95,6 +128,12 @@
"app.appearance-settings.show-play-time.title": {
"message": "Visa speltid"
},
"app.appearance-settings.skip-non-essential-warnings.description": {
"message": "Hoppar över bekräftelser med låg risk, såsom installation av dubbla modpaket, radering av vanligt innehåll, massuppdateringar, avlänkning av modpaket och reparationsmeddelanden. Varningar om farliga händelser visas fortfarande."
},
"app.appearance-settings.skip-non-essential-warnings.title": {
"message": "Hoppa över icke nödvändiga varningar"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Låter dig växla sidofältet."
},
@@ -146,6 +185,9 @@
"app.browse.project-type.modpacks": {
"message": "Modpaket"
},
"app.browse.server-instance-content-warning": {
"message": "Att lägga till innehåll kan bryta kompatibiliteten när du ansluter dig till servern. Allt tillagt innehåll kommer att förloras när du uppdaterar serverinstansen."
},
"app.browse.server.installing": {
"message": "Installerar"
},
@@ -161,24 +203,66 @@
"app.export-modal.header": {
"message": "Exportera modpaket"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Inkludera \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Modpaketets namn"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Modpaketets namn"
},
"app.export-modal.select-files-label": {
"message": "Konfigurera vilka filer som inkluderas i denna export"
},
"app.export-modal.version-number-label": {
"message": "Versionsnummer"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.install.phase.downloading_content": {
"message": "Laddar ner innehåll"
},
"app.install.phase.downloading_minecraft": {
"message": "Laddar ner Minecraft"
},
"app.install.phase.downloading_pack_file": {
"message": "Laddar ner pack fil"
},
"app.install.phase.extracting_overrides": {
"message": "Extraherar överskrivningar"
},
"app.install.phase.finalizing": {
"message": "Avslutar"
},
"app.install.phase.preparing_instance": {
"message": "Förbereder instans"
},
"app.install.phase.preparing_java": {
"message": "Förbereder Java"
},
"app.install.phase.preparing_java.downloading": {
"message": "Laddar ner Java {version}"
},
"app.install.phase.preparing_java.extracting": {
"message": "Extraherar Java {version}"
},
"app.install.phase.preparing_java.fetching-metadata": {
"message": "Hämtar Java {version}"
},
"app.install.phase.preparing_java.resolving": {
"message": "Förbereder Java {version}"
},
"app.install.phase.preparing_java.validating": {
"message": "Bekräftar Java {version}"
},
"app.install.phase.reading_pack_manifest": {
"message": "Läser pack information"
},
"app.install.phase.resolving_loader": {
"message": "Laddar ner loadern"
},
"app.install.phase.resolving_minecraft": {
"message": "Laddar ner Minecraft"
},
"app.install.phase.resolving_pack": {
"message": "Laddar ner innehåll"
},
"app.instance.confirm-delete.admonition-body": {
"message": "All data från din instans kommer permanent raderas, däribland dina världar, konfigurationer samt allt installerat innehåll."
},
@@ -203,6 +287,15 @@
"app.instance.modpack-already-installed.instance": {
"message": "Instans"
},
"app.instance.mods.bulk-update.downloading-projects": {
"message": "Laddar ner {current, number}/{total, number} projekt..."
},
"app.instance.mods.bulk-update.finishing": {
"message": "Slutför uppdatering..."
},
"app.instance.mods.bulk-update.resolving-versions": {
"message": "Laddar versioner..."
},
"app.instance.mods.content-type-project": {
"message": "projekt"
},
@@ -227,6 +320,15 @@
"app.instance.worlds.browse-servers": {
"message": "Utforska servrar"
},
"app.instance.worlds.delete-world-modal.delete-button": {
"message": "Ta bort värld"
},
"app.instance.worlds.delete-world-modal.title": {
"message": "Ta bort värld"
},
"app.instance.worlds.delete-world-modal.warning-header": {
"message": "Raderar {name}"
},
"app.instance.worlds.filter-modded": {
"message": "Moddad"
},
@@ -245,6 +347,15 @@
"app.instance.worlds.no-worlds-heading": {
"message": "Inga servrar eller världar tillagda"
},
"app.instance.worlds.remove-server-modal.remove-button": {
"message": "Ta bort server"
},
"app.instance.worlds.remove-server-modal.title": {
"message": "Ta bort server"
},
"app.instance.worlds.remove-server-modal.warning-header": {
"message": "Raderar {name}"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Sök {count} världar..."
},
@@ -287,6 +398,9 @@
"app.project.install-button.already-installed": {
"message": "Detta projekt är redan installerat"
},
"app.project.install-context.back-to-browse": {
"message": "Tillbaka till upptäck"
},
"app.project.install-context.install-content-to-instance": {
"message": "Installera innehåll till instans"
},
@@ -401,6 +515,12 @@
"app.skins.rate-limit.title": {
"message": "Sakta ner!"
},
"app.skins.reorder-error.text": {
"message": "Ditt utseende kunde inte sparas."
},
"app.skins.section.builders-and-biomes": {
"message": "Builders & Biomes"
},
"app.skins.section.chase-the-skies": {
"message": "Chase the Skies"
},
@@ -425,6 +545,9 @@
"app.skins.section.saved-skins": {
"message": "Sparade utseenden"
},
"app.skins.section.striding-hero": {
"message": "Striding Hero"
},
"app.skins.section.the-copper-age": {
"message": "The Copper Age"
},
@@ -815,6 +938,9 @@
"instance.worlds.copy_address": {
"message": "Kopiera adress"
},
"instance.worlds.create_shortcut": {
"message": "Skapa genväg"
},
"instance.worlds.dont_show_on_home": {
"message": "Visa inte på Startsidan"
},
@@ -170,18 +170,12 @@
"app.export-modal.header": {
"message": "ส่งออกแพ็กม็อด"
},
"app.export-modal.include-file-accessibility-label": {
"message": "รวมถึง \"{file}\" ใช่หรือไม่"
},
"app.export-modal.modpack-name-label": {
"message": "ชื่อแพ็กม็อด"
},
"app.export-modal.modpack-name-placeholder": {
"message": "ชื่อแพ็กม็อด"
},
"app.export-modal.select-files-label": {
"message": "กำหนดไฟล์ที่ต้องการจะส่งออก"
},
"app.export-modal.version-number-label": {
"message": "หมายเลขเวอร์ชัน"
},
+123 -6
View File
@@ -11,6 +11,33 @@
"app.action-bar.hide-more-running-instances": {
"message": "Diğer çalışan kurulumları gizle"
},
"app.action-bar.install.dismiss": {
"message": "Reddet"
},
"app.action-bar.install.failed": {
"message": "Yükleme yapılamadı"
},
"app.action-bar.install.failed-app-closed": {
"message": "Yükleme uygulama kapandığından yapılamadı."
},
"app.action-bar.install.failed-network": {
"message": "Yükleme ağ hatasından dolayı yapılamadı."
},
"app.action-bar.install.failed-unknown": {
"message": "Yükleme bilinmeyen bir hatadan yapılamadı."
},
"app.action-bar.install.open-instance": {
"message": "Kurulumu aç"
},
"app.action-bar.install.retry": {
"message": "Yeniden Dene"
},
"app.action-bar.install.unknown-instance": {
"message": "Bilinmeyen kurulum"
},
"app.action-bar.installs": {
"message": "Yüklenenler"
},
"app.action-bar.make-primary-instance": {
"message": "Birincil kurulum yap"
},
@@ -101,6 +128,12 @@
"app.appearance-settings.show-play-time.title": {
"message": "Oynama Süresini Göster"
},
"app.appearance-settings.skip-non-essential-warnings.description": {
"message": "Mükerrer mod paketi kurulumları, normal içerik silme, toplu güncellemeler, mod paketi bağlantısını kesme ve onarım uyarıları gibi düşük riskli onayları otomatik olarak atlar. Tehlikeli uyarılar gösterilmeye devam edecektir."
},
"app.appearance-settings.skip-non-essential-warnings.title": {
"message": "Gerekli olmayan uyarıları atla"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Kenar çubuğunu ayarlama özelliğini aktifleştirir."
},
@@ -170,24 +203,72 @@
"app.export-modal.header": {
"message": "Mod paketini dışa aktar"
},
"app.export-modal.include-file-accessibility-label": {
"message": "\"{file}\" dahil mi?"
},
"app.export-modal.modpack-name-label": {
"message": "Mod Paketi Adı"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Mod paketi adı"
},
"app.export-modal.select-files-label": {
"message": "Bu dışa aktarmaya hangi dosyaların dahil edileceğini yapılandırma"
},
"app.export-modal.version-number-label": {
"message": "Sürüm numarası"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.install.phase.downloading_content": {
"message": "İçerik indiriliyor"
},
"app.install.phase.downloading_minecraft": {
"message": "Minecraft yükleniyor"
},
"app.install.phase.downloading_pack_file": {
"message": "Paket dosyaları yükleniyor"
},
"app.install.phase.extracting_overrides": {
"message": "Geçersiz kılmalar ayıklanıyor"
},
"app.install.phase.finalizing": {
"message": "Tamamlanıyor"
},
"app.install.phase.preparing_instance": {
"message": "Kurulum hazırlanıyor"
},
"app.install.phase.preparing_java": {
"message": "Java Hazırlanıyor"
},
"app.install.phase.preparing_java.downloading": {
"message": "Java {version} İndiriliyor"
},
"app.install.phase.preparing_java.extracting": {
"message": "Java {version} ayıklanıyor"
},
"app.install.phase.preparing_java.fetching-metadata": {
"message": "Java {version} getiriliyor"
},
"app.install.phase.preparing_java.resolving": {
"message": "Java {version} Hazırlanıyor"
},
"app.install.phase.preparing_java.validating": {
"message": "Java {version} doğrulanıyor"
},
"app.install.phase.reading_pack_manifest": {
"message": "Paket manifesti okunuyor"
},
"app.install.phase.resolving_loader": {
"message": "Yükleyici çözümleniyor"
},
"app.install.phase.resolving_minecraft": {
"message": "Minecraft çözümleniyor"
},
"app.install.phase.resolving_pack": {
"message": "İçerik çözümleniyor"
},
"app.install.phase.rolling_back": {
"message": "Değişiklikler geri alınıyor"
},
"app.install.phase.running_loader_processors": {
"message": "Yükleyici işlemcileri çalıştırılıyor"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Dünyalarınız, yapılandırmalarınız ve yüklü tüm içerikler ve tüm veriler kalıcı olarak silinecek."
},
@@ -212,6 +293,15 @@
"app.instance.modpack-already-installed.instance": {
"message": "Kurulum"
},
"app.instance.mods.bulk-update.downloading-projects": {
"message": "{current, number}/{total, number} proje indiriliyor..."
},
"app.instance.mods.bulk-update.finishing": {
"message": "Güncelleme tamamlanıyor..."
},
"app.instance.mods.bulk-update.resolving-versions": {
"message": "Sürümler çözümleniyor..."
},
"app.instance.mods.content-type-project": {
"message": "proje"
},
@@ -236,6 +326,18 @@
"app.instance.worlds.browse-servers": {
"message": "Sunucuları Keşfet"
},
"app.instance.worlds.delete-world-modal.delete-button": {
"message": "Dünya Sil"
},
"app.instance.worlds.delete-world-modal.title": {
"message": "Dünyayı sil"
},
"app.instance.worlds.delete-world-modal.warning-body": {
"message": "Bu dünya, bu profilden kalıcı olarak silinecek. Bu işlem geri alınamaz."
},
"app.instance.worlds.delete-world-modal.warning-header": {
"message": "{name} Siliniyor"
},
"app.instance.worlds.filter-modded": {
"message": "Modlu"
},
@@ -254,6 +356,18 @@
"app.instance.worlds.no-worlds-heading": {
"message": "Eklenmiş sunucu veya dünya yok"
},
"app.instance.worlds.remove-server-modal.remove-button": {
"message": "Sunucuyu kaldır"
},
"app.instance.worlds.remove-server-modal.title": {
"message": "Sunucuyu kaldır"
},
"app.instance.worlds.remove-server-modal.warning-body": {
"message": "Bu sunucu, sunucu listenizden ve oyun içi sunucu listesinden kaldırılacaktır. Adresini biliyorsanız daha sonra tekrar ekleyebilirsiniz."
},
"app.instance.worlds.remove-server-modal.warning-header": {
"message": "{name} kaldırılıyor"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "{count} dünya ara..."
},
@@ -839,6 +953,9 @@
"instance.worlds.copy_address": {
"message": "Adresi kopyala"
},
"instance.worlds.create_shortcut": {
"message": "Kısayol yap"
},
"instance.worlds.dont_show_on_home": {
"message": "Ana sayfada gösterme"
},
@@ -170,18 +170,12 @@
"app.export-modal.header": {
"message": "Експортувати збірку"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Уключити «{file}»?"
},
"app.export-modal.modpack-name-label": {
"message": "Назва збірки"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Назва збірки"
},
"app.export-modal.select-files-label": {
"message": "Змініть файли, які додані до експорту"
},
"app.export-modal.version-number-label": {
"message": "Номер версії"
},
@@ -170,18 +170,12 @@
"app.export-modal.header": {
"message": "Xuất modpack"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Bao gồm \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Tên modpack"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Tên modpack"
},
"app.export-modal.select-files-label": {
"message": "Cấu hình các tệp nào được bao gồm trong quá trình xuất phiên bản này"
},
"app.export-modal.version-number-label": {
"message": "Phiên bản"
},
+132 -15
View File
@@ -11,6 +11,33 @@
"app.action-bar.hide-more-running-instances": {
"message": "隐藏更多运行中的实例"
},
"app.action-bar.install.dismiss": {
"message": "忽略"
},
"app.action-bar.install.failed": {
"message": "安装失败"
},
"app.action-bar.install.failed-app-closed": {
"message": "由于应用关闭,安装失败。"
},
"app.action-bar.install.failed-network": {
"message": "由于网络错误,安装失败。"
},
"app.action-bar.install.failed-unknown": {
"message": "由于未知错误,安装失败。"
},
"app.action-bar.install.open-instance": {
"message": "打开实例"
},
"app.action-bar.install.retry": {
"message": "重试"
},
"app.action-bar.install.unknown-instance": {
"message": "未知的实例"
},
"app.action-bar.installs": {
"message": "安装"
},
"app.action-bar.make-primary-instance": {
"message": "设为主实例"
},
@@ -101,6 +128,12 @@
"app.appearance-settings.show-play-time.title": {
"message": "显示总游玩时间"
},
"app.appearance-settings.skip-non-essential-warnings.description": {
"message": "自动跳过低风险确认,包括重复安装整合包、常规内容删除、批量更新、解除整合包关联及修复提示。危险警告仍会显示。"
},
"app.appearance-settings.skip-non-essential-warnings.title": {
"message": "跳过非必要的警告"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "启用切换侧边栏的功能。"
},
@@ -108,7 +141,7 @@
"message": "切换侧边栏"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "如果你尝试安装一个未托管在 Modrinth 上的 Modrinth 包文件(.mrpack),我们会确保你在安装之前了解相关风险。"
"message": "如果你尝试安装一个未托管在 Modrinth 上的 Modrinth 整合包文件(.mrpack),我们会确保你在安装之前了解相关风险。"
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "安装未知整合包前提醒我"
@@ -120,7 +153,7 @@
"message": "无法连接到身份验证服务器"
},
"app.browse.add-servers-to-instance": {
"message": "正在添加服务器到实例"
"message": "添加服务器到实例"
},
"app.browse.add-to-an-instance": {
"message": "添加到实例"
@@ -170,24 +203,72 @@
"app.export-modal.header": {
"message": "导出整合包"
},
"app.export-modal.include-file-accessibility-label": {
"message": "包含 \"{file}\""
},
"app.export-modal.modpack-name-label": {
"message": "整合包名称"
},
"app.export-modal.modpack-name-placeholder": {
"message": "整合包名称"
},
"app.export-modal.select-files-label": {
"message": "配置此导出中包含哪些文件"
},
"app.export-modal.version-number-label": {
"message": "版本号"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.install.phase.downloading_content": {
"message": "正在下载内容"
},
"app.install.phase.downloading_minecraft": {
"message": "正在下载 Minecraft"
},
"app.install.phase.downloading_pack_file": {
"message": "正在下载包文件"
},
"app.install.phase.extracting_overrides": {
"message": "提取覆盖项"
},
"app.install.phase.finalizing": {
"message": "完成"
},
"app.install.phase.preparing_instance": {
"message": "准备实例"
},
"app.install.phase.preparing_java": {
"message": "正在准备 Java"
},
"app.install.phase.preparing_java.downloading": {
"message": "正在下载 Java {version}"
},
"app.install.phase.preparing_java.extracting": {
"message": "正在提取 Java {version}"
},
"app.install.phase.preparing_java.fetching-metadata": {
"message": "正在获取 Java {version}"
},
"app.install.phase.preparing_java.resolving": {
"message": "正在准备 Java {version}"
},
"app.install.phase.preparing_java.validating": {
"message": "正在校验 Java {version}"
},
"app.install.phase.reading_pack_manifest": {
"message": "正在读取整合包清单"
},
"app.install.phase.resolving_loader": {
"message": "正在解析加载器"
},
"app.install.phase.resolving_minecraft": {
"message": "正在解析 Minecraft"
},
"app.install.phase.resolving_pack": {
"message": "正在解析内容"
},
"app.install.phase.rolling_back": {
"message": "回滚"
},
"app.install.phase.running_loader_processors": {
"message": "正在运行加载处理器"
},
"app.instance.confirm-delete.admonition-body": {
"message": "你实例的所有数据将被永久删除,包括你的世界、配置和所有已安装的内容。"
},
@@ -212,6 +293,15 @@
"app.instance.modpack-already-installed.instance": {
"message": "实例"
},
"app.instance.mods.bulk-update.downloading-projects": {
"message": "正在下载 {current, number}/{total, number}个 项目……"
},
"app.instance.mods.bulk-update.finishing": {
"message": "正在结束更新……"
},
"app.instance.mods.bulk-update.resolving-versions": {
"message": "正在解析版本……"
},
"app.instance.mods.content-type-project": {
"message": "项目"
},
@@ -236,6 +326,18 @@
"app.instance.worlds.browse-servers": {
"message": "浏览服务器"
},
"app.instance.worlds.delete-world-modal.delete-button": {
"message": "删除世界"
},
"app.instance.worlds.delete-world-modal.title": {
"message": "删除世界"
},
"app.instance.worlds.delete-world-modal.warning-body": {
"message": "这个世界将会被永久删除,此操作无法撤销。"
},
"app.instance.worlds.delete-world-modal.warning-header": {
"message": "正在删除 {name}"
},
"app.instance.worlds.filter-modded": {
"message": "模组适配"
},
@@ -254,6 +356,18 @@
"app.instance.worlds.no-worlds-heading": {
"message": "未添加服务器或世界"
},
"app.instance.worlds.remove-server-modal.remove-button": {
"message": "删除服务器"
},
"app.instance.worlds.remove-server-modal.title": {
"message": "删除服务器"
},
"app.instance.worlds.remove-server-modal.warning-body": {
"message": "该服务器将会被移出你的服务器列表,也包括游戏内的服务器列表。之后如果你记得地址,仍可将其添加回来。"
},
"app.instance.worlds.remove-server-modal.warning-header": {
"message": "正在删除 {name}"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "搜索 {count} 个世界……"
},
@@ -651,7 +765,7 @@
"message": "将从设备中永久删除该实例,包括所有存档、配置文件及已安装内容。此操作不可撤销,请谨慎操作。"
},
"instance.settings.tabs.general.deleting.button": {
"message": "删除中..."
"message": "删除中……"
},
"instance.settings.tabs.general.duplicate-button": {
"message": "复制"
@@ -732,7 +846,7 @@
"message": "在游戏关闭后运行。"
},
"instance.settings.tabs.hooks.post-exit.enter": {
"message": "输入退出后运行的命令…"
"message": "输入退出后运行的命令…"
},
"instance.settings.tabs.hooks.pre-launch": {
"message": "启动前"
@@ -741,7 +855,7 @@
"message": "在实例启动前运行。"
},
"instance.settings.tabs.hooks.pre-launch.enter": {
"message": "输入启动前命令..."
"message": "输入启动前命令……"
},
"instance.settings.tabs.hooks.title": {
"message": "游戏启动钩子"
@@ -753,7 +867,7 @@
"message": "用于启动 Minecraft 的包装器命令。"
},
"instance.settings.tabs.hooks.wrapper.enter": {
"message": "输入封装命令..."
"message": "输入封装命令……"
},
"instance.settings.tabs.installation": {
"message": "安装"
@@ -819,7 +933,7 @@
"message": "游戏启动时的窗口高度。"
},
"instance.settings.tabs.window.height.enter": {
"message": "输入高度…"
"message": "输入高度…"
},
"instance.settings.tabs.window.width": {
"message": "宽度"
@@ -828,7 +942,7 @@
"message": "游戏启动时的窗口宽度。"
},
"instance.settings.tabs.window.width.enter": {
"message": "输入宽度…"
"message": "输入宽度…"
},
"instance.worlds.a_minecraft_server": {
"message": "Minecraft 服务器"
@@ -839,6 +953,9 @@
"instance.worlds.copy_address": {
"message": "复制地址"
},
"instance.worlds.create_shortcut": {
"message": "创建快照"
},
"instance.worlds.dont_show_on_home": {
"message": "在主界面隐藏"
},
@@ -927,7 +1044,7 @@
"message": "仍然安装"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "恶意软件常常通过模组包文件在 Discord 等平台上分享而传播。"
"message": "恶意软件常常通过整合包文件在 Discord 等平台上分享而传播。"
},
"unknown-pack-warning-modal.warning.body": {
"message": "我们在 Modrinth 上找不到此文件。强烈建议你仅从可信来源安装文件。"
+124 -7
View File
@@ -11,6 +11,33 @@
"app.action-bar.hide-more-running-instances": {
"message": "隱藏更多執行中的實例"
},
"app.action-bar.install.dismiss": {
"message": "忽略"
},
"app.action-bar.install.failed": {
"message": "無法安裝"
},
"app.action-bar.install.failed-app-closed": {
"message": "由於應用程式關閉,無法安裝。"
},
"app.action-bar.install.failed-network": {
"message": "由於網路錯誤,無法安裝。"
},
"app.action-bar.install.failed-unknown": {
"message": "由於未知錯誤,無法安裝。"
},
"app.action-bar.install.open-instance": {
"message": "開啟實例"
},
"app.action-bar.install.retry": {
"message": "重試"
},
"app.action-bar.install.unknown-instance": {
"message": "未知的實例"
},
"app.action-bar.installs": {
"message": "安裝"
},
"app.action-bar.make-primary-instance": {
"message": "設為主要實例"
},
@@ -101,6 +128,12 @@
"app.appearance-settings.show-play-time.title": {
"message": "顯示遊玩時數"
},
"app.appearance-settings.skip-non-essential-warnings.description": {
"message": "自動跳過低風險操作的確認提示,例如重複安裝模組包、常規內容刪除、批次更新、取消連結模組包以及修復提示。高風險警告仍會顯示。"
},
"app.appearance-settings.skip-non-essential-warnings.title": {
"message": "跳過非必要的警告"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "啟用切換側邊欄的功能。"
},
@@ -162,7 +195,7 @@
"message": "沒有符合 {compatibilityLabel} 的可用版本。請選擇一個版本強制安裝。不會自動安裝相依模組。"
},
"app.export-modal.description-placeholder": {
"message": "輸入模組包描述..."
"message": "輸入模組包描述……"
},
"app.export-modal.export-button": {
"message": "匯出"
@@ -170,24 +203,72 @@
"app.export-modal.header": {
"message": "匯出模組包"
},
"app.export-modal.include-file-accessibility-label": {
"message": "要包含「{file}」嗎?"
},
"app.export-modal.modpack-name-label": {
"message": "模組包名稱"
},
"app.export-modal.modpack-name-placeholder": {
"message": "模組包名稱"
},
"app.export-modal.select-files-label": {
"message": "設定要包含在此匯出檔案中的檔案"
},
"app.export-modal.version-number-label": {
"message": "版本號碼"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.install.phase.downloading_content": {
"message": "正在下載內容"
},
"app.install.phase.downloading_minecraft": {
"message": "正在下載 Minecraft"
},
"app.install.phase.downloading_pack_file": {
"message": "正在下載模組包檔案"
},
"app.install.phase.extracting_overrides": {
"message": "正在解壓縮覆寫檔案"
},
"app.install.phase.finalizing": {
"message": "即將完成"
},
"app.install.phase.preparing_instance": {
"message": "正在準備實例"
},
"app.install.phase.preparing_java": {
"message": "正在準備 Java"
},
"app.install.phase.preparing_java.downloading": {
"message": "正在下載 Java {version}"
},
"app.install.phase.preparing_java.extracting": {
"message": "正在解壓縮 Java {version}"
},
"app.install.phase.preparing_java.fetching-metadata": {
"message": "正在擷取 Java {version}"
},
"app.install.phase.preparing_java.resolving": {
"message": "正在準備 Java {version}"
},
"app.install.phase.preparing_java.validating": {
"message": "正在驗證 Java {version}"
},
"app.install.phase.reading_pack_manifest": {
"message": "正在讀取模組包清單"
},
"app.install.phase.resolving_loader": {
"message": "正在解析載入器"
},
"app.install.phase.resolving_minecraft": {
"message": "正在解析 Minecraft"
},
"app.install.phase.resolving_pack": {
"message": "正在解析內容"
},
"app.install.phase.rolling_back": {
"message": "正在復原"
},
"app.install.phase.running_loader_processors": {
"message": "正在執行載入器處理程式"
},
"app.instance.confirm-delete.admonition-body": {
"message": "你實例中的所有資料將被永久刪除,包含你的世界、設定檔以及所有已安裝的內容。"
},
@@ -212,6 +293,15 @@
"app.instance.modpack-already-installed.instance": {
"message": "實例"
},
"app.instance.mods.bulk-update.downloading-projects": {
"message": "正在下載專案 {current, number}/{total, number}..."
},
"app.instance.mods.bulk-update.finishing": {
"message": "正在結束更新..."
},
"app.instance.mods.bulk-update.resolving-versions": {
"message": "正在解析版本..."
},
"app.instance.mods.content-type-project": {
"message": "專案"
},
@@ -236,6 +326,18 @@
"app.instance.worlds.browse-servers": {
"message": "瀏覽伺服器"
},
"app.instance.worlds.delete-world-modal.delete-button": {
"message": "刪除世界"
},
"app.instance.worlds.delete-world-modal.title": {
"message": "刪除世界"
},
"app.instance.worlds.delete-world-modal.warning-body": {
"message": "此世界將會被永久刪除,此操作無法復原。"
},
"app.instance.worlds.delete-world-modal.warning-header": {
"message": "正在刪除 {name}"
},
"app.instance.worlds.filter-modded": {
"message": "模組"
},
@@ -254,6 +356,18 @@
"app.instance.worlds.no-worlds-heading": {
"message": "未新增任何伺服器或世界"
},
"app.instance.worlds.remove-server-modal.remove-button": {
"message": "移除伺服器"
},
"app.instance.worlds.remove-server-modal.title": {
"message": "移除伺服器"
},
"app.instance.worlds.remove-server-modal.warning-body": {
"message": "這個伺服器將從你的伺服器清單中移除。如果你記得伺服器位址,稍後可以將其重新新增回來。"
},
"app.instance.worlds.remove-server-modal.warning-header": {
"message": "正在移除 {name}"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "搜尋 {count} 個世界..."
},
@@ -839,6 +953,9 @@
"instance.worlds.copy_address": {
"message": "複製位址"
},
"instance.worlds.create_shortcut": {
"message": "建立捷徑"
},
"instance.worlds.dont_show_on_home": {
"message": "不要在首頁顯示"
},
+9 -4
View File
@@ -22,6 +22,8 @@ import {
preferencesDiffer,
provideBrowseManager,
requestInstall,
stripServerRuntimeInstallFilters,
stripServerRuntimeInstallOverrides,
useBrowseSearch,
useDebugLogger,
useVIntl,
@@ -403,7 +405,7 @@ const messages = defineMessages({
},
hideAddedServers: {
id: 'app.browse.hide-added-servers',
defaultMessage: 'Hide already added servers',
defaultMessage: 'Hide servers already added',
},
installingToServer: {
id: 'app.browse.server.installing',
@@ -680,7 +682,6 @@ async function chooseInstanceInstallVersion(
const selectedVersion = getLatestMatchingInstallVersion(
await getInstallProjectVersions(project.project_id),
selectedPreferences,
projectTypeValue,
)
if (!selectedVersion) {
@@ -763,11 +764,15 @@ function getCardActions(
project: projectResult,
contentType,
mode: isModpack ? 'immediate' : 'queue',
selectedFilters: isModpack ? [] : searchState.currentFilters.value,
selectedFilters: isModpack
? []
: stripServerRuntimeInstallFilters(searchState.currentFilters.value),
providedFilters: isModpack ? [] : combinedProvidedFilters.value,
overriddenProvidedFilterTypes: isModpack
? []
: searchState.overriddenProvidedFilterTypes.value,
: stripServerRuntimeInstallOverrides(
searchState.overriddenProvidedFilterTypes.value,
),
targetPreferences: getServerInstallTargetPreferences(contentType),
getProjectVersions: getInstallProjectVersions,
queue: serverInstallQueue,
+6
View File
@@ -114,6 +114,10 @@ const messages = defineMessages({
id: 'app.skins.section.tiny-takeover',
defaultMessage: 'Tiny Takeover',
},
chaosCubedSection: {
id: 'app.skins.section.chaos-cubed',
defaultMessage: 'Chaos Cubed',
},
rateLimitTitle: {
id: 'app.skins.rate-limit.title',
defaultMessage: 'Slow down!',
@@ -447,6 +451,8 @@ function getDefaultSkinSectionTitle(section?: string) {
return formatMessage(messages.mountsOfMayhemSection)
case 'Tiny Takeover':
return formatMessage(messages.tinyTakeoverSection)
case 'Chaos Cubed':
return formatMessage(messages.chaosCubedSection)
case 'Default skins':
return formatMessage(messages.defaultSkinsSection)
default:
@@ -1,7 +1,11 @@
<template>
<div class="h-full w-full pt-6">
<div
class="h-full w-full pt-6"
:class="isContainedServerRoute ? 'box-border min-h-0 overflow-hidden' : ''"
>
<ServersManageRootLayout
:server-id="serverId"
:layout-mode="isContainedServerRoute ? 'contained' : 'page'"
:reload-page="() => router.go(0)"
:resolve-viewer="resolveViewer"
:show-copy-id-action="themeStore.devMode"
@@ -63,6 +67,8 @@ const queryClient = useQueryClient()
const themeStore = useTheming()
const breadcrumbs = useBreadcrumbs()
const isContainedServerRoute = computed(() => route.name === 'ServerManageOverview')
const serverId = computed(() => {
const rawId = route.params.id
return Array.isArray(rawId) ? rawId[0] : (rawId ?? '')
@@ -3,5 +3,5 @@ import { ServersManageOverviewPage } from '@modrinth/ui'
</script>
<template>
<ServersManageOverviewPage />
<ServersManageOverviewPage contained-console />
</template>
+44 -11
View File
@@ -317,6 +317,10 @@ import ContextMenu from '@/components/ui/ContextMenu.vue'
import ExportModal from '@/components/ui/ExportModal.vue'
import InstanceSettingsModal from '@/components/ui/modal/InstanceSettingsModal.vue'
import UpdateToPlayModal from '@/components/ui/modal/UpdateToPlayModal.vue'
import {
fetchCachedServerStatus,
getFreshCachedServerStatus,
} from '@/composables/instances/use-server-status-query'
import { useInstanceConsole } from '@/composables/useInstanceConsole'
import { trackEvent } from '@/helpers/analytics'
import { get_project_v3 } from '@/helpers/cache.js'
@@ -327,7 +331,7 @@ import { type InstanceContentData, loadInstanceContentData } from '@/helpers/ins
import { get_by_instance_id } from '@/helpers/process'
import type { GameInstance } from '@/helpers/types'
import { createInstanceShortcut, showInstanceInFolder } from '@/helpers/utils.js'
import { get_server_status, refreshWorlds } from '@/helpers/worlds'
import { refreshWorlds, type ServerStatus } from '@/helpers/worlds'
import { injectServerInstall } from '@/providers/server-install'
import { handleSevereError } from '@/store/error.js'
import { useBreadcrumbs, useTheming } from '@/store/state'
@@ -372,13 +376,15 @@ const selected = ref<unknown[]>([])
const minecraftServer = computed(() => linkedProjectV3.value?.minecraft_server)
const javaServerPingData = computed(() => linkedProjectV3.value?.minecraft_java_server?.ping?.data)
const statusOnline = computed(() => !!javaServerPingData.value)
const liveServerStatusOnline = ref(false)
const statusOnline = computed(() => liveServerStatusOnline.value || !!javaServerPingData.value)
const recentPlays = computed(
() => linkedProjectV3.value?.minecraft_java_server?.verified_plays_2w ?? undefined,
)
const playersOnline = ref<number | undefined>(undefined)
const ping = ref<number | undefined>(undefined)
const loadingServerPing = ref(false)
const activeInstanceId = ref<string>()
watch(
() => router.currentRoute.value,
@@ -390,6 +396,20 @@ watch(
{ immediate: true },
)
function applyServerStatus(status: ServerStatus) {
playersOnline.value = status.players?.online
ping.value = status.ping
liveServerStatusOnline.value = true
loadingServerPing.value = true
}
function resetServerStatus() {
ping.value = undefined
playersOnline.value = undefined
liveServerStatusOnline.value = false
loadingServerPing.value = false
}
function isContentSubpageRoute(routeName = displayedInstanceRoute.value.name) {
return typeof routeName === 'string' && contentSubpageRouteNames.has(routeName)
}
@@ -398,9 +418,7 @@ async function fetchInstance() {
isServerInstance.value = false
linkedProjectV3.value = undefined
preloadedContent.value = null
ping.value = undefined
playersOnline.value = undefined
loadingServerPing.value = false
resetServerStatus()
const nextInstance = await get(route.params.id as string).catch(handleError)
let nextLinkedProjectV3: Labrinth.Projects.v3.Project | undefined
@@ -429,8 +447,9 @@ async function fetchInstance() {
linkedProjectV3.value = nextLinkedProjectV3
isServerInstance.value = nextIsServerInstance
preloadedContent.value = nextPreloadedContent
activeInstanceId.value = nextInstance?.id
fetchDeferredData()
fetchDeferredData(nextInstance?.id)
if (nextInstance) {
queryClient.prefetchQuery({
@@ -441,18 +460,32 @@ async function fetchInstance() {
}
}
function fetchDeferredData() {
function fetchDeferredData(instanceId?: string) {
const serverAddress = linkedProjectV3.value?.minecraft_java_server?.address
if (isServerInstance.value && serverAddress) {
get_server_status(serverAddress)
const cachedStatus = getFreshCachedServerStatus(queryClient, serverAddress)
if (cachedStatus) {
applyServerStatus(cachedStatus)
} else {
playersOnline.value = undefined
ping.value = undefined
loadingServerPing.value = false
}
fetchCachedServerStatus(queryClient, serverAddress)
.then((status) => {
playersOnline.value = status.players?.online
ping.value = status.ping
if (
activeInstanceId.value !== instanceId ||
linkedProjectV3.value?.minecraft_java_server?.address !== serverAddress
)
return
applyServerStatus(status)
})
.catch((error) => {
console.error(`Failed to fetch server status for ${serverAddress}:`, error)
})
.finally(() => {
if (activeInstanceId.value !== instanceId) return
loadingServerPing.value = true
})
} else {
@@ -676,7 +709,7 @@ const handleOptionsClick = async (args: { option: string; item: unknown }) => {
break
case 'copy_path': {
if (instance.value) {
const fullPath = await get_full_path(instance.value?.path)
const fullPath = await get_full_path(instance.value.id)
await navigator.clipboard.writeText(fullPath)
}
break
@@ -1351,7 +1351,9 @@ provideContentManager({
title: item.file_name.replace('.disabled', ''),
icon_url: null,
},
projectLink: item.project?.id ? { path: `/project/${item.project.id}` } : undefined,
projectLink: item.project?.id
? { path: `/project/${item.project.id}`, query: { i: props.instance.id } }
: undefined,
version: item.version ?? {
id: item.file_name,
version_number: formatMessage(commonMessages.unknownLabel),
@@ -1361,6 +1363,7 @@ provideContentManager({
item.project?.id && item.version?.id
? {
path: `/project/${item.project.id}/version/${item.version.id}`,
query: { i: props.instance.id },
}
: undefined,
owner: item.owner
@@ -1443,7 +1446,7 @@ onMounted(() => {
props.instance &&
event.instance_id === props.instance.id &&
event.event === 'synced' &&
props.instance.install_stage !== 'pack_installing' &&
props.instance.install_stage === 'installed' &&
!isBulkOperating.value
) {
await initProjects()
@@ -618,10 +618,7 @@ const filterOptions = computed(() => {
const hasSingleplayer = dedupedWorlds.value.some((x) => x.type === 'singleplayer')
const hasServer = dedupedWorlds.value.some((x) => x.type === 'server')
const hasStatusFilter =
selectedFilters.value.includes('online') || selectedFilters.value.includes('offline')
if (hasSingleplayer && hasServer && !hasStatusFilter) {
if (hasSingleplayer && hasServer) {
options.push({ id: 'singleplayer', label: formatMessage(commonMessages.singleplayerLabel) })
}
@@ -633,13 +630,11 @@ const filterOptions = computed(() => {
options.push({ id: 'vanilla', label: formatMessage(messages.vanillaFilter) })
options.push({ id: 'modded', label: formatMessage(messages.moddedFilter) })
}
if (!selectedFilters.value.includes('singleplayer')) {
const hasOnline = servers.some((x) => !!serverData.value[x.address]?.status)
const hasOffline = servers.some((x) => !serverData.value[x.address]?.status)
if (hasOnline && hasOffline) {
options.push({ id: 'online', label: formatMessage(messages.onlineFilter) })
options.push({ id: 'offline', label: formatMessage(messages.offlineFilter) })
}
const hasOnline = servers.some((x) => !!serverData.value[x.address]?.status)
const hasOffline = servers.some((x) => !serverData.value[x.address]?.status)
if (hasOnline && hasOffline) {
options.push({ id: 'online', label: formatMessage(messages.onlineFilter) })
options.push({ id: 'offline', label: formatMessage(messages.offlineFilter) })
}
}
+51 -8
View File
@@ -116,13 +116,27 @@
aria-label="More options"
>
<MoreVerticalIcon aria-hidden="true" />
<template #open-in-browser> <ExternalIcon /> Open in browser </template>
<template #open-in-browser>
<ExternalIcon /> {{ formatMessage(commonMessages.openInBrowserButton) }}
</template>
<template #report> <ReportIcon /> Report </template>
</OverflowMenu>
</ButtonStyled>
</template>
<template v-else #actions>
<ButtonStyled size="large" color="brand">
<ButtonStyled v-if="showSwitchVersion && onVersionsPage" size="large">
<button v-tooltip="installButtonTooltip" disabled>
<CheckIcon />
{{ formatMessage(commonMessages.installedLabel) }}
</button>
</ButtonStyled>
<ButtonStyled v-else-if="showSwitchVersion" size="large">
<button @click="goToVersions">
<SwapIcon />
{{ formatMessage(messages.switchVersion) }}
</button>
</ButtonStyled>
<ButtonStyled v-else size="large" color="brand">
<button
v-tooltip="installButtonTooltip"
:disabled="installButtonDisabled"
@@ -171,7 +185,9 @@
aria-label="More options"
>
<MoreVerticalIcon aria-hidden="true" />
<template #open-in-browser> <ExternalIcon /> Open in browser </template>
<template #open-in-browser>
<ExternalIcon /> {{ formatMessage(commonMessages.openInBrowserButton) }}
</template>
<template #follow> <HeartIcon /> Follow </template>
<template #save> <BookmarkIcon /> Save </template>
<template #report> <ReportIcon /> Report </template>
@@ -286,6 +302,7 @@ import {
SelectedProjectsFloatingBar,
useVIntl,
} from '@modrinth/ui'
import { useQueryClient } from '@tanstack/vue-query'
import { convertFileSrc } from '@tauri-apps/api/core'
import { openUrl } from '@tauri-apps/plugin-opener'
import dayjs from 'dayjs'
@@ -293,8 +310,13 @@ import relativeTime from 'dayjs/plugin/relativeTime'
import { computed, onUnmounted, ref, shallowRef, watch } from 'vue'
import { useRoute, useRouter } from 'vue-router'
import { SwapIcon } from '@/assets/icons/index.js'
import ContextMenu from '@/components/ui/ContextMenu.vue'
import InstanceIndicator from '@/components/ui/InstanceIndicator.vue'
import {
fetchCachedServerStatus,
getFreshCachedServerStatus,
} from '@/composables/instances/use-server-status-query'
import {
get_organization,
get_project,
@@ -313,7 +335,7 @@ import {
import { get_loader_versions as getLoaderManifest } from '@/helpers/metadata'
import { get_by_instance_id } from '@/helpers/process'
import { get_categories, get_game_versions, get_loaders } from '@/helpers/tags'
import { getServerAddress, getServerLatency } from '@/helpers/worlds'
import { getServerAddress } from '@/helpers/worlds'
import { injectContentInstall } from '@/providers/content-install'
import { injectServerInstall } from '@/providers/server-install'
import { createServerInstallContent } from '@/providers/setup/server-install-content'
@@ -326,6 +348,7 @@ const { handleError } = injectNotificationManager()
const { install: installVersion } = injectContentInstall()
const route = useRoute()
const router = useRouter()
const queryClient = useQueryClient()
const breadcrumbs = useBreadcrumbs()
const themeStore = useTheming()
const { formatMessage } = useVIntl()
@@ -343,6 +366,10 @@ const messages = defineMessages({
id: 'app.project.install-button.already-installed',
defaultMessage: 'This project is already installed',
},
switchVersion: {
id: 'app.project.install-button.switch-version',
defaultMessage: 'Switch version',
},
})
const { installingServerProjects, playServerProject, showAddServerToInstanceModal } =
@@ -514,6 +541,13 @@ const installButtonTooltip = computed(() => {
return null
})
const showSwitchVersion = computed(() => !!instance.value && installed.value)
const onVersionsPage = computed(() => route.name === 'Versions')
function goToVersions() {
router.push(versionsHref.value)
}
const [allLoaders, allGameVersions] = await Promise.all([
get_loaders().catch(handleError).then(ref),
get_game_versions().catch(handleError).then(ref),
@@ -600,10 +634,19 @@ async function fetchProjectData() {
function fetchDeferredServerData(project) {
const serverAddress = projectV3.value?.minecraft_java_server?.address
if (serverAddress) {
serverPing.value = undefined
getServerLatency(serverAddress)
.then((latency) => {
serverPing.value = latency
const cachedStatus = getFreshCachedServerStatus(queryClient, serverAddress)
if (cachedStatus) {
serverPing.value = cachedStatus.ping
serverStatusOnline.value = true
} else {
serverPing.value = undefined
}
fetchCachedServerStatus(queryClient, serverAddress)
.then((status) => {
if (projectV3.value?.minecraft_java_server?.address !== serverAddress) return
serverPing.value = status.ping
serverStatusOnline.value = true
})
.catch((error) => {
console.error(`Failed to ping server ${serverAddress}:`, error)
+165 -429
View File
@@ -1,259 +1,152 @@
<template>
<div>
<Card>
<Breadcrumbs
:current-title="version.name"
:link-stack="[
{
href: buildProjectHref(`/project/${route.params.id}/versions`),
label: 'Versions',
},
]"
/>
<div class="version-title">
<h2>{{ version.name }}</h2>
</div>
<div class="button-group">
<div class="flex flex-col">
<router-link
class="mb-4 flex w-fit items-center gap-2 rounded-lg px-2 py-0.5 pl-0 text-link"
:to="buildProjectHref(`/project/${route.params.id}/versions`)"
>
<ChevronLeftIcon class="shrink-0" /> {{ formatMessage(messages.allVersions) }}
</router-link>
<VersionPage
v-if="version"
:version="version"
:enrichment="enrichment"
:enrichment-loading="enrichmentLoading"
:members="members"
:dependency-link-creator="createDependencyLink"
>
<template #headerActions>
<ButtonStyled color="brand">
<button
:disabled="installing || (installed && installedVersion === version.id)"
@click="() => install(version.id)"
@click="() => version && install(version.id)"
>
<DownloadIcon v-if="!installed" />
<SwapIcon v-else-if="installedVersion !== version.id" />
<CheckIcon v-else />
{{
installing
? 'Installing...'
? formatMessage(messages.installing)
: installed && installedVersion === version.id
? 'Installed'
: 'Install'
? formatMessage(commonMessages.installedLabel)
: installed
? formatMessage(commonMessages.switchToVersionButton)
: formatMessage(commonMessages.installButton)
}}
</button>
</ButtonStyled>
<ButtonStyled>
<button>
<ReportIcon />
Report
</button>
</ButtonStyled>
<ButtonStyled>
<a
:href="`https://modrinth.com/mod/${route.params.id}/version/${route.params.version}`"
rel="external"
<ButtonStyled type="outlined" circular>
<OverflowMenu
v-tooltip="formatMessage(commonMessages.moreOptionsButton)"
:options="[
{
id: 'open-in-browser',
link: `https://modrinth.com/${project.project_type}/${project.slug}/version/${version.id}`,
external: true,
},
{
id: 'report',
color: 'red',
hoverFilled: true,
link: `https://modrinth.com/report?item=version&itemID=${version.id}`,
external: true,
},
]"
aria-label="More options"
>
Modrinth website
<ExternalIcon />
<MoreVerticalIcon aria-hidden="true" />
<template #open-in-browser>
<ExternalIcon aria-hidden="true" />
{{ formatMessage(commonMessages.openInBrowserButton) }}
</template>
<template #report>
<ReportIcon aria-hidden="true" /> {{ formatMessage(commonMessages.reportButton) }}
</template>
</OverflowMenu>
</ButtonStyled>
</template>
<template #supplementaryResourceActions="{ file }">
<ButtonStyled>
<a :href="file.url" :download="file.filename" target="_blank">
<DownloadIcon aria-hidden="true" />
{{ formatMessage(messages.downloadInBrowser) }}
</a>
</ButtonStyled>
</div>
</Card>
<div class="version-container">
<div class="description-cards">
<Card>
<h3 class="card-title">Changelog</h3>
<div class="markdown-body" v-html="renderString(version.changelog ?? '')" />
</Card>
<Card>
<h3 class="card-title">Files</h3>
<Card
v-for="file in version.files"
:key="file.id"
:class="{ primary: file.primary }"
class="file"
>
<span class="label">
<FileIcon />
<span>
<span class="title">
{{ file.filename }}
</span>
({{ formatBytes(file.size) }})
<span v-if="file.primary" class="primary-label"> Primary </span>
</span>
</span>
<ButtonStyled v-if="project.project_type !== 'modpack' || file.primary" color="brand">
<button class="download" :disabled="installed" @click="() => install(version.id)">
<DownloadIcon v-if="!installed" />
<CheckIcon v-else />
{{ installed ? 'Installed' : 'Install' }}
</button>
</ButtonStyled>
</Card>
</Card>
<Card v-if="displayDependencies.length > 0">
<h2>Dependencies</h2>
<div v-for="dependency in displayDependencies" :key="dependency.title">
<router-link v-if="dependency.link" class="btn dependency" :to="dependency.link">
<Avatar size="sm" :src="dependency.icon" />
<div>
<span class="title"> {{ dependency.title }} </span> <br />
<span> {{ dependency.subtitle }} </span>
</div>
</router-link>
<div v-else class="dependency disabled" disabled="">
<Avatar size="sm" :src="dependency.icon" />
<div class="text">
<div class="title">{{ dependency.title }}</div>
<div>{{ dependency.subtitle }}</div>
</div>
</div>
</div>
</Card>
</div>
<Card class="metadata-card">
<h3 class="card-title">Metadata</h3>
<div class="metadata">
<div class="metadata-item">
<span class="metadata-label">Release Channel</span>
<span class="metadata-value"
><Badge
:color="releaseColor(version.version_type)"
:type="
version.version_type.charAt(0).toUpperCase() + version.version_type.slice(1)
"
/></span>
</div>
<div class="metadata-item">
<span class="metadata-label">Version Number</span>
<span class="metadata-value">{{ version.version_number }}</span>
</div>
<div class="metadata-item">
<span class="metadata-label">Loaders</span>
<span class="metadata-value">{{
version.loaders
.map((loader) => loader.charAt(0).toUpperCase() + loader.slice(1))
.join(', ')
}}</span>
</div>
<div class="metadata-item">
<span class="metadata-label">Game Versions</span>
<span class="metadata-value"> {{ version.game_versions.join(', ') }} </span>
</div>
<div class="metadata-item">
<span class="metadata-label">Downloads</span>
<span class="metadata-value">{{ version.downloads }}</span>
</div>
<div class="metadata-item">
<span class="metadata-label">Publication Date</span>
<span class="metadata-value">
{{ formatDateTime(version.date_published) }}
</span>
</div>
<div v-if="author" class="metadata-item">
<span class="metadata-label">Author</span>
<a
:href="`https://modrinth.com/user/${author.user.username}`"
rel="external"
class="metadata-value btn author"
>
<Avatar size="sm" :src="author.user.avatar_url" circle />
<span>
<strong>
{{ author.user.username }}
</strong>
<br />
{{ author.role }}
</span>
</a>
</div>
<div class="metadata-item">
<span class="metadata-label">Version ID</span>
<span class="metadata-value"><CopyCode class="copycode" :text="version.id" /></span>
</div>
</div>
</Card>
</div>
</template>
</VersionPage>
</div>
</template>
<script setup>
import { CheckIcon, DownloadIcon, ExternalIcon, FileIcon, ReportIcon } from '@modrinth/assets'
<script setup lang="ts">
import type { Labrinth } from '@modrinth/api-client'
import {
CheckIcon,
ChevronLeftIcon,
DownloadIcon,
ExternalIcon,
MoreVerticalIcon,
ReportIcon,
} from '@modrinth/assets'
import {
Avatar,
Badge,
Breadcrumbs,
ButtonStyled,
Card,
CopyCode,
useFormatBytes,
useFormatDateTime,
commonMessages,
defineMessages,
type DependencyContext,
OverflowMenu,
useVIntl,
VersionPage,
} from '@modrinth/ui'
import { renderString } from '@modrinth/utils'
import { computed, ref, watch } from 'vue'
import { ref, watch } from 'vue'
import { useRoute } from 'vue-router'
import { SwapIcon } from '@/assets/icons'
import { get_project_many, get_version_many } from '@/helpers/cache.js'
import { releaseColor } from '@/helpers/utils'
import { useBreadcrumbs } from '@/store/breadcrumbs'
const formatDateTime = useFormatDateTime({
timeStyle: 'short',
dateStyle: 'long',
})
const formatBytes = useFormatBytes()
const { formatMessage } = useVIntl()
const breadcrumbs = useBreadcrumbs()
const route = useRoute()
const props = defineProps({
project: {
type: Object,
required: true,
},
versions: {
type: Array,
required: true,
},
members: {
type: Array,
required: true,
},
install: {
type: Function,
required: true,
},
installed: {
type: Boolean,
required: true,
const messages = defineMessages({
allVersions: {
id: 'app.project.version.all-versions',
defaultMessage: 'All versions',
},
installing: {
type: Boolean,
required: true,
id: 'app.project.version.installing',
defaultMessage: 'Installing',
},
installedVersion: {
type: String,
required: true,
downloadInBrowser: {
id: 'app.project.version.download-in-browser',
defaultMessage: 'Download in browser',
},
})
const breadcrumbs = useBreadcrumbs()
const route = useRoute()
const props = defineProps<{
project: Labrinth.Projects.v2.Project
versions: Labrinth.Versions.v3.Version[]
members: Labrinth.Projects.v3.TeamMember[]
install: (version: string | null) => void
installed: boolean
installing: boolean
installedVersion: string
}>()
const version = ref(props.versions.find((version) => version.id === route.params.version))
breadcrumbs.setName('Version', version.value.name)
if (version.value) {
breadcrumbs.setName('Version', version.value.name)
}
watch(
() => props.versions,
async () => {
if (route.params.version) {
version.value = props.versions.find((version) => version.id === route.params.version)
await refreshDisplayDependencies()
breadcrumbs.setName('Version', version.value.name)
}
},
)
const enrichment = ref<Labrinth.Projects.v2.DependencyInfo | undefined>(undefined)
const enrichmentLoading = ref(false)
const author = computed(() =>
props.members ? props.members.find((member) => member.user.id === version.value.author_id) : null,
)
const displayDependencies = ref({})
function buildProjectHref(path) {
function buildProjectHref(path: string): string {
const params = new URLSearchParams()
for (const [key, val] of Object.entries(route.query)) {
if (Array.isArray(val)) {
for (const v of val) params.append(key, v)
for (const v of val) {
if (v != null) params.append(key, v)
}
} else if (val) {
params.append(key, String(val))
}
@@ -262,222 +155,65 @@ function buildProjectHref(path) {
return qs ? `${path}?${qs}` : path
}
async function refreshDisplayDependencies() {
const projectIds = new Set()
const versionIds = new Set()
if (version.value.dependencies) {
for (const dependency of version.value.dependencies) {
if (dependency.project_id) {
projectIds.add(dependency.project_id)
}
if (dependency.version_id) {
versionIds.add(dependency.version_id)
}
}
function createDependencyLink(context: DependencyContext): string | undefined {
if (context.version) {
return buildProjectHref(`/project/${context.version.project_id}/version/${context.version.id}`)
}
const [projectDeps, versionDeps] = await Promise.all([
get_project_many([...projectIds]),
get_version_many([...versionIds]),
])
const dependencies = {
projects: projectDeps,
versions: versionDeps,
if (context.project) {
return buildProjectHref(`/project/${context.project.id}`)
}
displayDependencies.value = version.value.dependencies.map((dependency) => {
const version = dependencies.versions.find((obj) => obj.id === dependency.version_id)
if (version) {
const project = dependencies.projects.find(
(obj) => obj.id === version.project_id || obj.id === dependency.project_id,
)
return {
icon: project?.icon_url,
title: project?.title || project?.name,
subtitle: `Version ${version.version_number} is ${dependency.dependency_type}`,
link: buildProjectHref(`/project/${project.slug}/version/${version.id}`),
}
} else {
const project = dependencies.projects.find((obj) => obj.id === dependency.project_id)
if (project) {
return {
icon: project?.icon_url,
title: project?.title || project?.name,
subtitle: `${dependency.dependency_type}`,
link: buildProjectHref(`/project/${project.slug}`),
}
} else {
return {
icon: null,
title: dependency.file_name,
subtitle: `Added via overrides`,
link: null,
}
}
}
})
return undefined
}
await refreshDisplayDependencies()
async function refreshEnrichment() {
if (!version.value) return
const projectIds = new Set<string>()
const versionIds = new Set<string>()
for (const dependency of version.value.dependencies ?? []) {
if (dependency.project_id) {
projectIds.add(dependency.project_id)
}
if (dependency.version_id) {
versionIds.add(dependency.version_id)
}
}
if (projectIds.size === 0 && versionIds.size === 0) {
enrichment.value = { projects: [], versions: [] }
return
}
enrichmentLoading.value = true
try {
const versionResults = versionIds.size > 0 ? await get_version_many([...versionIds]) : []
for (const dependencyVersion of versionResults ?? []) {
if (dependencyVersion.project_id) {
projectIds.add(dependencyVersion.project_id)
}
}
const projectResults = projectIds.size > 0 ? await get_project_many([...projectIds]) : []
enrichment.value = {
projects: projectResults ?? [],
versions: versionResults ?? [],
}
} finally {
enrichmentLoading.value = false
}
}
watch(
() => props.versions,
async () => {
if (route.params.version) {
version.value = props.versions.find((v) => v.id === route.params.version)
if (version.value) {
breadcrumbs.setName('Version', version.value.name)
}
await refreshEnrichment()
}
},
)
await refreshEnrichment()
</script>
<style scoped lang="scss">
.version-container {
display: flex;
flex-direction: row;
gap: 1rem;
}
.version-title {
margin-bottom: 1rem;
h2 {
font-size: var(--font-size-2xl);
font-weight: 700;
color: var(--color-contrast);
margin: 0;
}
}
.dependency {
display: flex;
padding: 0.5rem 1rem 0.5rem 0.5rem;
gap: 0.5rem;
background: var(--color-raised-bg);
color: var(--color-base);
width: 100%;
.title {
font-weight: bolder;
}
:deep(svg) {
margin-right: 0 !important;
}
}
.file {
display: flex;
flex-direction: row;
gap: 0.5rem;
background: var(--color-button-bg);
color: var(--color-base);
padding: 0.5rem 1rem;
.download {
margin-left: auto;
background-color: var(--color-raised-bg);
}
.label {
display: flex;
margin: auto 0 auto;
gap: 0.5rem;
.title {
font-weight: bolder;
word-break: break-all;
}
svg {
min-width: 1.1rem;
min-height: 1.1rem;
width: 1.1rem;
height: 1.1rem;
margin: auto 0;
}
.primary-label {
font-style: italic;
}
}
}
.primary {
background: var(--color-brand-highlight);
color: var(--color-contrast);
}
.button-group {
display: flex;
flex-wrap: wrap;
flex-direction: row;
gap: 0.5rem;
}
.card-title {
font-size: var(--font-size-lg);
color: var(--color-contrast);
margin: 0 0 0.5rem;
}
.description-cards {
width: 100%;
}
.metadata-card {
width: 20rem;
height: min-content;
}
.metadata {
display: flex;
flex-direction: column;
flex-wrap: wrap;
gap: 1rem;
.metadata-item {
display: flex;
flex-direction: column;
gap: 0.5rem;
.metadata-label {
font-weight: bold;
}
}
}
.author {
display: flex;
flex-direction: row;
gap: 0.5rem;
align-items: center;
text-decoration: none;
color: var(--color-base);
background: var(--color-raised-bg);
padding: 0.5rem;
width: 100%;
box-shadow: none;
}
.markdown-body {
:deep(hr),
:deep(h1),
:deep(h2),
img {
max-width: max(60rem, 90%) !important;
}
:deep(ul),
:deep(ol) {
margin-left: 2rem;
}
}
.copycode {
border: 0;
color: var(--color-contrast);
}
.disabled {
display: flex;
flex-direction: row;
vertical-align: center;
align-items: center;
cursor: not-allowed;
border-radius: var(--radius-lg);
.text {
filter: brightness(0.5);
}
}
</style>
@@ -5,16 +5,23 @@
:game-versions="gameVersions"
:versions="versions"
:project="project"
:show-environment-column="themeStore.featureFlags.show_version_environment_column"
:version-link="(version) => buildProjectHref(`/project/${project.id}/version/${version.id}`)"
>
<template #actions="{ version }">
<ButtonStyled circular type="transparent">
<ButtonStyled
circular
type="transparent"
:color="installed && version.id === installedVersion ? 'standard' : 'green'"
>
<button
v-tooltip="`Install`"
:class="{
'group-hover:!bg-brand group-hover:[&>svg]:!text-brand-inverted':
!installed || version.id !== installedVersion,
}"
v-tooltip="
!installed
? formatMessage(commonMessages.installButton)
: version.id !== installedVersion
? formatMessage(commonMessages.switchToVersionButton)
: formatMessage(messages.alreadyInstalled)
"
:disabled="installing || (installed && version.id === installedVersion)"
@click.stop="() => install(version.id)"
>
@@ -26,7 +33,6 @@
<ButtonStyled circular type="transparent">
<OverflowMenu
v-if="false"
class="group-hover:!bg-button-bg"
:options="[
{
id: 'install-elsewhere',
@@ -47,12 +53,13 @@
<DownloadIcon aria-hidden="true" />
Add to another instance
</template>
<template #open-in-browser> <ExternalIcon /> Open in browser </template>
<template #open-in-browser>
<ExternalIcon /> {{ formatMessage(commonMessages.openInBrowserButton) }}
</template>
</OverflowMenu>
<a
v-else
v-tooltip="`Open in browser`"
class="group-hover:!bg-button-bg"
v-tooltip="formatMessage(commonMessages.openInBrowserButton)"
:href="`https://modrinth.com/${project.project_type}/${project.slug}/version/${version.id}`"
target="_blank"
>
@@ -68,15 +75,29 @@
import { CheckIcon, DownloadIcon, ExternalIcon, MoreVerticalIcon } from '@modrinth/assets'
import {
ButtonStyled,
commonMessages,
defineMessages,
injectNotificationManager,
OverflowMenu,
ProjectPageVersions,
useVIntl,
} from '@modrinth/ui'
import { ref } from 'vue'
import { useRoute } from 'vue-router'
import { SwapIcon } from '@/assets/icons/index.js'
import { get_game_versions, get_loaders } from '@/helpers/tags.js'
import { useTheming } from '@/store/theme.ts'
const { formatMessage } = useVIntl()
const themeStore = useTheming()
const messages = defineMessages({
alreadyInstalled: {
id: 'app.project.versions.already-installed',
defaultMessage: 'Already installed',
},
})
defineProps({
project: {
+1
View File
@@ -247,6 +247,7 @@ export default new createRouter({
name: 'Logs',
component: Instance.Logs,
meta: {
renderMode: 'fixed',
useRootContext: true,
breadcrumb: [{ name: '?Instance', link: '/instance/{id}/' }, { name: 'Logs' }],
},
+1
View File
@@ -8,6 +8,7 @@ export const DEFAULT_FEATURE_FLAGS = {
worlds_tab: false,
worlds_in_home: true,
server_project_qa: false,
show_version_environment_column: false,
server_ram_as_bytes_always_on: false,
always_show_app_controls: false,
skip_non_essential_warnings: false,
+6 -1
View File
@@ -414,7 +414,7 @@ components:
- unknown
- signature
example: required-resource-pack
# https://github.com/modrinth/labrinth/blob/master/src/routes/version_creation.rs#L27-L57
# https://github.com/modrinth/code/blob/main/apps/labrinth/src/routes/v2/version_creation.rs#L32-L76
CreatableVersion:
allOf:
- $ref: '#/components/schemas/BaseVersion'
@@ -446,6 +446,11 @@ components:
- client_or_server_prefers_both
- unknown
description: The environment that this version is for.
file_types:
type: object
additionalProperties:
$ref: '#/components/schemas/FileTypeEnum'
description: A map of file parts to their associated file type, a file type is used for additional files such as sources jars.
required:
- file_parts
- project_id
@@ -41,38 +41,38 @@ export const VISIBLE_PROJECT_STATUS_CHANGE_EVENT_STATUS_SET =
export const LIGHT_LEGEND_PALETTE = [
'hsl(152, 100%, 34%)',
'hsl(26, 100%, 42%)',
'hsl(202, 100%, 35%)',
'hsl(327, 45%, 64%)',
'hsl(41, 100%, 45%)',
'hsl(250, 60%, 33%)',
'hsl(170, 43%, 47%)',
'hsl(330, 60%, 33%)',
'hsl(46, 100%, 36%)',
'hsl(167, 100%, 30%)',
'hsl(343, 38%, 45%)',
'hsl(222, 100%, 28%)',
'hsl(270, 62%, 60%)',
'hsl(32, 100%, 37%)',
'hsl(349, 57%, 51%)',
'hsl(191, 43%, 37%)',
'hsl(41, 79%, 46%)',
'hsl(203, 76%, 64%)',
'hsl(0, 93%, 62%)',
'hsl(143, 66%, 29%)',
'hsl(58, 89%, 25%)',
'hsl(311, 64%, 49%)',
'hsl(198, 91%, 32%)',
'hsl(12, 88%, 27%)',
'hsl(236, 61%, 60%)',
'hsl(102, 59%, 74%)',
'hsl(293, 76%, 79%)',
'hsl(67, 99%, 41%)',
'hsl(179, 100%, 50%)',
'hsl(102, 100%, 61%)',
'hsl(0, 100%, 32%)',
]
export const DARK_LEGEND_PALETTE = [
'hsl(145, 78%, 48%)',
'hsl(41, 100%, 50%)',
'hsl(202, 77%, 63%)',
'hsl(323, 66%, 72%)',
'hsl(56, 85%, 60%)',
'hsl(255, 92%, 80%)',
'hsl(12, 100%, 67%)',
'hsl(176, 58%, 56%)',
'hsl(60, 100%, 41%)',
'hsl(165, 80%, 38%)',
'hsl(341, 36%, 56%)',
'hsl(226, 60%, 49%)',
'hsl(252, 53%, 62%)',
'hsl(75, 59%, 50%)',
'hsl(195, 56%, 42%)',
'hsl(30, 59%, 56%)',
'hsl(41, 79%, 46%)',
'hsl(203, 76%, 64%)',
'hsl(0, 93%, 62%)',
'hsl(143, 66%, 29%)',
'hsl(58, 94%, 45%)',
'hsl(311, 64%, 49%)',
'hsl(198, 91%, 32%)',
'hsl(12, 88%, 27%)',
'hsl(236, 61%, 60%)',
'hsl(102, 59%, 74%)',
'hsl(293, 76%, 79%)',
'hsl(61, 92%, 33%)',
'hsl(179, 100%, 50%)',
'hsl(102, 100%, 61%)',
'hsl(0, 100%, 32%)',
]
@@ -288,6 +288,7 @@ type PaletteRankEntry = {
key: string
label: string
total: number
excludedFromRank?: boolean
}
function formatDatasetTooltip(projectName: string | undefined): string | undefined {
@@ -330,9 +331,12 @@ function buildPaletteColorsByDownloadRank(
const colorsByKey = new Map<string, string>()
if (palette.length === 0) return colorsByKey
const sortedEntries = [...entries].sort(
(a, b) => b.total - a.total || a.label.localeCompare(b.label) || a.key.localeCompare(b.key),
)
const compareEntries = (a: PaletteRankEntry, b: PaletteRankEntry) =>
b.total - a.total || a.label.localeCompare(b.label) || a.key.localeCompare(b.key)
const rankedEntries = entries.filter((entry) => !entry.excludedFromRank).sort(compareEntries)
const excludedEntries = entries.filter((entry) => entry.excludedFromRank).sort(compareEntries)
const sortedEntries = [...rankedEntries, ...excludedEntries]
sortedEntries.forEach((entry, index) => {
colorsByKey.set(entry.key, getPaletteColorForIndex(index, palette))
})
@@ -340,6 +344,27 @@ function buildPaletteColorsByDownloadRank(
return colorsByKey
}
function isExcludedFromPaletteRank(breakdownValues: readonly string[]): boolean {
return breakdownValues.some(
(value) =>
isUnknownAnalyticsBreakdownValue(value) || isNoDependentAnalyticsBreakdownValue(value),
)
}
function buildPaletteRankEntry(
key: string,
breakdownValues: readonly string[],
total: number,
formatLabel: (breakdownValues: readonly string[]) => string,
): PaletteRankEntry {
return {
key,
label: formatLabel(breakdownValues),
total,
excludedFromRank: isExcludedFromPaletteRank(breakdownValues),
}
}
export function getMetricValue(
point: Labrinth.Analytics.v3.ProjectAnalytics,
activeStat: AnalyticsDashboardStat,
@@ -499,11 +524,14 @@ export function buildChartDatasets(
})
const colorsByBreakdown = buildPaletteColorsByDownloadRank(
Array.from(dataByBreakdown.keys()).map((breakdownKey) => ({
key: breakdownKey,
label: formatChartBreakdownLabels(breakdownValuesByKey.get(breakdownKey) ?? []),
total: downloadTotalsByBreakdown.get(breakdownKey) ?? 0,
})),
Array.from(dataByBreakdown.keys()).map((breakdownKey) =>
buildPaletteRankEntry(
breakdownKey,
breakdownValuesByKey.get(breakdownKey) ?? [],
downloadTotalsByBreakdown.get(breakdownKey) ?? 0,
formatChartBreakdownLabels,
),
),
palette,
)
@@ -538,7 +566,7 @@ export function buildChartDatasets(
? isNoDependentAnalyticsBreakdownValue(dependentProjectId)
? formatMessage(analyticsMessages.noDependentTooltip)
: isUnknownAnalyticsBreakdownValue(dependentProjectId)
? formatMessage(analyticsMessages.unknown)
? formatMessage(analyticsMessages.unknownDependentTooltip)
: formatDependentProjectDatasetTooltip(
versionName,
dependentProjectName,
@@ -675,11 +703,14 @@ export function buildChartDatasets(
})
const colorsByBreakdown = buildPaletteColorsByDownloadRank(
Array.from(dataByProjectBreakdown.keys()).map((breakdownKey) => ({
key: breakdownKey,
label: formatChartBreakdownLabels(breakdownValuesByKey.get(breakdownKey) ?? []),
total: downloadTotalsByProjectBreakdown.get(breakdownKey) ?? 0,
})),
Array.from(dataByProjectBreakdown.keys()).map((breakdownKey) =>
buildPaletteRankEntry(
breakdownKey,
breakdownValuesByKey.get(breakdownKey) ?? [],
downloadTotalsByProjectBreakdown.get(breakdownKey) ?? 0,
formatChartBreakdownLabels,
),
),
palette,
)
@@ -92,6 +92,11 @@ export const analyticsMessages = defineMessages({
id: 'analytics.value.no-dependent-tooltip',
defaultMessage: 'Downloaded for reasons other than being a dependency',
},
unknownDependentTooltip: {
id: 'analytics.value.unknown-dependent-tooltip',
defaultMessage:
"There's no metadata to determine which dependent project this download attributes to.",
},
other: {
id: 'analytics.value.other',
defaultMessage: 'Other',
@@ -515,7 +515,7 @@ function getDependentProjectTooltip(row: AnalyticsTableRow) {
return formatMessage(analyticsMessages.noDependentTooltip)
}
if (isUnknownAnalyticsBreakdownValue(row.breakdownValues.dependent_project_download)) {
return formatMessage(analyticsMessages.unknown)
return formatMessage(analyticsMessages.unknownDependentTooltip)
}
const dependencyProjectIds = new Set(row.dependentOnProjectIds)
@@ -0,0 +1,494 @@
<template>
<div v-if="downloadRows.length > 0" class="flex flex-col gap-1">
<div v-if="showTitle" class="flex flex-wrap items-center justify-between gap-2">
<h3 class="m-0 flex items-center gap-1.5 text-base font-semibold text-contrast">
{{ sectionTitle }}
<InfoIcon
v-if="duplicateDependencyRowsHidden"
v-tooltip="formatMessage(messages.duplicateDependenciesHidden)"
aria-hidden="true"
class="size-4 text-secondary"
/>
</h3>
</div>
<div class="flex flex-col gap-2">
<DownloadDependency
v-for="dependency in downloadRows"
:key="dependency.key"
:dependency="dependency"
@download="emit('download')"
/>
</div>
</div>
</template>
<script setup lang="ts">
import type { Labrinth } from '@modrinth/api-client'
import { FileIcon, InfoIcon } from '@modrinth/assets'
import {
type CdnDownloadReason,
defineMessages,
fileTypeMessages,
injectModrinthClient,
useVIntl,
} from '@modrinth/ui'
import type { DisplayProjectType } from '@modrinth/utils'
import { useQuery } from '@tanstack/vue-query'
import { type Component, computed, watch } from 'vue'
import DownloadDependency from './DownloadDependency.vue'
defineOptions({
name: 'DownloadDependencies',
})
type DownloadModalProject = Omit<Labrinth.Projects.v2.Project, 'project_type'> & {
project_type: DisplayProjectType
actualProjectType: Labrinth.Projects.v2.ProjectType
}
type ResolvedContent = Labrinth.Content.v3.ResolvedContent | Labrinth.Content.v3.SkippedContent
interface DownloadDependencyRow {
key: string
name: string
icon?: string
fallbackIcon?: Component
projectHref?: string
downloadHref?: string
filename?: string
fileSize?: number
typeLabel: string
unavailableTooltip: string
dependencies: DownloadDependencyRow[]
}
interface DownloadableDependencyFile {
href: string
filename: string
name: string
}
const props = withDefaults(
defineProps<{
dependencies?: DownloadDependencyRow[] | null
project?: DownloadModalProject | null
selectedVersion?: Labrinth.Versions.v3.Version | null
currentGameVersion?: string | null
currentPlatform?: string | null
downloadReason?: CdnDownloadReason
additionalFiles?: Labrinth.Versions.v3.VersionFile[]
showTitle?: boolean
}>(),
{
dependencies: null,
project: null,
selectedVersion: null,
currentGameVersion: null,
currentPlatform: null,
downloadReason: 'standalone',
additionalFiles: () => [],
showTitle: true,
},
)
const emit = defineEmits<{
download: []
'update:downloadable-files': [files: DownloadableDependencyFile[]]
}>()
const client = injectModrinthClient()
const { createProjectDownloadUrl } = useCdnDownloadContext()
const { formatMessage } = useVIntl()
const shouldResolveDependencies = computed(
() => !props.dependencies && !!props.project && !!props.selectedVersion,
)
const dependencyResolutionPreferences = computed<Labrinth.Content.v3.ResolutionPreferences>(() => ({
game_versions: props.selectedVersion?.game_versions || [],
loaders: props.currentPlatform ? [props.currentPlatform] : props.selectedVersion?.loaders || [],
}))
const { data: dependencyResolution } = useQuery({
queryKey: computed(() => [
'project-download-modal',
'content-resolve',
props.project?.id,
props.selectedVersion?.id,
props.project?.project_type,
dependencyResolutionPreferences.value,
]),
queryFn: () =>
client.labrinth.content_v3.resolve({
project_id: props.project!.id,
version_id: props.selectedVersion!.id,
content_type: resolveContentType(props.project!.project_type),
selected: dependencyResolutionPreferences.value,
target: dependencyResolutionPreferences.value,
}),
enabled: shouldResolveDependencies,
})
const visibleResolvedDependencies = computed<ResolvedContent[]>(() => {
return [
...(dependencyResolution.value?.dependencies || []),
...(dependencyResolution.value?.skipped || []),
].filter(shouldShowDependency)
})
const dependencyVersionIds = computed<string[]>(() => {
return [
...new Set(
visibleResolvedDependencies.value
.filter((dependency) => !('reason' in dependency))
.map((dependency) => dependency.version_id)
.filter((versionId): versionId is string => !!versionId),
),
]
})
const { data: dependencyVersions } = useQuery({
queryKey: computed(() => [
'project-download-modal',
'resolved-versions',
dependencyVersionIds.value,
]),
queryFn: () => client.labrinth.versions_v3.getVersions(dependencyVersionIds.value),
enabled: computed(() => shouldResolveDependencies.value && dependencyVersionIds.value.length > 0),
})
const dependencyVersionById = computed(() => {
const map = new Map<string, Labrinth.Versions.v3.Version>()
for (const version of dependencyVersions.value || []) {
if (!version) continue
map.set(version.id, version)
}
return map
})
const dependencyProjectIds = computed<string[]>(() => {
return [
...new Set(
visibleResolvedDependencies.value
.map((dependency) => dependency.project_id)
.filter((projectId): projectId is string => !!projectId),
),
]
})
const { data: dependencyProjects } = useQuery({
queryKey: computed(() => [
'project-download-modal',
'resolved-projects',
dependencyProjectIds.value,
]),
queryFn: () => client.labrinth.projects_v2.getMultiple(dependencyProjectIds.value),
enabled: computed(() => shouldResolveDependencies.value && dependencyProjectIds.value.length > 0),
})
const dependencyProjectById = computed(() => {
const map = new Map<string, Labrinth.Projects.v2.Project>()
for (const project of dependencyProjects.value || []) {
map.set(project.id, project)
}
return map
})
const dependenciesByParentVersionId = computed(() => {
const map = new Map<string, ResolvedContent[]>()
for (const dependency of visibleResolvedDependencies.value) {
if (!dependency.dependent_on_version_id) continue
const dependencies = map.get(dependency.dependent_on_version_id) || []
dependencies.push(dependency)
map.set(dependency.dependent_on_version_id, dependencies)
}
return map
})
const dependenciesLoaded = computed(() => {
if (!shouldResolveDependencies.value) return false
if (!dependencyResolution.value) return false
if (
dependencyResolution.value.primary.version_id &&
dependencyResolution.value.primary.version_id !== props.selectedVersion?.id
) {
return false
}
if (
!dependencyVersionIds.value.every((versionId) => dependencyVersionById.value.has(versionId))
) {
return false
}
if (
!dependencyProjectIds.value.every((projectId) => dependencyProjectById.value.has(projectId))
) {
return false
}
return true
})
const resolvedDependencyRows = computed<DownloadDependencyRow[]>(() => {
if (!dependenciesLoaded.value) return []
const primaryVersionId =
dependencyResolution.value?.primary.version_id || props.selectedVersion?.id
if (!primaryVersionId) return []
const dependencies = dependenciesByParentVersionId.value.get(primaryVersionId) || []
return dependencies.flatMap((dependency) => {
const row = createDependencyRow(dependency)
return row ? [row] : []
})
})
const dependencyRows = computed<DownloadDependencyRow[]>(
() => props.dependencies || resolvedDependencyRows.value,
)
const visibleDependencyRows = computed<DownloadDependencyRow[]>(() =>
dedupeDependencyRows(dependencyRows.value),
)
const duplicateDependencyRowsHidden = computed(() =>
hasDuplicateDependencyRows(dependencyRows.value),
)
const additionalFileRows = computed<DownloadDependencyRow[]>(() =>
props.additionalFiles.map((file) => ({
key: `additional-file-${additionalFileKey(file)}`,
name: file.filename,
fallbackIcon: FileIcon,
downloadHref: getDownloadUrl(file.url),
filename: file.filename,
fileSize: file.size,
typeLabel: fileTypeLabel(file.file_type),
unavailableTooltip: formatMessage(messages.unavailableFile),
dependencies: [],
})),
)
const downloadRows = computed<DownloadDependencyRow[]>(() => [
...visibleDependencyRows.value,
...additionalFileRows.value,
])
const sectionTitle = computed(() =>
formatMessage(
visibleDependencyRows.value.length > 0
? messages.dependenciesTitle
: messages.additionalFilesTitle,
),
)
const downloadableDependencyFiles = computed<DownloadableDependencyFile[]>(() =>
collectDownloadableDependencyFiles(visibleDependencyRows.value),
)
watch(
downloadableDependencyFiles,
(files) => {
emit('update:downloadable-files', files)
},
{ immediate: true },
)
function primaryFileForVersion(version?: Labrinth.Versions.v3.Version) {
return version?.files?.find((file) => file.primary) || version?.files?.[0]
}
function shouldShowDependency(dependency: ResolvedContent) {
return !(
'reason' in dependency && ['duplicate_project', 'quilt_fabric_api'].includes(dependency.reason)
)
}
function createDependencyRow(dependency: ResolvedContent): DownloadDependencyRow | null {
const versionId = dependency.version_id ?? undefined
const version = versionId ? dependencyVersionById.value.get(versionId) : undefined
const project = dependencyProjectById.value.get(dependency.project_id)
if (!project) return null
const primaryFile = primaryFileForVersion(version)
const unavailableTooltip =
'reason' in dependency && dependency.reason
? skippedReasonLabel(dependency.reason)
: formatMessage(messages.unavailableDependency)
const name = project.title
return {
key: `${dependency.project_id}-${versionId ?? 'unresolved'}-${
'reason' in dependency ? dependency.reason : 'resolved'
}`,
name,
icon: project.icon_url ?? undefined,
projectHref: `/${project.project_type}/${project.slug || project.id}`,
downloadHref:
'reason' in dependency || !primaryFile ? undefined : getDownloadUrl(primaryFile.url),
filename: primaryFile?.filename,
fileSize: primaryFile?.size,
typeLabel: 'Required',
unavailableTooltip,
dependencies: (versionId && dependenciesByParentVersionId.value.get(versionId)
? dependenciesByParentVersionId.value.get(versionId)!
: []
).flatMap((subDependency) => {
const row = createDependencyRow(subDependency)
return row ? [row] : []
}),
}
}
function skippedReasonLabel(reason: Labrinth.Content.v3.SkippedContent['reason']) {
return (
{
already_installed: formatMessage(messages.alreadyInstalledDependency),
duplicate_project: formatMessage(messages.duplicateDependency),
conflicting_dependency: formatMessage(messages.conflictingDependency),
no_compatible_version: formatMessage(messages.noCompatibleDependency),
missing_version: formatMessage(messages.missingDependencyVersion),
quilt_fabric_api: formatMessage(messages.quiltFabricApiDependency),
}[reason] || formatMessage(messages.unavailableDependency)
)
}
function resolveContentType(projectType: DisplayProjectType): Labrinth.Content.v3.ContentType {
return ['mod', 'plugin', 'datapack', 'resourcepack', 'shader', 'modpack'].includes(projectType)
? (projectType as Labrinth.Content.v3.ContentType)
: 'mod'
}
function getDownloadUrl(url: string) {
return createProjectDownloadUrl(url, {
reason: props.downloadReason,
gameVersion: props.currentGameVersion ?? undefined,
loader: props.currentPlatform ?? undefined,
})
}
function fileTypeLabel(type?: Labrinth.Versions.v3.FileType | null) {
return formatMessage(fileTypeMessages[type ?? 'unknown'] ?? fileTypeMessages.unknown)
}
function additionalFileKey(file: Labrinth.Versions.v3.VersionFile) {
return file.hashes?.sha1 ?? file.filename
}
function dedupeDependencyRows(
rows: DownloadDependencyRow[],
seenDependencies = new Set<string>(),
): DownloadDependencyRow[] {
return rows.flatMap((row) => {
const identity = dependencyRowIdentity(row)
if (seenDependencies.has(identity)) return []
seenDependencies.add(identity)
return [
{
...row,
dependencies: dedupeDependencyRows(row.dependencies, seenDependencies),
},
]
})
}
function dependencyRowIdentity(row: DownloadDependencyRow) {
return row.projectHref ?? row.downloadHref ?? row.key
}
function hasDuplicateDependencyRows(
rows: DownloadDependencyRow[],
seenDependencies = new Set<string>(),
): boolean {
for (const row of rows) {
const rowId = dependencyRowIdentity(row)
if (seenDependencies.has(rowId)) return true
seenDependencies.add(rowId)
if (hasDuplicateDependencyRows(row.dependencies, seenDependencies)) return true
}
return false
}
function collectDownloadableDependencyFiles(
rows: DownloadDependencyRow[],
seenHrefs = new Set<string>(),
): DownloadableDependencyFile[] {
const files: DownloadableDependencyFile[] = []
for (const row of rows) {
if (row.downloadHref && !seenHrefs.has(row.downloadHref)) {
seenHrefs.add(row.downloadHref)
files.push({
href: row.downloadHref,
filename: row.filename || filenameFromUrl(row.downloadHref),
name: row.name,
})
}
files.push(...collectDownloadableDependencyFiles(row.dependencies, seenHrefs))
}
return files
}
function filenameFromUrl(url: string) {
try {
const filename = new URL(url).pathname.split('/').pop()
return filename ? decodeURIComponent(filename) : 'dependency.jar'
} catch {
return 'dependency.jar'
}
}
const messages = defineMessages({
dependenciesTitle: {
id: 'project.download.dependencies-title',
defaultMessage: 'Dependencies',
},
duplicateDependenciesHidden: {
id: 'project.download.duplicate-dependencies-hidden',
defaultMessage: 'Duplicate dependencies are hidden',
},
additionalFilesTitle: {
id: 'project.download.additional-files-title',
defaultMessage: 'Additional files',
},
alreadyInstalledDependency: {
id: 'project.download.dependency-already-installed',
defaultMessage: 'This dependency is already installed',
},
conflictingDependency: {
id: 'project.download.dependency-conflicting',
defaultMessage: 'This dependency conflicts with another dependency',
},
duplicateDependency: {
id: 'project.download.dependency-duplicate',
defaultMessage: 'This dependency is already included',
},
missingDependencyVersion: {
id: 'project.download.dependency-missing-version',
defaultMessage: 'This dependency version is unavailable',
},
noCompatibleDependency: {
id: 'project.download.dependency-no-compatible-version',
defaultMessage: 'No compatible version is available for this dependency',
},
quiltFabricApiDependency: {
id: 'project.download.dependency-quilt-fabric-api',
defaultMessage: 'Fabric API is skipped for Quilt',
},
unavailableDependency: {
id: 'project.download.dependency-unavailable',
defaultMessage: 'This dependency cannot be downloaded',
},
unavailableFile: {
id: 'project.download.file-unavailable',
defaultMessage: 'This file cannot be downloaded',
},
})
</script>
@@ -0,0 +1,149 @@
<template>
<div class="flex min-w-0 flex-col gap-2">
<div
class="grid min-h-10 grid-cols-[minmax(0,1fr)_min-content] items-center gap-3 rounded-xl bg-button-bg py-0 pl-3.5 pr-2 text-primary"
>
<span class="flex min-w-0 items-center gap-3">
<Avatar
v-if="dependency.icon"
:src="dependency.icon"
:alt="dependency.name"
size="24px"
class="!rounded-lg !shadow-none"
/>
<span
v-else
class="flex size-4 flex-shrink-0 items-center justify-center rounded-lg border border-solid border-surface-5 text-secondary"
>
<component
:is="dependency.fallbackIcon ?? PackageIcon"
aria-hidden="true"
class="size-5"
/>
</span>
<a
v-if="dependency.projectHref"
ref="dependencyNameRef"
v-tooltip="truncatedTooltip(dependencyNameRef, dependency.name)"
:href="dependency.projectHref"
target="_blank"
rel="noopener noreferrer"
class="min-w-0 truncate text-base font-semibold text-contrast no-underline hover:underline"
>
{{ dependency.name }}
</a>
<span
v-else
ref="dependencyNameRef"
v-tooltip="truncatedTooltip(dependencyNameRef, dependency.name)"
class="min-w-0 truncate text-base font-semibold text-contrast"
>
{{ dependency.name }}
</span>
<TagItem class="shrink-0 border !border-solid border-surface-5 !px-3 !py-1 text-base">
{{ dependency.typeLabel }}
</TagItem>
</span>
<ButtonStyled v-if="dependency.downloadHref" circular type="transparent">
<a
v-tooltip="downloadTooltip"
:href="dependency.downloadHref"
:download="dependency.filename"
:aria-label="downloadTooltip"
@click="emit('download')"
>
<DownloadIcon aria-hidden="true" class="size-6 text-secondary" />
</a>
</ButtonStyled>
<ButtonStyled v-else circular type="transparent">
<button
v-tooltip="dependency.unavailableTooltip"
disabled
:aria-label="dependency.unavailableTooltip"
>
<DownloadIcon aria-hidden="true" class="size-6 text-secondary" />
</button>
</ButtonStyled>
</div>
<div
v-for="childDependency in dependency.dependencies"
:key="childDependency.key"
class="group/dependency relative pl-10"
>
<DownloadDependency :dependency="childDependency" class="z-1" @download="emit('download')" />
<div
aria-hidden="true"
class="absolute -top-2 left-6 z-0 h-[calc(100%+1rem)] w-0.5 bg-surface-5 group-first/dependency:-top-2 group-first/dependency:h-20 group-last/dependency:h-7"
/>
<div aria-hidden="true" class="absolute left-6 top-5 z-0 h-0.5 w-4 bg-surface-5" />
</div>
</div>
</template>
<script setup lang="ts">
import { DownloadIcon, PackageIcon } from '@modrinth/assets'
import {
Avatar,
ButtonStyled,
defineMessages,
TagItem,
truncatedTooltip,
useFormatBytes,
useVIntl,
} from '@modrinth/ui'
import { type Component, computed, ref } from 'vue'
defineOptions({
name: 'DownloadDependency',
})
interface DownloadDependencyRow {
key: string
name: string
icon?: string
fallbackIcon?: Component
projectHref?: string
downloadHref?: string
filename?: string
fileSize?: number
typeLabel: string
unavailableTooltip: string
dependencies: DownloadDependencyRow[]
}
const props = defineProps<{
dependency: DownloadDependencyRow
}>()
const emit = defineEmits<{
download: []
}>()
const { formatMessage } = useVIntl()
const formatBytes = useFormatBytes()
const dependencyNameRef = ref<HTMLElement | null>(null)
const downloadTooltip = computed(() => {
const filename = props.dependency.filename || props.dependency.name
if (typeof props.dependency.fileSize === 'number') {
return formatMessage(messages.downloadFileWithSize, {
filename,
size: formatBytes(props.dependency.fileSize, 1),
})
}
return formatMessage(messages.downloadFile, { filename })
})
const messages = defineMessages({
downloadFile: {
id: 'project.download.dependency-download-file',
defaultMessage: 'Download {filename}',
},
downloadFileWithSize: {
id: 'project.download.dependency-download-file-with-size',
defaultMessage: 'Download {filename} ({size})',
},
})
</script>
@@ -0,0 +1,766 @@
<template>
<div class="flex w-full gap-2 max-sm:flex-wrap">
<Combobox
:model-value="currentGameVersion || undefined"
class="w-full"
:options="gameVersionOptions"
:placeholder="formatMessage(messages.selectGameVersion)"
:searchable="project.game_versions.length > 4"
search-autocomplete="off"
:search-placeholder="formatMessage(messages.searchGameVersions)"
:no-options-message="formatMessage(messages.noGameVersionsFound)"
trigger-class="!rounded-xl !bg-button-bg !px-3 !py-2"
dropdown-class="!rounded-xl"
select-search-text-on-focus
@update:model-value="selectGameVersion"
@search-input="versionFilter = $event"
@close="versionFilter = ''"
>
<template #option="{ item, isSelected }">
<div
v-tooltip="gameVersionOptionTooltip(item.value)"
class="flex w-full items-center justify-between gap-2 px-4 py-2"
:class="{
'text-brand-red opacity-40': isGameVersionUnavailable(item.value),
'text-green': isSelected,
'!opacity-100': isSelected,
'text-primary': !isGameVersionUnavailable(item.value) && !isSelected,
}"
>
<span class="min-w-0 truncate font-semibold leading-tight">{{ item.label }}</span>
<TriangleAlertIcon
v-if="isSelected && isGameVersionUnavailable(item.value)"
aria-hidden="true"
class="size-5 shrink-0 text-orange"
/>
</div>
</template>
<template #dropdown-footer>
<div
v-if="showVersionsCheckbox"
class="border-0 border-t border-solid border-surface-5 p-3"
>
<Checkbox
v-model="showAllVersionsModel"
:label="formatMessage(messages.showAllVersions)"
:disabled="!!versionFilter"
/>
</div>
</template>
</Combobox>
<Combobox
v-if="project.project_type !== 'resourcepack'"
:model-value="currentPlatform || undefined"
class="w-full"
:options="platformOptions"
:placeholder="formatMessage(messages.selectPlatform)"
trigger-class="!rounded-xl !bg-button-bg !px-3 !py-2"
dropdown-class="!rounded-xl"
@update:model-value="selectPlatform"
>
<template #option="{ item, isSelected }">
<div
v-tooltip="platformOptionTooltip(item.value, item.label)"
class="flex w-full items-center justify-between gap-2 px-4 py-2"
:class="{
'text-brand-red opacity-40': isPlatformUnavailable(item.value),
'text-green': isSelected,
'!opacity-100': isSelected,
'text-primary': !isPlatformUnavailable(item.value) && !isSelected,
}"
>
<span class="min-w-0 truncate font-semibold leading-tight">{{ item.label }}</span>
<TriangleAlertIcon
v-if="isSelected && isPlatformUnavailable(item.value)"
aria-hidden="true"
class="size-5 shrink-0 text-orange"
/>
</div>
</template>
</Combobox>
</div>
<div v-if="selectedVersion" class="flex flex-col gap-1">
<div class="flex flex-wrap items-center justify-between gap-2">
<h3 class="relative top-0.5 m-0 text-base font-semibold text-contrast">
{{ formatMessage(messages.compatibleVersionTitle) }}
</h3>
<ButtonStyled v-if="downloadAllFiles.length > 1" type="transparent">
<button :disabled="downloadingSelectedVersion" @click="downloadSelectedVersionFiles">
<SpinnerIcon v-if="downloadingSelectedVersion" aria-hidden="true" class="animate-spin" />
<DownloadIcon v-else aria-hidden="true" />
{{
formatMessage(
downloadingSelectedVersion
? messages.downloadingSelectedVersion
: messages.downloadAllSelectedVersion,
{
current: selectedVersionDownloadProgress.current,
total: selectedVersionDownloadProgress.total,
},
)
}}
</button>
</ButtonStyled>
</div>
<div
class="grid grid-cols-[1fr_min-content] items-center gap-3 rounded-2xl bg-surface-2 px-3 py-3"
>
<div class="flex min-w-0 flex-col gap-1">
<div class="flex min-w-0 items-center gap-2">
<nuxt-link
v-tooltip="truncatedTooltip(versionNumberRef, selectedVersion.version_number)"
:to="`/${project.project_type}/${project.slug || project.id}/version/${selectedVersion.id}`"
target="_blank"
rel="noopener noreferrer"
class="block min-w-0 text-contrast no-underline hover:underline"
>
<span ref="versionNumberRef" class="block truncate font-semibold">
{{ selectedVersion.version_number }}
</span>
</nuxt-link>
<VersionChannelTag
:channel="selectedVersion.version_type"
class="relative -top-px !py-0.5"
/>
</div>
<p
ref="versionNameRef"
v-tooltip="truncatedTooltip(versionNameRef, selectedVersion.name)"
class="m-0 w-fit max-w-full truncate text-sm text-secondary"
>
{{ selectedVersion.name }}
</p>
</div>
<ButtonStyled v-if="selectedPrimaryFile" color="brand" circular>
<a
v-tooltip="'Download'"
:href="selectedPrimaryFileDownloadUrl"
:download="selectedPrimaryFile.filename"
:aria-label="
formatMessage(messages.downloadVersion, {
version: selectedVersion.version_number,
})
"
@click="emit('download')"
>
<DownloadIcon aria-hidden="true" />
</a>
</ButtonStyled>
</div>
</div>
<p v-else-if="currentPlatform && currentGameVersion && versions.length > 0">
{{
formatMessage(messages.noVersionsAvailable, {
gameVersion: currentGameVersion,
platform: currentPlatformText,
})
}}
</p>
</template>
<script setup lang="ts">
import type { Labrinth } from '@modrinth/api-client'
import { DownloadIcon, SpinnerIcon, TriangleAlertIcon } from '@modrinth/assets'
import {
ButtonStyled,
type CdnDownloadReason,
Checkbox,
Combobox,
type ComboboxOption,
defineMessages,
getTagMessage,
injectNotificationManager,
truncatedTooltip,
useDebugLogger,
useVIntl,
} from '@modrinth/ui'
import VersionChannelTag from '@modrinth/ui/src/components/version/VersionChannelTag.vue'
import type { DisplayProjectType } from '@modrinth/utils'
import dayjs from 'dayjs'
import JSZip from 'jszip'
import { computed, ref, watch } from 'vue'
defineOptions({
name: 'DownloadProject',
})
type DownloadModalProject = Omit<Labrinth.Projects.v2.Project, 'project_type'> & {
project_type: DisplayProjectType
actualProjectType: Labrinth.Projects.v2.ProjectType
}
type ProjectDownloadSelection = {
currentGameVersion: string | null
currentPlatform: string | null
selectedVersion: Labrinth.Versions.v3.Version | null
selectedPrimaryFile: Labrinth.Versions.v3.VersionFile | null
}
type DownloadableFile = {
href: string
filename: string
}
const props = withDefaults(
defineProps<{
project: DownloadModalProject
versions?: Labrinth.Versions.v3.Version[]
dependencyDownloadFiles?: DownloadableFile[]
downloadReason?: CdnDownloadReason
initialGameVersion?: string | null
initialPlatform?: string | null
incompatibleGameVersions?: string[]
incompatibleLoaders?: string[]
resetKey?: number
}>(),
{
versions: () => [],
dependencyDownloadFiles: () => [],
downloadReason: 'standalone',
initialGameVersion: null,
initialPlatform: null,
incompatibleGameVersions: () => [],
incompatibleLoaders: () => [],
resetKey: 0,
},
)
const emit = defineEmits<{
download: []
selectGameVersion: [gameVersion: string]
selectPlatform: [platform: string]
'update:selection': [selection: ProjectDownloadSelection]
}>()
const { formatMessage } = useVIntl()
const { createProjectDownloadUrl } = useCdnDownloadContext()
const { addNotification } = injectNotificationManager()
const debug = useDebugLogger('DownloadProject')
const tags = useGeneratedState()
const userSelectedGameVersion = ref<string | null>(props.initialGameVersion)
const userSelectedPlatform = ref<string | null>(props.initialPlatform)
const showAllVersions = ref(defaultShowAllVersions())
const versionFilter = ref('')
const versionNumberRef = ref<HTMLElement | null>(null)
const versionNameRef = ref<HTMLElement | null>(null)
const downloadingSelectedVersion = ref(false)
const selectedVersionDownloadProgress = ref({
current: 0,
total: 0,
})
const incompatibleGameVersionsSet = computed(() => new Set(props.incompatibleGameVersions))
const incompatibleLoadersSet = computed(() => new Set(props.incompatibleLoaders))
const showAllVersionsModel = computed({
get() {
return showAllVersions.value
},
set(value) {
showAllVersions.value = value
},
})
const selectedPlatform = computed<string | null>(() => {
if (userSelectedPlatform.value) return userSelectedPlatform.value
return props.project.loaders.length === 1 ? props.project.loaders[0] : null
})
const selectedGameVersion = computed<string | null>(() => {
if (userSelectedGameVersion.value) return userSelectedGameVersion.value
return props.project.game_versions.length === 1 ? props.project.game_versions[0] : null
})
const compatiblePlatforms = computed<string[]>(() => {
return props.project.loaders.filter(
(platform) =>
props.versions.some(
(version) =>
version.loaders.includes(platform) &&
(!selectedGameVersion.value || version.game_versions.includes(selectedGameVersion.value)),
) && !incompatibleLoadersSet.value.has(platform),
)
})
const currentPlatform = computed<string | null>(() => {
if (selectedPlatform.value) return selectedPlatform.value
return compatiblePlatforms.value.length === 1 ? compatiblePlatforms.value[0] : null
})
const possibleGameVersions = computed<string[]>(() => {
return props.versions
.filter((x) => !currentPlatform.value || x.loaders.includes(currentPlatform.value))
.flatMap((x) => x.game_versions)
})
const compatibleGameVersions = computed<string[]>(() => {
return props.project.game_versions.filter(
(gameVersion) =>
possibleGameVersions.value.includes(gameVersion) &&
!incompatibleGameVersionsSet.value.has(gameVersion),
)
})
const currentGameVersion = computed<string | null>(() => {
if (selectedGameVersion.value) return selectedGameVersion.value
return compatibleGameVersions.value.length === 1 ? compatibleGameVersions.value[0] : null
})
const possiblePlatforms = computed<string[]>(() => {
return props.versions
.filter((x) => !currentGameVersion.value || x.game_versions.includes(currentGameVersion.value))
.flatMap((x) => x.loaders)
})
const currentPlatformText = computed(() => {
if (!currentPlatform.value) return ''
return loaderLabel(currentPlatform.value)
})
const releaseVersions = computed<Set<string>>(() => {
const set = new Set<string>()
for (const gameVersion of tags.value.gameVersions || []) {
if (gameVersion?.version && gameVersion.version_type === 'release') {
set.add(gameVersion.version)
}
}
return set
})
const nonReleaseVersions = computed<Set<string>>(() => {
const set = new Set<string>()
for (const gameVersion of tags.value.gameVersions || []) {
if (gameVersion?.version && gameVersion.version_type !== 'release') {
set.add(gameVersion.version)
}
}
return set
})
const showVersionsCheckbox = computed(() => {
let hasRelease = false
let hasNonRelease = false
for (const version of props.project.game_versions) {
if (isReleaseGameVersion(version)) {
hasRelease = true
} else {
hasNonRelease = true
}
if (hasRelease && hasNonRelease) return true
}
return false
})
const filteredGameVersions = computed(() => {
return props.project.game_versions
.filter(
(x) =>
(versionFilter.value && x.includes(versionFilter.value)) ||
(!versionFilter.value && (showAllVersions.value || isReleaseGameVersion(x))),
)
.slice()
.reverse()
})
const gameVersionOptions = computed<ComboboxOption<string>[]>(() => {
return filteredGameVersions.value.map((gameVersion) => ({
value: gameVersion,
label: gameVersion,
class: '!px-0 !py-1',
}))
})
const platformOptions = computed<ComboboxOption<string>[]>(() => {
return props.project.loaders
.slice()
.reverse()
.map((platform) => ({
value: platform,
label: loaderLabel(platform),
class: '!px-0 !py-1',
}))
})
const filteredVersions = computed<Labrinth.Versions.v3.Version[]>(() => {
const gameVersion = currentGameVersion.value
if (!gameVersion) return []
const platform = currentPlatform.value
const result = props.versions.filter((x) => {
const matchesPlatform =
props.project.project_type === 'resourcepack' || (!!platform && x.loaders.includes(platform))
return x.game_versions.includes(gameVersion) && matchesPlatform
})
debug('filteredVersions', {
total: props.versions.length,
filtered: result.length,
currentGameVersion: currentGameVersion.value,
currentPlatform: currentPlatform.value,
sampleLoaders: props.versions.slice(0, 3).map((v) => v.loaders),
})
return result
})
const filteredRelease = computed<Labrinth.Versions.v3.Version | undefined>(() => {
return filteredVersions.value.find((x) => x.version_type === 'release')
})
const filteredBeta = computed<Labrinth.Versions.v3.Version | undefined>(() => {
return filteredVersions.value.find(
(x) =>
x.version_type === 'beta' &&
(!filteredRelease.value ||
dayjs(x.date_published).isAfter(dayjs(filteredRelease.value.date_published))),
)
})
const filteredAlpha = computed<Labrinth.Versions.v3.Version | undefined>(() => {
return filteredVersions.value.find(
(x) =>
x.version_type === 'alpha' &&
(!filteredRelease.value ||
dayjs(x.date_published).isAfter(dayjs(filteredRelease.value.date_published))) &&
(!filteredBeta.value ||
dayjs(x.date_published).isAfter(dayjs(filteredBeta.value.date_published))),
)
})
const selectedVersion = computed<Labrinth.Versions.v3.Version | null>(() => {
return filteredRelease.value || filteredBeta.value || filteredAlpha.value || null
})
const selectedPrimaryFile = computed<Labrinth.Versions.v3.VersionFile | null>(() => {
return (
selectedVersion.value?.files?.find((file) => file.primary) ||
selectedVersion.value?.files?.[0] ||
null
)
})
const selectedPrimaryFileDownloadUrl = computed(() => {
if (!selectedPrimaryFile.value) return '#'
return getDownloadUrl(selectedPrimaryFile.value.url)
})
const selectedVersionDownloadFiles = computed(() => {
if (!selectedVersion.value) return []
return selectedVersion.value.files.map((file) => ({
href: getDownloadUrl(file.url),
filename: file.filename,
}))
})
const downloadAllFiles = computed(() => {
const files: DownloadableFile[] = []
const hrefs = new Set<string>()
for (const file of [...selectedVersionDownloadFiles.value, ...props.dependencyDownloadFiles]) {
if (hrefs.has(file.href)) continue
hrefs.add(file.href)
files.push(file)
}
return files
})
const selectedVersionZipFilename = computed(() => {
if (!selectedVersion.value) return `${sanitizeFilename(props.project.title)}.zip`
return `${sanitizeFilename(props.project.title)} ${sanitizeFilename(
selectedVersion.value.version_number,
)}.zip`
})
watch(
[currentGameVersion, currentPlatform, selectedVersion, selectedPrimaryFile],
() => {
emit('update:selection', {
currentGameVersion: currentGameVersion.value,
currentPlatform: currentPlatform.value,
selectedVersion: selectedVersion.value,
selectedPrimaryFile: selectedPrimaryFile.value,
})
},
{ immediate: true },
)
watch(
() => props.resetKey,
() => {
userSelectedGameVersion.value = props.initialGameVersion
userSelectedPlatform.value = props.initialPlatform
showAllVersions.value = defaultShowAllVersions()
versionFilter.value = ''
},
)
function selectGameVersion(gameVersion?: string) {
if (!gameVersion) return
userSelectedGameVersion.value = gameVersion
emit('selectGameVersion', gameVersion)
selectOnlyCompatiblePlatform()
}
function selectPlatform(platform?: string) {
if (!platform) return
userSelectedPlatform.value = platform
emit('selectPlatform', platform)
}
function getDownloadUrl(url: string) {
return createProjectDownloadUrl(url, {
reason: props.downloadReason,
gameVersion: currentGameVersion.value ?? undefined,
loader: currentPlatform.value ?? undefined,
})
}
async function downloadSelectedVersionFiles() {
if (downloadingSelectedVersion.value || downloadAllFiles.value.length <= 1) return
downloadingSelectedVersion.value = true
const files = [...downloadAllFiles.value]
selectedVersionDownloadProgress.value = {
current: 0,
total: files.length,
}
try {
const zip = new JSZip()
const usedFilenames = new Set<string>()
for (const [index, file] of files.entries()) {
selectedVersionDownloadProgress.value = {
current: index + 1,
total: files.length,
}
const response = await fetch(file.href)
if (!response.ok) {
throw new Error(`Failed to download ${file.filename}`)
}
zip.file(uniqueFilename(file.filename, usedFilenames), await response.blob())
}
downloadBlob(
await zip.generateAsync({
type: 'blob',
mimeType: 'application/zip',
}),
selectedVersionZipFilename.value,
)
emit('download')
} catch (error) {
console.error('Failed to download selected version files:', error)
addNotification({
title: formatMessage(messages.downloadSelectedVersionFailedTitle),
text: formatMessage(messages.downloadSelectedVersionFailedText),
type: 'error',
})
} finally {
downloadingSelectedVersion.value = false
selectedVersionDownloadProgress.value = {
current: 0,
total: 0,
}
}
}
function downloadBlob(blob: Blob, filename: string) {
const url = URL.createObjectURL(blob)
const link = document.createElement('a')
link.href = url
link.download = filename
document.body.appendChild(link)
link.click()
link.remove()
window.setTimeout(() => URL.revokeObjectURL(url), 0)
}
function sanitizeFilename(value: string) {
const sanitized = value
.replace(/[<>:"/\\|?*]/g, '')
.replace(/\s+/g, ' ')
.trim()
return sanitized || 'download'
}
function uniqueFilename(filename: string, usedFilenames: Set<string>) {
const sanitizedFilename = sanitizeFilename(filename)
if (!usedFilenames.has(sanitizedFilename)) {
usedFilenames.add(sanitizedFilename)
return sanitizedFilename
}
const extensionIndex = sanitizedFilename.lastIndexOf('.')
const basename =
extensionIndex > 0 ? sanitizedFilename.slice(0, extensionIndex) : sanitizedFilename
const extension = extensionIndex > 0 ? sanitizedFilename.slice(extensionIndex) : ''
let index = 2
let candidate = `${basename} (${index})${extension}`
while (usedFilenames.has(candidate)) {
index += 1
candidate = `${basename} (${index})${extension}`
}
usedFilenames.add(candidate)
return candidate
}
function loaderLabel(loader: string) {
return formatMessage(getTagMessage(loader, 'loader') ?? messages.unknownLoader)
}
function isReleaseGameVersion(version: string) {
if (releaseVersions.value.has(version)) return true
if (nonReleaseVersions.value.has(version)) return false
return true
}
function defaultShowAllVersions() {
return (
props.project.game_versions.length > 0 &&
props.project.game_versions.every((projectVersion) => {
const gameVersion = tags.value.gameVersions?.find((x) => x.version === projectVersion)
return !!gameVersion?.version_type && gameVersion.version_type !== 'release'
})
)
}
function isGameVersionUnavailable(gameVersion: string) {
return (
incompatibleGameVersionsSet.value.has(gameVersion) ||
!possibleGameVersions.value.includes(gameVersion)
)
}
function isPlatformUnavailable(platform: string) {
return incompatibleLoadersSet.value.has(platform) || !possiblePlatforms.value.includes(platform)
}
function selectOnlyCompatiblePlatform() {
const compatiblePlatforms = props.project.loaders.filter(
(platform) =>
possiblePlatforms.value.includes(platform) && !incompatibleLoadersSet.value.has(platform),
)
if (compatiblePlatforms.length !== 1) return
userSelectedPlatform.value = compatiblePlatforms[0]
emit('selectPlatform', compatiblePlatforms[0])
}
function gameVersionOptionTooltip(gameVersion: string) {
if (incompatibleGameVersionsSet.value.has(gameVersion)) {
return formatMessage(messages.baseGameVersionIncompatibleTooltip)
}
if (!possibleGameVersions.value.includes(gameVersion)) {
return formatMessage(messages.gameVersionUnsupportedTooltip, {
title: props.project.title,
gameVersion,
platform: currentPlatformText.value,
})
}
return null
}
function platformOptionTooltip(platform: string, platformLabel: string) {
if (incompatibleLoadersSet.value.has(platform)) {
return formatMessage(messages.baseLoaderIncompatibleTooltip)
}
if (!possiblePlatforms.value.includes(platform)) {
return formatMessage(messages.platformUnsupportedTooltip, {
title: props.project.title,
platform: platformLabel,
gameVersion: currentGameVersion.value,
})
}
return null
}
const messages = defineMessages({
baseGameVersionIncompatibleTooltip: {
id: 'project.download.base-game-version-incompatible-tooltip',
defaultMessage: 'This game version is incompatible with the base project.',
},
baseLoaderIncompatibleTooltip: {
id: 'project.download.base-loader-incompatible-tooltip',
defaultMessage: 'This loader is incompatible with the base project.',
},
gameVersionUnsupportedTooltip: {
id: 'project.download.game-version-unsupported-tooltip',
defaultMessage: '{title} does not support {gameVersion} for {platform}',
},
downloadVersion: {
id: 'project.download.download-version',
defaultMessage: 'Download {version}',
},
compatibleVersionTitle: {
id: 'project.download.compatible-version-title',
defaultMessage: 'Compatible version',
},
downloadAllSelectedVersion: {
id: 'project.download.selected-version-download-all',
defaultMessage: 'Download all (.zip)',
},
downloadingSelectedVersion: {
id: 'project.download.selected-version-downloading',
defaultMessage: 'Downloading... ({current}/{total})',
},
downloadSelectedVersionFailedTitle: {
id: 'project.download.selected-version-failed-title',
defaultMessage: 'Could not download version',
},
downloadSelectedVersionFailedText: {
id: 'project.download.selected-version-failed-text',
defaultMessage: 'One or more version files could not be downloaded. Please try again.',
},
noGameVersionsFound: {
id: 'project.download.no-game-versions-found',
defaultMessage: 'No game versions found',
},
noVersionsAvailable: {
id: 'project.download.no-versions-available',
defaultMessage: 'No versions available for {gameVersion} and {platform}.',
},
platformUnsupportedTooltip: {
id: 'project.download.platform-unsupported-tooltip',
defaultMessage: '{title} does not support {platform} for {gameVersion}',
},
searchGameVersions: {
id: 'project.download.search-game-versions',
defaultMessage: 'Select game version',
},
selectGameVersion: {
id: 'project.download.select-game-version',
defaultMessage: 'Select game version',
},
selectPlatform: {
id: 'project.download.select-platform',
defaultMessage: 'Select platform',
},
showAllVersions: {
id: 'project.download.show-all-versions',
defaultMessage: 'Show all versions',
},
unknownLoader: {
id: 'project.download.unknown-loader',
defaultMessage: 'Unknown loader',
},
})
</script>
@@ -0,0 +1,111 @@
<template>
<div
v-if="
project.project_type !== 'plugin' ||
project.loaders.some((x) => !tags.loaderData.allPluginLoaders.includes(x))
"
class="modrinth-app-section contents"
>
<div class="flex flex-col">
<a
class="modrinth-app-install-card flex items-center justify-between gap-3 rounded-2xl border border-solid border-brand-highlight bg-surface-1 px-4 py-3 text-primary no-underline transition-[filter] hover:brightness-110"
:href="`modrinth://mod/${project.slug}`"
@click="installWithApp"
>
<span class="flex w-full min-w-0 flex-col gap-1">
<div class="flex items-center justify-between">
<span class="flex min-w-0 items-center gap-1.5 font-medium text-contrast">
Install with
<span class="text-brand">Modrinth App</span>
<ModrinthIcon aria-hidden="true" class="size-4 flex-shrink-0 text-brand" />
</span>
<ExternalIcon
aria-hidden="true"
class="size-4 flex-shrink-0 text-contrast transition-colors"
/>
</div>
<span class="truncate text-base text-contrast opacity-80">
{{ formatMessage(messages.installWithModrinthAppDescription) }}
</span>
</span>
</a>
<Accordion ref="getModrinthAppAccordion">
<nuxt-link class="mt-2 flex justify-center text-brand-blue hover:underline" to="/app">
{{ formatMessage(messages.dontHaveModrinthApp) }}
</nuxt-link>
</Accordion>
</div>
<div class="flex items-center gap-4">
<div class="flex h-[2px] w-full rounded-2xl bg-button-bg"></div>
<span class="flex-shrink-0 text-sm font-medium text-secondary">
{{ formatMessage(messages.downloadManually) }}
</span>
<div class="flex h-[2px] w-full rounded-2xl bg-button-bg"></div>
</div>
</div>
</template>
<script setup lang="ts">
import type { Labrinth } from '@modrinth/api-client'
import { ExternalIcon, ModrinthIcon } from '@modrinth/assets'
import { defineMessages, useVIntl } from '@modrinth/ui'
import type { DisplayProjectType } from '@modrinth/utils'
import { ref } from 'vue'
import Accordion from '~/components/ui/Accordion.vue'
defineOptions({
name: 'InstallWithModrinthApp',
})
type DownloadModalProject = Omit<Labrinth.Projects.v2.Project, 'project_type'> & {
project_type: DisplayProjectType
actualProjectType: Labrinth.Projects.v2.ProjectType
}
defineProps<{
project: DownloadModalProject
}>()
const { formatMessage } = useVIntl()
const tags = useGeneratedState()
const getModrinthAppAccordion = ref<InstanceType<typeof Accordion> | null>(null)
const messages = defineMessages({
dontHaveModrinthApp: {
id: 'project.download.no-app',
defaultMessage: "Don't have Modrinth App?",
},
downloadManually: {
id: 'project.download.manually',
defaultMessage: 'Download manually',
},
installWithModrinthAppDescription: {
id: 'project.download.install-with-app-description',
defaultMessage: 'Automatically install the correct version and dependencies.',
},
})
function installWithApp() {
setTimeout(() => {
getModrinthAppAccordion.value?.open()
}, 1500)
}
</script>
<style lang="scss" scoped>
.modrinth-app-install-card {
background: radial-gradient(
ellipse 90% 250% at 50% 200%,
color-mix(in srgb, var(--color-brand-shadow) 50%, var(--surface-1)) -30%,
var(--surface-1) 72%
);
}
@media (hover: none) and (max-width: 767px) {
.modrinth-app-section {
display: none;
}
}
</style>
@@ -0,0 +1,447 @@
<template>
<NewModal ref="modal" :on-show="onShow" :on-hide="onHide" width="544px">
<template #title>
<template v-if="project">
<Avatar :src="project.icon_url" :alt="project.title" class="icon" size="32px" />
<div
ref="downloadTitleRef"
v-tooltip="truncatedTooltip(downloadTitleRef, downloadTitle)"
class="truncate text-lg font-extrabold text-contrast"
>
{{ downloadTitle }}
</div>
</template>
</template>
<template #default>
<div v-if="project" class="mx-auto flex w-full flex-col gap-4">
<InstallWithModrinthApp :project="project" />
<DownloadProject
:project="project"
:versions="versions"
:dependency-download-files="dependencyDownloadFiles"
:download-reason="downloadReason"
:initial-game-version="initialGameVersion"
:initial-platform="initialPlatform"
:incompatible-game-versions="showOptions.incompatibleGameVersions"
:incompatible-loaders="showOptions.incompatibleLoaders"
:reset-key="downloadProjectResetKey"
@select-game-version="selectGameVersion"
@select-platform="selectPlatform"
@update:selection="projectDownloadSelection = $event"
@download="onDownload"
/>
<div class="flex flex-col gap-4">
<DownloadDependencies
:project="project"
:selected-version="selectedVersion"
:current-game-version="currentGameVersion"
:current-platform="currentPlatform"
:download-reason="downloadReason"
:additional-files="additionalFiles"
@update:downloadable-files="dependencyDownloadFiles = $event"
@download="onDownload"
/>
</div>
<ServersPromo
v-if="flags.showProjectPageDownloadModalServersPromo"
:link="`/hosting#plan`"
@close="
() => {
flags.showProjectPageDownloadModalServersPromo = false
saveFeatureFlags()
}
"
/>
</div>
</template>
</NewModal>
</template>
<script setup lang="ts">
import type { Labrinth } from '@modrinth/api-client'
import {
Avatar,
type CdnDownloadReason,
defineMessages,
injectModrinthClient,
NewModal,
ServersPromo,
truncatedTooltip,
useDebugLogger,
useVIntl,
} from '@modrinth/ui'
import type { DisplayProjectType } from '@modrinth/utils'
import { useQuery } from '@tanstack/vue-query'
import { computed, nextTick, onUnmounted, ref, watch } from 'vue'
import { navigateTo } from '#app'
import { saveFeatureFlags } from '~/composables/featureFlags.ts'
import { STALE_TIME, STALE_TIME_LONG } from '~/composables/queries/project'
import DownloadDependencies from './DownloadDependencies.vue'
import DownloadProject from './DownloadProject.vue'
import InstallWithModrinthApp from './InstallWithModrinthApp.vue'
type DownloadModalProject = Omit<Labrinth.Projects.v2.Project, 'project_type'> & {
project_type: DisplayProjectType
actualProjectType: Labrinth.Projects.v2.ProjectType
}
type ProjectDownloadSelection = {
currentGameVersion: string | null
currentPlatform: string | null
selectedVersion: Labrinth.Versions.v3.Version | null
selectedPrimaryFile: Labrinth.Versions.v3.VersionFile | null
}
type DownloadableFile = {
href: string
filename: string
}
type NewModalRef = {
show: (event?: MouseEvent) => void
hide: () => void
}
type ProjectDownloadModalShowOptions = {
projectId?: string
incompatibleGameVersions?: string[]
incompatibleLoaders?: string[]
}
type ResolvedProjectDownloadModalShowOptions = {
projectId?: string
incompatibleGameVersions: string[]
incompatibleLoaders: string[]
}
const props = withDefaults(
defineProps<{
projectId?: string
downloadReason?: CdnDownloadReason
useRouteHash?: boolean
updateRouteSelection?: boolean
}>(),
{
downloadReason: 'standalone',
useRouteHash: true,
updateRouteSelection: true,
},
)
const emit = defineEmits<{
download: []
}>()
const route = useRoute()
const flags = useFeatureFlags()
const tags = useGeneratedState()
const client = injectModrinthClient()
const { formatMessage } = useVIntl()
const debug = useDebugLogger('DownloadModal')
const modal = ref<NewModalRef | null>(null)
const downloadTitleRef = ref<HTMLElement | null>(null)
const modalOpen = ref(false)
const showProjectId = ref<string | null>(null)
const showOptions = ref<ResolvedProjectDownloadModalShowOptions>(getDefaultShowOptions())
const downloadProjectResetKey = ref(0)
const projectDownloadSelection = ref<ProjectDownloadSelection>(getDefaultProjectDownloadSelection())
const dependencyDownloadFiles = ref<DownloadableFile[]>([])
const MODAL_CLOSE_STATE_RESET_MS = 350
let closeStateResetTimeout: ReturnType<typeof setTimeout> | null = null
const routeProjectId = computed(() => showProjectId.value ?? props.projectId ?? null)
const {
data: projectRaw,
error: projectV2Error,
refetch: refetchProject,
} = useQuery({
queryKey: computed(() => ['project', 'v2', routeProjectId.value]),
queryFn: () => client.labrinth.projects_v2.get(routeProjectId.value!),
enabled: computed(() => !!routeProjectId.value),
staleTime: STALE_TIME,
})
const resolvedProjectId = computed(() => projectRaw.value?.id)
const project = computed<DownloadModalProject | null>(() => {
if (!projectRaw.value) return null
return {
...projectRaw.value,
actualProjectType: projectRaw.value.project_type,
project_type: getProjectTypeForUrl(projectRaw.value.project_type, projectRaw.value.loaders),
}
})
const downloadTitle = computed(() => {
if (!project.value) return ''
return formatMessage(messages.downloadTitle, { title: project.value.title })
})
const versionsEnabled = ref(false)
const {
data: versionsV3,
error: _versionsV3Error,
isFetching: versionsV3Loading,
} = useQuery({
queryKey: computed(() => ['project', resolvedProjectId.value, 'versions', 'v3']),
queryFn: () =>
client.labrinth.versions_v3.getProjectVersions(resolvedProjectId.value!, {
include_changelog: false,
apiVersion: 3,
}),
staleTime: STALE_TIME_LONG,
enabled: computed(() => !!resolvedProjectId.value && versionsEnabled.value),
})
const versions = computed<Labrinth.Versions.v3.Version[]>(() => {
const isModpack =
project.value?.actualProjectType === 'modpack' || project.value?.project_type === 'modpack'
return (versionsV3.value ?? []).map((version) => {
const files = Array.isArray(version.files) ? version.files : []
const gameVersions = Array.isArray(version.game_versions) ? version.game_versions : []
const loaders = Array.isArray(version.loaders) ? version.loaders : []
const mrpackLoaders = Array.isArray(version.mrpack_loaders) ? version.mrpack_loaders : []
return {
...version,
files,
game_versions: gameVersions,
loaders: isModpack && mrpackLoaders.length ? mrpackLoaders : loaders,
}
})
})
const initialGameVersion = computed(() => {
const version = route.query.version
if (typeof version !== 'string' || !project.value?.game_versions.includes(version)) return null
return version
})
const initialPlatform = computed(() => {
const loader = route.query.loader
if (typeof loader !== 'string' || !project.value?.loaders.includes(loader)) return null
return loader
})
const currentGameVersion = computed(() => projectDownloadSelection.value.currentGameVersion)
const currentPlatform = computed(() => projectDownloadSelection.value.currentPlatform)
const selectedVersion = computed(() => projectDownloadSelection.value.selectedVersion)
const selectedPrimaryFile = computed(() => projectDownloadSelection.value.selectedPrimaryFile)
const additionalFiles = computed(() => {
if (!selectedVersion.value || !selectedPrimaryFile.value) return []
return selectedVersion.value.files.filter((file) => file !== selectedPrimaryFile.value)
})
watch(projectV2Error, (error) => {
if (error) {
debug('project query failed', error)
}
})
const messages = defineMessages({
downloadTitle: {
id: 'project.download.title',
defaultMessage: 'Download {title}',
},
})
function getProjectTypeForUrl(
type: Labrinth.Projects.v2.ProjectType,
loaders: string[],
): DisplayProjectType {
if (type !== 'mod') return type as DisplayProjectType
const isMod = loaders.some((loader) => tags.value.loaderData.modLoaders.includes(loader))
const isPlugin = loaders.some((loader) => tags.value.loaderData.allPluginLoaders.includes(loader))
const isDataPack = loaders.some((loader) =>
tags.value.loaderData.dataPackLoaders.includes(loader),
)
if (isDataPack) return 'datapack'
if (isPlugin) return 'plugin'
if (isMod) return 'mod'
return 'mod'
}
function updateDownloadQuery({
gameVersion,
platform,
}: {
gameVersion: string | null
platform: string | null
}) {
if (!props.updateRouteSelection) return
navigateTo(
{
query: {
...route.query,
...(gameVersion && {
version: gameVersion,
}),
...(platform && {
loader: platform,
}),
},
hash: route.hash,
},
{ replace: true },
)
}
function selectGameVersion(gameVersion: string) {
updateDownloadQuery({
gameVersion,
platform: currentPlatform.value,
})
}
function selectPlatform(platform: string) {
updateDownloadQuery({
gameVersion: currentGameVersion.value,
platform,
})
}
function onShow() {
clearCloseStateResetTimeout()
modalOpen.value = true
debug('on-show fired')
versionsEnabled.value = true
if (props.useRouteHash && !showProjectId.value) {
navigateTo({ query: route.query, hash: '#download' }, { replace: true })
}
}
function onHide() {
const hadShowProjectId = !!showProjectId.value
modalOpen.value = false
clearCloseStateResetTimeout()
closeStateResetTimeout = setTimeout(() => {
showProjectId.value = null
showOptions.value = getDefaultShowOptions()
closeStateResetTimeout = null
}, MODAL_CLOSE_STATE_RESET_MS)
if (props.useRouteHash && !hadShowProjectId) {
navigateTo({ query: route.query, hash: '' }, { replace: true })
}
}
async function show(
event?: MouseEvent,
options: ProjectDownloadModalShowOptions = {},
): Promise<void> {
if (!modal.value || modalOpen.value) return
await waitForCloseStateReset()
if (!modal.value || modalOpen.value) return
showOptions.value = {
...getDefaultShowOptions(),
...options,
}
showProjectId.value = showOptions.value.projectId ?? null
await nextTick()
if (!(await loadProjectForModal(!!showOptions.value.projectId))) return
resetDownloadState()
modalOpen.value = true
modal.value.show(event)
}
function hide() {
if (!modal.value || !modalOpen.value) return
modal.value?.hide()
}
function onDownload() {
emit('download')
}
function getDefaultProjectDownloadSelection(): ProjectDownloadSelection {
return {
currentGameVersion: null,
currentPlatform: null,
selectedVersion: null,
selectedPrimaryFile: null,
}
}
function getDefaultShowOptions(): ResolvedProjectDownloadModalShowOptions {
return {
projectId: undefined,
incompatibleGameVersions: [],
incompatibleLoaders: [],
}
}
function clearCloseStateResetTimeout() {
if (!closeStateResetTimeout) return
clearTimeout(closeStateResetTimeout)
closeStateResetTimeout = null
}
async function waitForCloseStateReset() {
if (!closeStateResetTimeout) return
await new Promise((resolve) => setTimeout(resolve, MODAL_CLOSE_STATE_RESET_MS))
}
async function loadProjectForModal(forceRefetch: boolean) {
if (!routeProjectId.value) return false
if (!forceRefetch && projectRaw.value) return true
const { data } = await refetchProject()
return !!data
}
function resetDownloadState() {
projectDownloadSelection.value = getDefaultProjectDownloadSelection()
dependencyDownloadFiles.value = []
downloadProjectResetKey.value += 1
}
function openFromHash() {
if (
!props.useRouteHash ||
!modal.value ||
modalOpen.value ||
showProjectId.value ||
route.hash !== '#download'
) {
return
}
debug('hash #download watch fired, opening modal')
show()
}
if (
props.useRouteHash &&
(route.hash === '#download' ||
route.query.version !== undefined ||
route.query.loader !== undefined)
) {
debug('eager loadVersions from setup', {
hash: route.hash,
version: route.query.version,
loader: route.query.loader,
loading: versionsV3Loading.value,
})
versionsEnabled.value = true
}
watch(modal, openFromHash)
watch(() => route.hash, openFromHash)
watch(routeProjectId, () => {
projectDownloadSelection.value = getDefaultProjectDownloadSelection()
dependencyDownloadFiles.value = []
downloadProjectResetKey.value += 1
})
onUnmounted(clearCloseStateResetTimeout)
defineExpose({ show, hide })
</script>
@@ -257,7 +257,7 @@ const messages = defineMessages({
},
managePasskeyModalLoading: {
id: 'settings.account.security.passkey.modal.loading',
defaultMessage: 'Loading passkeys',
defaultMessage: 'Loading passkeys...',
},
managePasskeyModalNoPasskeys: {
id: 'settings.account.security.passkey.modal.no-passkeys',
@@ -73,6 +73,7 @@
:options="[userOption, ...ownerOptions]"
searchable
:disabled="hasHitLimit"
select-search-text-on-focus
show-icon-in-selected
/>
<span>{{ formatMessage(messages.ownerDescription) }}</span>
@@ -129,7 +130,7 @@
<script setup lang="ts">
import type { Labrinth } from '@modrinth/api-client'
import { PlusIcon, XIcon } from '@modrinth/assets'
import { OrganizationIcon, PlusIcon, XIcon } from '@modrinth/assets'
import {
ButtonStyled,
Chips,
@@ -362,7 +363,13 @@ async function fetchOrganizations() {
}),
),
)
: undefined,
: markRaw(
defineAsyncComponent(() =>
Promise.resolve({
setup: () => () => h(OrganizationIcon, { class: 'size-5' }),
}),
),
),
}))
if (props.organizationId) owner.value = props.organizationId
} catch (err) {
@@ -395,6 +402,7 @@ async function createProject() {
server_side: 'required',
license_id: 'LicenseRef-Unknown',
is_draft: true,
organization_id: owner.value !== 'self' ? owner.value : undefined,
}
formData.append('data', JSON.stringify(projectData))
@@ -2,12 +2,7 @@
<div class="shadow-card rounded-2xl border border-solid border-surface-4 bg-surface-3 p-4">
<div class="flex items-center justify-between">
<div class="flex items-center gap-4">
<NuxtLink
:to="`/project/${queueEntry.project.slug}`"
target="_blank"
tabindex="-1"
class="flex"
>
<NuxtLink :to="`/project/${projectRouteParam}`" target="_blank" tabindex="-1" class="flex">
<Avatar
:src="queueEntry.project.icon_url"
size="4rem"
@@ -17,7 +12,7 @@
<div class="flex flex-col gap-1.5">
<div class="flex items-center gap-2">
<NuxtLink
:to="`/project/${queueEntry.project.slug}`"
:to="`/project/${projectRouteParam}`"
target="_blank"
class="text-lg font-semibold text-contrast hover:underline"
>
@@ -177,7 +172,7 @@ function getDaysQueued(date: Date): number {
const queuedDate = computed(() => {
return dayjs(
props.queueEntry.project.queued ||
props.queueEntry.project.created ||
props.queueEntry.project.published ||
props.queueEntry.project.updated,
)
})
@@ -186,10 +181,14 @@ const daysInQueue = computed(() => {
return getDaysQueued(queuedDate.value.toDate())
})
const projectRouteParam = computed(
() => props.queueEntry.project.slug || props.queueEntry.project.id,
)
const formattedDate = computed(() => {
const date =
props.queueEntry.project.queued ||
props.queueEntry.project.created ||
props.queueEntry.project.published ||
props.queueEntry.project.updated
if (!date) return 'Unknown'
@@ -202,7 +201,7 @@ const formattedDate = computed(() => {
function copyLink() {
const base = window.location.origin
const projectUrl = `${base}/project/${props.queueEntry.project.slug}`
const projectUrl = `${base}/project/${projectRouteParam.value}`
navigator.clipboard.writeText(projectUrl).then(() => {
addNotification({
type: 'success',
@@ -10,9 +10,8 @@ import {
CodeIcon,
CopyIcon,
DownloadIcon,
EllipsisVerticalIcon,
ExternalIcon,
EyeOffIcon,
LinkIcon,
LoaderCircleIcon,
ScaleIcon,
ShieldCheckIcon,
@@ -113,51 +112,6 @@ const isProjectApproved = computed(() => {
)
})
const quickActions = computed<OverflowMenuOption[]>(() => {
const actions: OverflowMenuOption[] = []
const sourceUrl = props.item.project.link_urls?.['source']?.url
if (sourceUrl) {
actions.push({
id: 'view-source',
action: () => {
window.open(sourceUrl, '_blank', 'noopener,noreferrer')
},
})
}
actions.push(
{
id: 'copy-link',
action: () => {
const base = window.location.origin
const reportUrl = `${base}/moderation/technical-review/${props.item.project.id}`
navigator.clipboard.writeText(reportUrl).then(() => {
addNotification({
type: 'success',
title: 'Technical Review link copied',
text: 'The link to this review has been copied to your clipboard.',
})
})
},
},
{
id: 'copy-id',
action: () => {
navigator.clipboard.writeText(props.item.project.id).then(() => {
addNotification({
type: 'success',
title: 'Project ID copied',
text: 'The ID of this project has been copied to your clipboard.',
})
})
},
},
)
return actions
})
const isLoadingStatusAction = ref(false)
const projectStatusActions = computed<OverflowMenuOption[]>(() => [
{
@@ -193,6 +147,7 @@ async function setStatus(status: Labrinth.Projects.v2.ProjectStatus) {
isLoadingStatusAction.value = true
try {
await client.labrinth.projects_v2.edit(props.item.project.id, { status })
emit('refetch')
projectStatus.value = status
} catch (err) {
@@ -1019,6 +974,16 @@ async function handleSubmitReview(verdict: 'safe' | 'unsafe') {
}
}
}
function copyId() {
navigator.clipboard.writeText(props.item.project.id).then(() => {
addNotification({
type: 'success',
title: 'Project ID copied',
text: 'The ID of this project has been copied to your clipboard.',
})
})
}
</script>
<template>
@@ -1104,25 +1069,31 @@ async function handleSubmitReview(verdict: 'safe' | 'unsafe') {
<div class="flex items-center gap-3">
<span class="text-base text-secondary">{{ formattedDate }}</span>
<ButtonStyled circular>
<OverflowMenu :options="quickActions" class="!shadow-none">
<template #default>
<EllipsisVerticalIcon class="size-4" />
</template>
<template #copy-id>
<ClipboardCopyIcon />
<span class="hidden sm:inline">Copy ID</span>
</template>
<template #copy-link>
<LinkIcon />
<span class="hidden sm:inline">Copy link</span>
</template>
<template #view-source>
<div class="flex items-center gap-2">
<ButtonStyled v-if="props.item.project.link_urls?.['source']?.url" circular>
<a
v-tooltip="'Open sources in new tab'"
:href="props.item.project.link_urls?.['source']?.url"
target="_blank"
>
<CodeIcon />
<span class="hidden sm:inline">View source</span>
</template>
</OverflowMenu>
</ButtonStyled>
</a>
</ButtonStyled>
<ButtonStyled circular>
<button v-tooltip="'Copy ID'" @click="copyId">
<ClipboardCopyIcon />
</button>
</ButtonStyled>
<ButtonStyled circular>
<a
v-tooltip="'Open in new tab'"
:href="`/moderation/technical-review/${props.item.project.id}`"
target="_blank"
>
<ExternalIcon />
</a>
</ButtonStyled>
</div>
</div>
</div>
@@ -1206,7 +1177,7 @@ async function handleSubmitReview(verdict: 'safe' | 'unsafe') {
</OverflowMenu>
</ButtonStyled>
<ButtonStyled v-if="featureFlags.developerMode" type="outlined">
<button @click="emit('showMaliciousSummary', unsafeFiles)">Debug Summary</button>
<button @click="emit('showMaliciousSummary', unsafeFiles)">Debug</button>
</ButtonStyled>
</template>
</ThreadView>
@@ -0,0 +1,326 @@
<script setup lang="ts">
import type { Labrinth } from '@modrinth/api-client'
import { FolderSearchIcon, StarIcon } from '@modrinth/assets'
import {
ButtonStyled,
defineMessages,
injectModrinthClient,
NewModal,
Table,
type TableColumn,
useVIntl,
} from '@modrinth/ui'
import { computed, ref, useTemplateRef } from 'vue'
const messages = defineMessages({
title: {
id: 'modpack-scan-modal.title',
defaultMessage: 'Modpack Scan ({scanned}/{total} Files)',
},
scanAllFiles: {
id: 'modpack-scan-modal.scan-all-files',
defaultMessage: 'Scan All Files',
},
packFileName: {
id: 'modpack-scan-modal.pack-file-name',
defaultMessage: 'Pack File Name',
},
newFiles: {
id: 'modpack-scan-modal.new-files',
defaultMessage: 'New Files',
},
newGroups: {
id: 'modpack-scan-modal.new-groups',
defaultMessage: 'New Groups',
},
loadingVersions: {
id: 'modpack-scan-modal.loading-versions',
defaultMessage: 'Loading versions...',
},
noFiles: {
id: 'modpack-scan-modal.no-files',
defaultMessage: 'No files found.',
},
notScanned: {
id: 'modpack-scan-modal.not-scanned',
defaultMessage: 'Not scanned',
},
scanning: {
id: 'modpack-scan-modal.scanning',
defaultMessage: 'Scanning...',
},
failed: {
id: 'modpack-scan-modal.failed',
defaultMessage: 'Failed',
},
overrideFiles: {
id: 'modpack-scan-modal.override-files',
defaultMessage: 'Override Files ({count})',
},
loadVersionsError: {
id: 'modpack-scan-modal.load-versions-error',
defaultMessage: 'Failed to load versions: {error}',
},
scanError: {
id: 'modpack-scan-modal.scan-error',
defaultMessage: 'Some files failed to scan: {error}',
},
})
type ScanTableColumn = 'filename' | 'newFiles' | 'newGroups'
type ScanRow = {
id: string
filename: string
primary: boolean
scan?: Labrinth.Attribution.Internal.FileScanResponse
isScanning: boolean
error?: string
newFiles?: number
newGroups?: number
}
const props = defineProps<{
project_id: string
}>()
const client = injectModrinthClient()
const modalRef = useTemplateRef<InstanceType<typeof NewModal>>('modalRef')
const { formatMessage } = useVIntl()
const rows = ref<ScanRow[]>([])
const isLoadingVersions = ref(false)
const isScanning = ref(false)
const versionLoadError = ref<string | null>(null)
const scanError = ref<string | null>(null)
const requestId = ref(0)
const scanRequestId = ref(0)
const columns = computed<TableColumn<ScanTableColumn>[]>(() => [
{ key: 'filename', label: formatMessage(messages.packFileName), width: '60%' },
{ key: 'newFiles', label: formatMessage(messages.newFiles), align: 'center', width: '20%' },
{ key: 'newGroups', label: formatMessage(messages.newGroups), align: 'center', width: '20%' },
])
const scannedCount = computed(() => rows.value.filter((row) => row.scan || row.error).length)
const isBusy = computed(() => isLoadingVersions.value || isScanning.value)
function getErrorMessage(error: unknown) {
if (error instanceof Error) {
return error.message
}
if (typeof error === 'object' && error !== null && 'data' in error) {
const data = (error as { data?: { description?: string } }).data
if (data?.description) {
return data.description
}
}
return String(error)
}
async function fetchAllVersions() {
const currentRequestId = ++requestId.value
isLoadingVersions.value = true
versionLoadError.value = null
scanError.value = null
rows.value = []
try {
const versions = await client.labrinth.versions_v2.getProjectVersions(props.project_id)
if (currentRequestId !== requestId.value) {
return
}
rows.value = versions
.flatMap((version) => version.files)
.filter((file): file is Labrinth.Versions.v2.VersionFile & { id: string } => Boolean(file.id))
.map((file) => ({
id: file.id,
filename: file.filename,
primary: file.primary,
isScanning: false,
newFiles: undefined,
newGroups: undefined,
}))
} catch (error) {
if (currentRequestId === requestId.value) {
versionLoadError.value = formatMessage(messages.loadVersionsError, {
error: getErrorMessage(error),
})
}
} finally {
if (currentRequestId === requestId.value) {
isLoadingVersions.value = false
}
}
}
async function fetchAllScans() {
if (isBusy.value) {
return
}
const currentScanRequestId = ++scanRequestId.value
isScanning.value = true
scanError.value = null
rows.value = rows.value.map((row) => ({
...row,
scan: undefined,
isScanning: false,
error: undefined,
newFiles: undefined,
newGroups: undefined,
}))
try {
for (const row of rows.value) {
if (currentScanRequestId !== scanRequestId.value) {
return
}
row.isScanning = true
try {
const scan = await client.labrinth.attribution_internal.scanFile(row.id)
if (currentScanRequestId !== scanRequestId.value) {
return
}
row.scan = scan
row.newFiles = scan.new_attribution_files
row.newGroups = scan.new_attribution_groups
} catch (error) {
if (currentScanRequestId !== scanRequestId.value) {
return
}
row.error = getErrorMessage(error)
scanError.value = formatMessage(messages.scanError, { error: row.error })
} finally {
row.isScanning = false
}
}
} finally {
if (currentScanRequestId === scanRequestId.value) {
isScanning.value = false
}
}
}
function show() {
scanRequestId.value++
isScanning.value = false
rows.value = []
void fetchAllVersions()
modalRef.value?.show()
}
function hide() {
modalRef.value?.hide()
}
defineExpose({ show, hide })
</script>
<template>
<NewModal
ref="modalRef"
width="60vw"
:close-on-click-outside="false"
:close-on-esc="false"
:disable-close="isBusy"
>
<template #title>
<div class="flex w-full items-center justify-between gap-2">
<span class="text-2xl font-semibold text-contrast">
{{
formatMessage(messages.title, {
scanned: scannedCount,
total: rows.length,
})
}}
</span>
<div>
<ButtonStyled circular>
<button
v-tooltip="formatMessage(messages.scanAllFiles)"
:disabled="isBusy || rows.length === 0"
@click="fetchAllScans"
>
<FolderSearchIcon aria-hidden="true" />
</button>
</ButtonStyled>
</div>
</div>
</template>
<div class="w-full">
<div
v-if="versionLoadError || scanError"
class="mb-3 rounded-xl bg-highlight-red p-3 text-red"
>
{{ versionLoadError || scanError }}
</div>
<Table
:columns="columns"
:data="rows"
row-key="id"
:row-below-visible="
(row) => Boolean(row.scan?.scanned_file_names && row.scan.scanned_file_names.length > 0)
"
table-min-width="42rem"
>
<template #cell-filename="{ row }">
<div class="flex min-w-0 items-center gap-1 text-contrast">
<StarIcon v-if="row.primary" class="size-4 shrink-0" aria-hidden="true" />
<span class="min-w-0 truncate">{{ row.filename }}</span>
</div>
</template>
<template #cell-newFiles="{ row }">
<span v-if="row.isScanning">{{ formatMessage(messages.scanning) }}</span>
<span v-else-if="row.error" v-tooltip="row.error" class="text-red">
{{ formatMessage(messages.failed) }}
</span>
<span v-else-if="row.scan">{{ row.scan.new_attribution_files }}</span>
<span v-else>{{ formatMessage(messages.notScanned) }}</span>
</template>
<template #cell-newGroups="{ row }">
<span v-if="row.isScanning">{{ formatMessage(messages.scanning) }}</span>
<span v-else-if="row.error" v-tooltip="row.error" class="text-red">
{{ formatMessage(messages.failed) }}
</span>
<span v-else-if="row.scan">{{ row.scan.new_attribution_groups }}</span>
<span v-else>{{ formatMessage(messages.notScanned) }}</span>
</template>
<template #row-below="{ row }">
<div class="border-0 border-t border-solid border-surface-4 px-4 py-3">
<details>
<summary>
{{
formatMessage(messages.overrideFiles, {
count: row.scan?.scanned_file_names.length ?? 0,
})
}}
</summary>
<div class="flex flex-wrap gap-1 pt-2">
<span
v-for="name of row.scan?.scanned_file_names ?? []"
:key="name"
v-tooltip="name"
class="flex items-center gap-1 text-wrap rounded-full bg-button-bg px-2 py-0.5 text-xs font-medium text-contrast"
>
{{ name }}
</span>
</div>
</details>
</div>
</template>
<template #empty-state>
<div class="flex h-64 items-center justify-center text-secondary">
{{ formatMessage(isLoadingVersions ? messages.loadingVersions : messages.noFiles) }}
</div>
</template>
</Table>
</div>
</NewModal>
</template>
@@ -1949,7 +1949,10 @@ function generateModpackMessage(allFiles: {
const hasNextProject = ref(false)
async function refreshModerationCaches(threadId?: string) {
const refreshes: Promise<unknown>[] = [invalidate(), refreshNuxtData('moderation-projects')]
const refreshes: Promise<unknown>[] = [
invalidate(),
queryClient.invalidateQueries({ queryKey: ['moderation-projects'] }),
]
if (threadId) {
refreshes.push(queryClient.invalidateQueries({ queryKey: ['thread', threadId] }))
@@ -21,6 +21,7 @@ export const DEFAULT_FEATURE_FLAGS = validateValues({
developerMode: false,
demoMode: false,
showVersionFilesInTable: false,
showVersionEnvironmentColumn: false,
showAdsWithPlus: false,
alwaysShowChecklistAsPopup: true,
testTaxForm: false,
@@ -4,6 +4,7 @@ import type {
BrowseInstallPlan,
BrowseSearchState,
CreationFlowContextValue,
EnvironmentSearchOverride,
FilterValue,
PendingServerContentInstall,
PendingServerContentInstallType,
@@ -21,6 +22,8 @@ import {
readStoredServerInstallQueue,
removePendingServerContentInstall,
requestInstall,
stripServerRuntimeInstallFilters,
stripServerRuntimeInstallOverrides,
useVIntl,
writePendingServerContentInstallBaseline,
writeStoredServerInstallQueue,
@@ -160,6 +163,7 @@ export function useServerInstallContent({
})
const serverHideInstalled = ref(false)
const serverContentServerOnly = ref(false)
const hideSelectedServerInstalls = ref(false)
const installingProjectIds = ref<Set<string>>(new Set())
const optimisticallyInstalledProjectIds = ref<Set<string>>(new Set())
@@ -348,10 +352,6 @@ export function useServerInstallContent({
filters.push({ type: 'plugin_loader', option: platform })
}
if (projectType.value?.id === 'mod') {
filters.push({ type: 'environment', option: 'server' })
}
if (serverHideInstalled.value && hiddenInstalledProjectIds.value.size > 0) {
for (const x of hiddenInstalledProjectIds.value) {
filters.push({
@@ -383,6 +383,28 @@ export function useServerInstallContent({
return filters
})
const showServerOnlyToggle = computed(() => !!serverData.value && projectType.value?.id === 'mod')
const serverEnvironmentOverride = computed<EnvironmentSearchOverride | undefined>(() => {
if (!showServerOnlyToggle.value) return undefined
if (serverContentServerOnly.value) {
return {
mode: 'include',
values: [
'server_only',
'dedicated_server_only',
'server_only_client_optional',
'client_or_server_prefers_both',
'client_or_server',
],
}
}
return {
mode: 'exclude',
values: ['client_only', 'singleplayer_only'],
}
})
function getCurrentServerInstallType(): BrowseInstallContentType {
const type = projectType.value?.id
if (type === 'modpack' || type === 'mod' || type === 'plugin' || type === 'datapack') {
@@ -584,11 +606,15 @@ export function useServerInstallContent({
project,
contentType,
mode: isModpack ? 'immediate' : 'queue',
selectedFilters: isModpack ? [] : browseSearchState.currentFilters.value,
selectedFilters: isModpack
? []
: stripServerRuntimeInstallFilters(browseSearchState.currentFilters.value),
providedFilters: isModpack ? [] : serverFilters.value,
overriddenProvidedFilterTypes: isModpack
? []
: browseSearchState.overriddenProvidedFilterTypes.value,
: stripServerRuntimeInstallOverrides(
browseSearchState.overriddenProvidedFilterTypes.value,
),
targetPreferences: getServerInstallTargetPreferences(contentType),
getProjectVersions: getInstallProjectVersions,
queue: serverInstallQueue,
@@ -737,6 +763,10 @@ export function useServerInstallContent({
serverHideInstalled.value = route.query.shi === 'true'
}
if (route.query.so && projectType.value?.id === 'mod') {
serverContentServerOnly.value = route.query.so === 'true'
}
watch(serverHideInstalled, (hideInstalled) => {
if (hideInstalled) {
syncHiddenInstalledProjectIds()
@@ -763,6 +793,9 @@ export function useServerInstallContent({
serverContentData,
serverFilters,
serverHideInstalled,
serverContentServerOnly,
showServerOnlyToggle,
serverEnvironmentOverride,
hideSelectedServerInstalls,
installingProjectIds,
optimisticallyInstalledProjectIds,
+3 -6
View File
@@ -1,3 +1,4 @@
import type { Labrinth } from '@modrinth/api-client'
import type { ExtendedReport, OwnershipTarget } from '@modrinth/moderation'
import type {
Organization,
@@ -197,14 +198,10 @@ export interface ModerationOwnershipOrganization {
export type ModerationOwnership = ModerationOwnershipUser | ModerationOwnershipOrganization
export interface ProjectWithOwnership {
ownership: ModerationOwnership
external_dependencies_count: number
[key: string]: any
}
export type ProjectWithOwnership = Labrinth.Moderation.Internal.QueueProject
export interface ModerationProject {
project: any
project: Omit<ProjectWithOwnership, 'ownership' | 'external_dependencies_count'>
ownership: ModerationOwnership | null
external_dependencies_count: number
}
+48
View File
@@ -5,6 +5,10 @@
<div class="pointer-events-none absolute inset-0 z-[-1]">
<div id="absolute-background-teleport" class="relative"></div>
</div>
<div
class="pride-backdrop pointer-events-none absolute inset-0 z-[-1]"
:class="{ shown: showPrideBackdrop }"
></div>
<div class="pointer-events-none absolute inset-0 z-50">
<div
class="over-the-top-random-animation"
@@ -801,6 +805,7 @@ import ProjectCreateModal from '~/components/ui/create/ProjectCreateModal.vue'
import ModrinthFooter from '~/components/ui/ModrinthFooter.vue'
import { getSignInRouteObj } from '~/composables/auth.ts'
import { errors as generatedStateErrors } from '~/generated/state.json'
import { provideCurrentProjectId } from '~/providers/current-project.ts'
import { getProjectTypeMessage } from '~/utils/i18n-project-type.ts'
import { hasActiveMidas } from '~/utils/user-membership.ts'
@@ -867,6 +872,32 @@ const showTinMismatchBanner = computed(() => {
return !!auth.value.user && status === 'tin-mismatch'
})
const PRIDE_COLLECTION_ID = 'M4c3ITvd'
const PRIDE_ARTICLE_SLUGS = ['pride-campaign-2025', 'pride-campaign-2026', 'proud-of-you-2026']
const PRIDE_CACHE_TIME = 1000 * 60 * 60 * 24
const { data: prideCollection } = useQuery({
queryKey: computed(() => ['collection', PRIDE_COLLECTION_ID]),
queryFn: () => client.labrinth.collections.get(PRIDE_COLLECTION_ID),
staleTime: PRIDE_CACHE_TIME,
gcTime: PRIDE_CACHE_TIME,
})
const prideProjectIds = computed(() => new Set(prideCollection.value?.projects ?? []))
const currentProjectId = ref()
provideCurrentProjectId(currentProjectId)
const showPrideBackdrop = computed(() => {
if (PRIDE_ARTICLE_SLUGS.includes(route.params.slug)) {
return true
}
if (route.params.collection === PRIDE_COLLECTION_ID) {
return true
}
return !!currentProjectId.value && prideProjectIds.value.has(currentProjectId.value)
})
const basePopoutId = useId()
async function fetchIntercomToken() {
@@ -1695,4 +1726,21 @@ const { cycle: changeTheme } = useTheme()
transform: translateY(0);
}
}
.pride-backdrop {
background-image: linear-gradient(to right, #c20732, #f57203, #ffd632, #21ca8b, #2f9ff2, #e420fc);
mask-image: linear-gradient(to bottom, rgba(0, 0, 0, 1), rgba(0, 0, 0, 0) 80%);
height: 30rem;
opacity: 0;
transition: opacity 1s ease;
}
.pride-backdrop.shown {
opacity: 0.08;
}
.light-mode .pride-backdrop.shown,
.light .pride-backdrop.shown {
opacity: 0.15;
}
</style>
@@ -356,18 +356,9 @@
"auth.reset-password.title.long": {
"message": "تغيير كلمة المرور"
},
"auth.sign-in.2fa.description": {
"message": "يرجى إدخال رمز التحقق الثنائي للمتابعة."
},
"auth.sign-in.2fa.label": {
"message": "أدخل رمز التحقق الثنائي"
},
"auth.sign-in.2fa.placeholder": {
"message": "أدخل الرمز..."
},
"auth.sign-in.sign-in-with": {
"message": "تسجيل الدخول باستخدام"
},
"auth.sign-in.title": {
"message": "تسجيل الدخول"
},
@@ -380,9 +371,6 @@
"auth.sign-up.title": {
"message": "إنشاء حساب"
},
"auth.sign-up.title.sign-up-with": {
"message": "سجّل باستخدام"
},
"auth.verify-email.action.account-settings": {
"message": "إعدادات الحساب"
},
@@ -926,18 +914,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "يرجى مراجعة بيانات تعريف البيئة"
},
"dashboard.projects.sort.ascending": {
"message": "صعوداً"
},
"dashboard.projects.sort.descending": {
"message": "نزولا"
},
"dashboard.projects.sort.option.name": {
"message": "الإسم"
},
"dashboard.projects.sort.option.status": {
"message": "الحالة"
},
"dashboard.revenue.available-now": {
"message": "متاح الآن"
},
File diff suppressed because it is too large Load Diff
@@ -254,18 +254,9 @@
"auth.reset-password.title.long": {
"message": "Nulstil din adgangskode"
},
"auth.sign-in.2fa.description": {
"message": "Indtast en to-faktor-kode for at fortsætte."
},
"auth.sign-in.2fa.label": {
"message": "Indtast to-faktor-kode"
},
"auth.sign-in.2fa.placeholder": {
"message": "Indtast kode..."
},
"auth.sign-in.sign-in-with": {
"message": "Log ind med"
},
"auth.sign-in.title": {
"message": "Log ind"
},
@@ -278,9 +269,6 @@
"auth.sign-up.title": {
"message": "Tilmeld"
},
"auth.sign-up.title.sign-up-with": {
"message": "Tilmeld dig med"
},
"auth.verify-email.action.account-settings": {
"message": "Kontoindstillinger"
},
@@ -1772,45 +1760,21 @@
"project.description.title": {
"message": "Beskrivelse"
},
"project.download.game-version": {
"message": "Spille version: {version}"
},
"project.download.game-version-error": {
"message": "Fejl: ingen spil versioner fundet"
},
"project.download.game-version-tooltip": {
"message": "{title} er kun tilgængelig til {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} understøtter ikke {gameVersion} til {platform}"
},
"project.download.install-with-app": {
"message": "Installer med Modrinth App"
},
"project.download.no-app": {
"message": "Har ikke Modrinth App?"
},
"project.download.no-versions-available": {
"message": "Ingen versioner tilgængelig til {gameVersion} og {platform}."
},
"project.download.platform": {
"message": "Platform: {platform}"
},
"project.download.platform-error": {
"message": "Fejl: ingen platforme fundet"
},
"project.download.platform-tooltip": {
"message": "{title} er kun tilgængelig til {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} understøtter ikke {platform} til {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Søg spil versioner..."
},
"project.download.search-game-versions-label": {
"message": "Søg spil versioner..."
},
"project.download.select-game-version": {
"message": "Vælg spil version"
},
+326 -59
View File
@@ -23,6 +23,15 @@
"analytics.breakdown.country": {
"message": "Land"
},
"analytics.breakdown.dependent-on": {
"message": "Abhängig von"
},
"analytics.breakdown.dependent-project-download": {
"message": "Abhängiges Projekt"
},
"analytics.breakdown.dependent-project-type": {
"message": "Abhängiger Projekttyp"
},
"analytics.breakdown.download-reason": {
"message": "Download-Grund"
},
@@ -38,6 +47,9 @@
"analytics.breakdown.loader": {
"message": "Loader"
},
"analytics.breakdown.members": {
"message": "Mitglied"
},
"analytics.breakdown.monetization": {
"message": "Monetarisierung"
},
@@ -134,6 +146,24 @@
"analytics.chart.render-limit.header": {
"message": "Alle {count} Linien im Diagramm anzeigen?"
},
"analytics.chart.table-selection.all": {
"message": "Zeige alle {itemType, select, project {{count, plural, one {Projekt} other {Projekte}}} country {{count, plural, one {Land} other {Länder}}} monetization {{count, plural, one {Monetarisierungswert} other {Monetarisierungswerte}}} downloadSource {{count, plural, one {Downloadquelle} other {Downloadquellen}}} downloadReason {{count, plural, one {Downloadgrund} other {Downloadgründe}}} member {{count, plural, one {Mitglied} other {Mitglieder}}} projectVersion {{count, plural, one {Projektversion} other {Projektversionen}}} loader {{count, plural, one {Loader} other {Loader}}} gameVersion {{count, plural, one {Spielversion} other {Spielversionen}}} other {{count, plural, one {Artikel} other {Artikel}}}} aus der Tabelle"
},
"analytics.chart.table-selection.count": {
"message": "Zeige {count} {itemType, select, project {{count, plural, one {Projekt} other {Projekte}}} country {{count, plural, one {Land} other {Länder}}} monetization {{count, plural, one {Monetarisierungswert} other {Monetarisierungswerte}}} downloadSource {{count, plural, one {Downloadquelle} other {Downloadquellen}}} downloadReason {{count, plural, one {Downloadgrund} other {Downloadgründe}}} member {{count, plural, one {Mitglied} other {Mitglieder}}} projectVersion {{count, plural, one {Projektversion} other {Projektversionen}}} loader {{count, plural, one {Loader} other {Loader}}} gameVersion {{count, plural, one {Spielversion} other {Spielversionen}}} other {{count, plural, one {Artikel} other {Artikel}}}} aus der Tabelle"
},
"analytics.chart.table-selection.limited": {
"message": "Zeige {limit} {itemType, select, project {{limit, plural, one {Projekt} other {Projekte}}} country {{limit, plural, one {Land} other {Länder}}} monetization {{limit, plural, one {Monetarisierungswert} other {Monetarisierungswerte}}} downloadSource {{limit, plural, one {Downloadquelle} other {Downloadquellen}}} downloadReason {{limit, plural, one {Downloadgrund} other {Downloadgründe}}} member {{limit, plural, one {Mitglied} other {Mitglieder}}} projectVersion {{limit, plural, one {Projektversion} other {Projektversionen}}} loader {{limit, plural, one {Loader} other {Loader}}} gameVersion {{limit, plural, one {Spielversion} other {Spielversionen}}} other {{limit, plural, one {Artikel} other {Artikel}}}} aus der Tabelle"
},
"analytics.chart.table-selection.top": {
"message": "Zeige die top {count} {itemType, select, project {{count, plural, one {Projekt} other {Projekte}}} country {{count, plural, one {Land} other {Länder}}} monetization {{count, plural, one {Monetarisierungswert} other {Monetarisierungswerte}}} downloadSource {{count, plural, one {Downloadquelle} other {Downloadquellen}}} downloadReason {{count, plural, one {Downloadgrund} other {Downloadgründe}}} member {{count, plural, one {Mitglied} other {Mitglieder}}} projectVersion {{count, plural, one {Projektversion} other {Projektversionen}}} loader {{count, plural, one {Loader} other {Loader}}} gameVersion {{count, plural, one {Spielversion} other {Spielversionen}}} other {{count, plural, one {Artikel} other {Artikel}}}} aus der Tabelle"
},
"analytics.chart.tooltip.dependent-on-project": {
"message": "Abhängig von {project}"
},
"analytics.chart.tooltip.dependent-project-version": {
"message": "{dependentProject} abhängig von {dependencyProject}, {version}"
},
"analytics.chart.tooltip.duration.days": {
"message": "{count, plural, one {# Tag} other {# Tage}}"
},
@@ -218,9 +248,15 @@
"analytics.filter.search.countries": {
"message": "Länder suchen..."
},
"analytics.filter.search.dependent-projects": {
"message": "Projekte durchsuchen..."
},
"analytics.filter.search.download-sources": {
"message": "Download-Quellen suchen..."
},
"analytics.filter.search.members": {
"message": "Mitglieder durchsuchen..."
},
"analytics.filter.search.project-versions": {
"message": "Projektversionen suchen..."
},
@@ -467,6 +503,12 @@
"analytics.value.monetized": {
"message": "Monetarisiert"
},
"analytics.value.no-dependent": {
"message": "Keine"
},
"analytics.value.no-dependent-tooltip": {
"message": "Aus anderen Gründen als einer Abhängigkeit heruntergeladen"
},
"analytics.value.none": {
"message": "Keine"
},
@@ -689,12 +731,72 @@
"auth.authorize.authorize-app-name": {
"message": "{appName} autorisieren"
},
"auth.authorize.error.missing-parameters": {
"message": "Erforderliche Abfrageparameter für OAuth fehlen."
},
"auth.authorize.error.no-redirect-url": {
"message": "Keine Weiterleitungsziel in Antwort gefunden"
},
"auth.authorize.errro-title": {
"message": "Ein Fehler ist aufgetreten"
},
"auth.authorize.redirect-url": {
"message": "Du wirst zu <redirect-url>{url}</redirect-url> weitergeleitet"
},
"auth.continue-with-provider": {
"message": "Weiter mit {provider}"
},
"auth.create-account.age-requirement.warning-title": {
"message": "Mindestalter"
},
"auth.create-account.complete-sign-up": {
"message": "Registrierung abschließen"
},
"auth.create-account.date-of-birth.invalid.text": {
"message": "Bitte gib ein gültiges Geburtsdatum ein. Das Jahr darf nicht 0000 sein."
},
"auth.create-account.date-of-birth.invalid.title": {
"message": "Ungültiges Geburtsdatum"
},
"auth.create-account.date-of-birth.label": {
"message": "Geburtsdatum"
},
"auth.create-account.date-of-birth.placeholder": {
"message": "Wähle dein Geburtsdatum"
},
"auth.create-account.date-of-birth.required.text": {
"message": "Bitte gib dein Geburtsdatum ein, bevor du fortfährst."
},
"auth.create-account.date-of-birth.required.title": {
"message": "Geburtsdatum erforderlich"
},
"auth.create-account.date-of-birth.under13-helper": {
"message": "Du erfüllst das Mindestalter für die Erstellung eines Kontos bei Modrinth nicht."
},
"auth.create-account.info-panel.source-code-link": {
"message": "Relevanter Quellcode"
},
"auth.create-account.info-panel.text": {
"message": "Wir speichern dein Geburtsdatum nicht. Wir verwenden es ausschließlich bei der Registrierung, um die Einhaltung der COPPA-Vorschriften sicherzustellen."
},
"auth.create-account.page-title": {
"message": "Konto erstellen"
},
"auth.create-account.security-check.label": {
"message": "Sicherheitscheck"
},
"auth.create-account.subscribe.label": {
"message": "Haltet mich per E-Mail über coole Dinge auf dem Laufenden, an denen Modrinth gerade arbeitet"
},
"auth.create-account.title": {
"message": "Ein Konto erstellen"
},
"auth.create-account.username.label": {
"message": "Benutzername"
},
"auth.create-account.username.placeholder": {
"message": "Benutzername eingeben"
},
"auth.reset-password.method-choice.action": {
"message": "Wiederherstellungs-E-Mail senden"
},
@@ -729,23 +831,53 @@
"message": "Dein Passwort zurücksetzen"
},
"auth.sign-in.2fa.description": {
"message": "Bitte gib einen Zwei-Faktor-Code ein, um fortzufahren."
"message": "Gib den 6-stelligen Code aus deiner Authentifikator-App oder einen deiner Backup-Codes ein."
},
"auth.sign-in.2fa.label": {
"message": "Zwei-Faktor-Code eingeben"
"message": "Zwei-Faktor-Authentifizierung"
},
"auth.sign-in.2fa.placeholder": {
"message": "Code eingeben..."
},
"auth.sign-in.continue-with-email": {
"message": "Weiter mit E-Mail"
},
"auth.sign-in.continue-with-passkey": {
"message": "Weiter mit Passkey"
},
"auth.sign-in.create-account": {
"message": "Registrieren"
},
"auth.sign-in.forgot-password": {
"message": "Passwort vergessen"
},
"auth.sign-in.last-sign-in": {
"message": "Zuletzt benutzt"
},
"auth.sign-in.no-account": {
"message": "Kein Account?"
},
"auth.sign-in.sign-in-with": {
"message": "Anmelden mit"
"message": "Einloggen"
},
"auth.sign-in.title": {
"message": "Anmelden"
},
"auth.sign-up.age-requirement.warning-title": {
"message": "Mindestalter"
},
"auth.sign-up.continue-with-email": {
"message": "Mit E-Mail fortfahren"
},
"auth.sign-up.legal-dislaimer": {
"message": "Durch das erstellen eines Kontos stimmst du den <terms-link>Nutzungsbedingungen</terms-link> und <privacy-policy-link>Datenschutzrichtlinien</privacy-policy-link> von Modrinth zu."
},
"auth.sign-up.show-fewer-options": {
"message": "Weniger Optionen anzeigen"
},
"auth.sign-up.show-other-options": {
"message": "Andere Optionen anzeigen"
},
"auth.sign-up.sign-in-option.title": {
"message": "Du hast bereits ein Konto?"
},
@@ -753,11 +885,14 @@
"message": "Registrieren"
},
"auth.sign-up.title.sign-up-with": {
"message": "Registrieren mit"
"message": "Account erstellen"
},
"auth.verify-email.action.account-settings": {
"message": "Kontoeinstellungen"
},
"auth.verify-email.action.discover-mods": {
"message": "Mods entdecken"
},
"auth.verify-email.already-verified.description": {
"message": "Deine E-Mail ist bereits verifiziert!"
},
@@ -776,6 +911,15 @@
"auth.verify-email.failed-verification.title": {
"message": "E-Mail-Veifizierung fehlgeschlagen"
},
"auth.verify-email.notification.email-sent.description": {
"message": "Eine E-Mail an {email} wurde zur Verifikation deines Accounts geschickt."
},
"auth.verify-email.notification.email-sent.title": {
"message": "E-Mail gesendet"
},
"auth.verify-email.notification.error-occurred.title": {
"message": "Ein Fehler ist aufgetreten"
},
"auth.verify-email.post-verification.description": {
"message": "Deine E-Mail-Adresse wurde erfolgreich verifiziert!"
},
@@ -1490,9 +1634,6 @@
"dashboard.overview.notifications.loading": {
"message": "Benachrichtigungen werden geladen..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Du kannst mehrere Projekte gleichzeitig bearbeiten, indem du sie unten auswählst."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Serverprojekte understützen Massenbearbeitung nicht"
},
@@ -1568,24 +1709,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Bitte überprüfe die Umgebungsmetadaten"
},
"dashboard.projects.sort.ascending": {
"message": "Aufsteigend"
},
"dashboard.projects.sort.descending": {
"message": "Absteigend"
},
"dashboard.projects.sort.option.name": {
"message": "Name"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Art"
},
"dashboard.projects.table.icon": {
"message": "Icon"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -3098,45 +3221,21 @@
"project.details.licensed": {
"message": "Lizenziert unter"
},
"project.download.game-version": {
"message": "Spielversion: {version}"
},
"project.download.game-version-error": {
"message": "Fehler: Keine Spielversion gefunden"
},
"project.download.game-version-tooltip": {
"message": "{title} ist nur für {version} verfügbar"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} unterstützt {gameVersion} für {platform} nicht"
},
"project.download.install-with-app": {
"message": "Mit Modrinth App installieren"
},
"project.download.no-app": {
"message": "Du hast die Modrinth App nicht?"
},
"project.download.no-versions-available": {
"message": "Keinen versionen verfügbar für {gameVersion} und {platform}."
},
"project.download.platform": {
"message": "Platform: {platform}"
},
"project.download.platform-error": {
"message": "Fehler: Keine Plattform gefunden"
},
"project.download.platform-tooltip": {
"message": "{title} ist nur für {platform} verfügbar"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} unterstützt {platform} für {gameVersion} nicht"
},
"project.download.search-game-versions": {
"message": "Spielversionen durchsuchen..."
},
"project.download.search-game-versions-label": {
"message": "Spielversionen durchuschen..."
},
"project.download.select-game-version": {
"message": "Spielversion wählen"
},
@@ -3327,43 +3426,76 @@
"message": "URL"
},
"project.settings.permissions.attention-needed.description.proj-approved": {
"message": "Bitte lege Nachweise vor, dass du die Erlaubnis zur Weiterverbreitung fgolgender Dateien hast; alle zurückgehaltenen Versionen werden automatisch veröffentlicht."
"message": "Bitte lege Nachweise vor, dass du die Erlaubnis zur Weiterverbreitung folgender Dateien hast. Danach werden die zurückgehaltenen Versionen automatisch veröffentlicht."
},
"project.settings.permissions.attention-needed.description.proj-draft": {
"message": "Bitte lege Nachweise vor, dass du die Erlaubnis zur Weiterverbreitung fgolgender Dateien hast, bevor du dein Projekt zur überprüfung einreichen kannst."
"message": "Bitte lege Nachweise vor, dass du die Erlaubnis zur Weiterverbreitung aller folgenden Dateien hast, bevor du dein Projekt zur Überprüfung einreichst."
},
"project.settings.permissions.attention-needed.title": {
"message": "Unbekannter eingebetteter Inhalt"
"message": "Unbekannter externer Inhalt"
},
"project.settings.permissions.bad-proof.description": {
"message": "Das Moderationsteam von Modrinth hat die von dir für einige externe Inhalte vorgelegten Berechtigungsnachweise abgelehnt. Bitte überprüfe die unten aufgeführten abgelehnten Einträge und lege zulässige Nachweise vor oder entfernen die Inhalte."
},
"project.settings.permissions.bad-proof.title": {
"message": "Manche Beweise wurden abgelehnt"
},
"project.settings.permissions.collapse-all": {
"message": "Alle minimieren"
},
"project.settings.permissions.completed.description": {
"message": "Alle externen Inhalte haben Quellenangaben."
"message": "Alle externen Inhalte sind mit Erlaubnisangaben versehen, und die Quellenangaben wurden angegeben."
},
"project.settings.permissions.completed.title": {
"message": "Zuordnungen abgschlossen!"
"message": "Genehmigungen abgeschlossen!"
},
"project.settings.permissions.empty-state.description": {
"message": "Keine deiner Versionen enrhalten externe Inhalte, also musst du dir keine Sorgen über die Einholung von Berechtigungen machen."
"message": "Keine der Versionen deines Projekts enthält externe Inhalte, weshalb du dir keine Gedanken über die Einholung von Genehmigungen machen musst."
},
"project.settings.permissions.empty-state.heading": {
"message": "Du bist startklar!"
},
"project.settings.permissions.expand-all": {
"message": "Alle anzeigen"
},
"project.settings.permissions.fail.description": {
"message": "Du hast keine Berechtigung, einige der von dir hinzugefügten externen Inhalte weiterzuverbreiten. Um auf Modrinth veröffentlichen zu können, entferne bitte die urheberrechtswidrigen Inhalte."
"message": "Möglicherweise verfügst du nicht über die erforderliche Genehmigung zur Weitergabe einiger externer Inhalte in deinem Projekt. Um dein Projekt auf Modrinth zu veröffentlichen, entferne bitte diese Inhalte oder lege einen Nachweis vor, dass du über die erforderliche Genehmigung zur Nutzung verfügst."
},
"project.settings.permissions.fail.title": {
"message": "Einige Inhalte können nicht enthalten sein"
},
"project.settings.permissions.info-banner.description": {
"message": "Wenn du Inhalte einbindest, welche nicht auf Modrinth gehostet werden, musst du uns deren Quelle mitteilen und bestätigen, dass du die Berechtigung zur Verbreitung der Dateien hast. In <link>unserer Anleitung (Englisch)</link> lernst du, wie du dies am besten machst!"
"message": "Wenn du Inhalte einbindest, welche nicht auf Modrinth gehostet werden, musst du uns deren Quelle mitteilen und bestätigen, dass du die Berechtigung zur Verbreitung der Dateien hast. Schau dir <link>unsere Ankündigung zu diesem neuen System</link> an, um mehr zu erfahren!"
},
"project.settings.permissions.info-banner.title": {
"message": "Lerne wie Zuschreibungen funktionieren"
"message": "Erfahre mehr über die Rechte zur Verbreitung"
},
"project.settings.permissions.learn-more": {
"message": "Mehr erfahren"
},
"project.settings.permissions.no-results": {
"message": "Keine externen Dateien übereinstimmen deiner Suche."
},
"project.settings.permissions.not-allowed.description": {
"message": "Einige der enthaltenen externen Inhalte dürfen auf Modrinth nicht verbreitet werden, da sie gegen unsere Inhaltsrichtlinien verstoßen und daher entfernt werden müssen."
},
"project.settings.permissions.pending-approval-count": {
"message": "{count, plural, =0 {Keine Quellenangaben müssen genehmigt werden} one {# Quellenangabe muss genehmigt werden} other {# Quellenangaben müssen genehmigt werden}}"
},
"project.settings.permissions.search-placeholder": {
"message": "Durchsuche {count} {count, plural, one {externes Projekt} other {externe Projekte}}..."
"message": "Durchsuche {count} {count, plural, one {Projekt} other {Projekten}}..."
},
"project.settings.permissions.sort.most-files": {
"message": "Meiste Dateien"
},
"project.settings.permissions.sort.recently-edited": {
"message": "Letztens bearbeitet"
},
"project.settings.permissions.sort.rejected": {
"message": "Abgelehnt"
},
"project.settings.permissions.sort.status": {
"message": "Status"
},
"project.settings.title": {
"message": "Einstellungen"
@@ -3923,6 +4055,48 @@
"settings.account.security.email.title": {
"message": "E-Mail"
},
"settings.account.security.passkey.add": {
"message": "Passkey hinzufügen"
},
"settings.account.security.passkey.add-modal.name.description": {
"message": "Stell sicher, dass du etwas nimmst, was du dir gut merken kannst, damit du den Passkey später identifizieren kannst."
},
"settings.account.security.passkey.add-modal.name.label": {
"message": "Name"
},
"settings.account.security.passkey.add-modal.name.placeholder": {
"message": "Mein Passkey"
},
"settings.account.security.passkey.description": {
"message": "Verwalte deine gespeicherten Passkeys oder füge einen neuen hinzu."
},
"settings.account.security.passkey.modal.added": {
"message": "Hinzugefügt {ago}"
},
"settings.account.security.passkey.modal.last-used": {
"message": "Zuletzt benutzt {ago}"
},
"settings.account.security.passkey.modal.loading": {
"message": "Passkeys laden..."
},
"settings.account.security.passkey.modal.never-used": {
"message": "Nie benutzt"
},
"settings.account.security.passkey.modal.no-passkeys": {
"message": "Du hast keine registrierten Passkeys."
},
"settings.account.security.passkey.remove.description": {
"message": "Dadurch wird der Passkey „{name}“ endgültig gelöscht. Du kannst dich mit ihm nicht mehr anmelden."
},
"settings.account.security.passkey.remove.title": {
"message": "Möchtest du diesen Passkey wirklich löschen?"
},
"settings.account.security.passkey.rename-modal.header": {
"message": "Passkey umbenennen"
},
"settings.account.security.passkey.title": {
"message": "Passkeys verwalten"
},
"settings.account.security.password.action.add": {
"message": "Passwort hinzufügen"
},
@@ -4535,6 +4709,48 @@
"ui.newsletter-button.tooltip": {
"message": "Abonniere den Modrinth Newsletter"
},
"version.all-versions": {
"message": "Alle Versionen"
},
"version.confirm-delete.description": {
"message": "Diese Version wird endgültig gelöscht. Dieser Vorgang kann nicht rückgängig gemacht werden."
},
"version.confirm-delete.proceed": {
"message": "Version löschen"
},
"version.confirm-delete.title": {
"message": "Willst du diese Version wirklich löschen?"
},
"version.dependency.view-project": {
"message": "Projekt anzeigen"
},
"version.dependency.view-version": {
"message": "Version anzeigen"
},
"version.download.download-dependency": {
"message": "Abhängigkeit herunterladen"
},
"version.download.no-primary-file": {
"message": "Fehler: Keine primäre Datei gefunden"
},
"version.download.optional-resource-pack": {
"message": "Optionales Ressourcenpaket"
},
"version.download.required-resource-pack": {
"message": "Erforderliches Ressourcenpaket"
},
"version.edit.button": {
"message": "Bearbeiten"
},
"version.edit.details": {
"message": "Details bearbeiten"
},
"version.edit.files": {
"message": "Dateien bearbeiten"
},
"version.edit.metadata": {
"message": "Metadaten bearbeiten"
},
"version.environment.none.description": {
"message": "Die Umgebung für diese Version wurde nicht angegeben."
},
@@ -4546,5 +4762,56 @@
},
"version.environment.unknown.title": {
"message": "Unbekannte Umgebung"
},
"version.package-as-mod.button": {
"message": "Als Mod verpacken"
},
"version.package-as-mod.description": {
"message": "Dadurch wird eine neue Version mit Unterstützung für die ausgewählten Mod-Loader erstellt. Du wirst zur neuen Version weitergeleitet und kannst diese nach deinen Wünschen bearbeiten."
},
"version.package-as-mod.header": {
"message": "Datenpaket als Mod packen"
},
"version.package-as-mod.mod-loaders": {
"message": "Modloader"
},
"version.package-as-mod.mod-loaders.description": {
"message": "Die Modloader, für die du dein Datenpaket packen möchtest."
},
"version.package-as-mod.mod-loaders.placeholder": {
"message": "Modloader auswählen..."
},
"version.package-as-mod.submit-button": {
"message": "Datenpaket packen"
},
"version.section.content.dev-info": {
"message": "Informationen für Entwickler"
},
"version.section.content.dev-info.gradle-snippet": {
"message": "build.gradle:"
},
"version.section.content.dev-info.maven-coordinates": {
"message": "Maven-Koordinaten:"
},
"version.section.content.dev-info.maven-description": {
"message": "Projekte auf Modrinth sind automatisch über ein Maven-Repository für die Verwendung mit JVM-Build-Tools wie <gradle-link>Gradle</gradle-link> verfügbar. Um mehr über die Maven-API von Modrinth zu erfahren, <article-link>klicke hier</article-link>."
},
"version.section.content.dev-info.maven-note": {
"message": "Hinweis: Falls verfügbar, solltest du stattdessen das Maven-Repository des Entwicklers verwenden, da dieses Informationen zu transitiven Abhängigkeiten enthält, die in der Maven-API von Modrinth fehlen. Außerdem kann es zu doppelten Abhängigkeiten kommen, wenn du für deine Abhängigkeiten sowohl Modrinth- als auch andere Maven-Repositorys verwendest, da die Gruppen-ID bei der Bereitstellung über die Maven-API von Modrinth abweicht."
},
"version.section.content.dev-info.version-id": {
"message": "Versions-ID:"
},
"version.supplementary-resources.copy-hash-sha1": {
"message": "SHA-1 kopieren"
},
"version.supplementary-resources.copy-hash-sha512": {
"message": "SHA-512 kopieren"
},
"version.unknown-embedded-content.description": {
"message": "Diese Version wird derzeit zurückgehalten und ist nicht öffentlich gelistet. Bitte lege Nachweise vor, dass du zur Verbreitung bestimmter darin enthaltener Dateien berechtigt bist."
},
"version.unknown-embedded-content.title": {
"message": "Wegen unbekannten eingebetteten Inhalten zurückgehalten"
}
}
+329 -62
View File
@@ -23,6 +23,15 @@
"analytics.breakdown.country": {
"message": "Land"
},
"analytics.breakdown.dependent-on": {
"message": "Abhängig von"
},
"analytics.breakdown.dependent-project-download": {
"message": "Abhängiges Projekt"
},
"analytics.breakdown.dependent-project-type": {
"message": "Abhängiger Projekttyp"
},
"analytics.breakdown.download-reason": {
"message": "Downloadgrund"
},
@@ -38,6 +47,9 @@
"analytics.breakdown.loader": {
"message": "Loader"
},
"analytics.breakdown.members": {
"message": "Mitglied"
},
"analytics.breakdown.monetization": {
"message": "Monetarisierung"
},
@@ -60,7 +72,7 @@
"message": "Alle anzeigen"
},
"analytics.chart.action.show-limited": {
"message": "Zeige limitierte"
"message": "Eingeschränkt anzeigen"
},
"analytics.chart.action.show-top-eight": {
"message": "Top 8 anzeigen"
@@ -75,13 +87,13 @@
"message": "Anmerkungen"
},
"analytics.chart.controls.aria": {
"message": "Steuerelemente für Analysediagramm, {activeCount}"
"message": "Einstellungselemente für Analysediagramm, {activeCount}"
},
"analytics.chart.controls.button": {
"message": "Einstellungen"
},
"analytics.chart.controls.dialog-aria": {
"message": "Steuerelemente für Analysediagramm"
"message": "Einstellungselemente für Analysediagramm"
},
"analytics.chart.controls.display": {
"message": "Anzeigen"
@@ -134,6 +146,24 @@
"analytics.chart.render-limit.header": {
"message": "Alle {count} Zeilen im Graphen anzeigen?"
},
"analytics.chart.table-selection.all": {
"message": "Zeige alle {itemType, select, project {{count, plural, one {Projekt} other {Projekte}}} country {{count, plural, one {Land} other {Länder}}} monetization {{count, plural, one {Monetarisierungswert} other {Monetarisierungswerte}}} downloadSource {{count, plural, one {Downloadquelle} other {Downloadquellen}}} downloadReason {{count, plural, one {Downloadgrund} other {Downloadgründe}}} member {{count, plural, one {Mitglied} other {Mitglieder}}} projectVersion {{count, plural, one {Projektversion} other {Projektversionen}}} loader {{count, plural, one {Loader} other {Loader}}} gameVersion {{count, plural, one {Spielversion} other {Spielversionen}}} other {{count, plural, one {Artikel} other {Artikel}}}} aus der Tabelle"
},
"analytics.chart.table-selection.count": {
"message": "Zeige {count} {itemType, select, project {{count, plural, one {Projekt} other {Projekte}}} country {{count, plural, one {Land} other {Länder}}} monetization {{count, plural, one {Monetarisierungswert} other {Monetarisierungswerte}}} downloadSource {{count, plural, one {Downloadquelle} other {Downloadquellen}}} downloadReason {{count, plural, one {Downloadgrund} other {Downloadgründe}}} member {{count, plural, one {Mitglied} other {Mitglieder}}} projectVersion {{count, plural, one {Projektversion} other {Projektversionen}}} loader {{count, plural, one {Loader} other {Loader}}} gameVersion {{count, plural, one {Spielversion} other {Spielversionen}}} other {{count, plural, one {Artikel} other {Artikel}}}} aus der Tabelle"
},
"analytics.chart.table-selection.limited": {
"message": "Zeige {limit} {itemType, select, project {{limit, plural, one {Projekt} other {Projekte}}} country {{limit, plural, one {Land} other {Länder}}} monetization {{limit, plural, one {Monetarisierungswert} other {Monetarisierungswerte}}} downloadSource {{limit, plural, one {Downloadquelle} other {Downloadquellen}}} downloadReason {{limit, plural, one {Downloadgrund} other {Downloadgründe}}} member {{limit, plural, one {Mitglied} other {Mitglieder}}} projectVersion {{limit, plural, one {Projektversion} other {Projektversionen}}} loader {{limit, plural, one {Loader} other {Loader}}} gameVersion {{limit, plural, one {Spielversion} other {Spielversionen}}} other {{limit, plural, one {Artikel} other {Artikel}}}} aus der Tabelle"
},
"analytics.chart.table-selection.top": {
"message": "Zeige die top {count} {itemType, select, project {{count, plural, one {Projekt} other {Projekte}}} country {{count, plural, one {Land} other {Länder}}} monetization {{count, plural, one {Monetarisierungswert} other {Monetarisierungswerte}}} downloadSource {{count, plural, one {Downloadquelle} other {Downloadquellen}}} downloadReason {{count, plural, one {Downloadgrund} other {Downloadgründe}}} member {{count, plural, one {Mitglied} other {Mitglieder}}} projectVersion {{count, plural, one {Projektversion} other {Projektversionen}}} loader {{count, plural, one {Loader} other {Loader}}} gameVersion {{count, plural, one {Spielversion} other {Spielversionen}}} other {{count, plural, one {Artikel} other {Artikel}}}} aus der Tabelle"
},
"analytics.chart.tooltip.dependent-on-project": {
"message": "Abhängig von {project}"
},
"analytics.chart.tooltip.dependent-project-version": {
"message": "{dependentProject} abhängig von {dependencyProject}, {version}"
},
"analytics.chart.tooltip.duration.days": {
"message": "{count, plural, one {# Tag} other {# Tage}}"
},
@@ -218,9 +248,15 @@
"analytics.filter.search.countries": {
"message": "Länder durchsuchen..."
},
"analytics.filter.search.dependent-projects": {
"message": "Projekte durchsuchen..."
},
"analytics.filter.search.download-sources": {
"message": "Download-Quellen durchsuchen..."
},
"analytics.filter.search.members": {
"message": "Mitglieder durchsuchen..."
},
"analytics.filter.search.project-versions": {
"message": "Projektversionen durchsuchen..."
},
@@ -467,6 +503,12 @@
"analytics.value.monetized": {
"message": "Monetarisiert"
},
"analytics.value.no-dependent": {
"message": "Keine"
},
"analytics.value.no-dependent-tooltip": {
"message": "Aus anderen Gründen als einer Abhängigkeit heruntergeladen"
},
"analytics.value.none": {
"message": "Keine"
},
@@ -689,12 +731,72 @@
"auth.authorize.authorize-app-name": {
"message": "Autorisiere {appName}"
},
"auth.authorize.error.missing-parameters": {
"message": "Erforderliche Abfrageparameter für OAuth fehlen."
},
"auth.authorize.error.no-redirect-url": {
"message": "Keine Weiterleitungsziel in Antwort gefunden"
},
"auth.authorize.errro-title": {
"message": "Ein Fehler ist aufgetreten"
},
"auth.authorize.redirect-url": {
"message": "Du wirst zu <redirect-url>{url}</redirect-url> weitergeleitet"
},
"auth.continue-with-provider": {
"message": "Weiter mit {provider}"
},
"auth.create-account.age-requirement.warning-title": {
"message": "Mindestalter"
},
"auth.create-account.complete-sign-up": {
"message": "Registrierung abschließen"
},
"auth.create-account.date-of-birth.invalid.text": {
"message": "Bitte gib ein gültiges Geburtsdatum ein. Das Jahr darf nicht 0000 sein."
},
"auth.create-account.date-of-birth.invalid.title": {
"message": "Ungültiges Geburtsdatum"
},
"auth.create-account.date-of-birth.label": {
"message": "Geburtsdatum"
},
"auth.create-account.date-of-birth.placeholder": {
"message": "Wähle dein Geburtsdatum"
},
"auth.create-account.date-of-birth.required.text": {
"message": "Bitte gib dein Geburtsdatum ein, bevor du fortfährst."
},
"auth.create-account.date-of-birth.required.title": {
"message": "Geburtsdatum erforderlich"
},
"auth.create-account.date-of-birth.under13-helper": {
"message": "Du erfüllst das Mindestalter für die Erstellung eines Kontos bei Modrinth nicht."
},
"auth.create-account.info-panel.source-code-link": {
"message": "Relevanter Quellcode"
},
"auth.create-account.info-panel.text": {
"message": "Wir speichern dein Geburtsdatum nicht. Wir verwenden es ausschließlich bei der Registrierung, um die Einhaltung der COPPA-Vorschriften sicherzustellen."
},
"auth.create-account.page-title": {
"message": "Konto erstellen"
},
"auth.create-account.security-check.label": {
"message": "Sicherheitscheck"
},
"auth.create-account.subscribe.label": {
"message": "Haltet mich per E-Mail über coole Dinge auf dem Laufenden, an denen Modrinth gerade arbeitet"
},
"auth.create-account.title": {
"message": "Ein Konto erstellen"
},
"auth.create-account.username.label": {
"message": "Benutzername"
},
"auth.create-account.username.placeholder": {
"message": "Benutzername eingeben"
},
"auth.reset-password.method-choice.action": {
"message": "E-Mail zur Wiederherstellung senden"
},
@@ -729,23 +831,53 @@
"message": "Dein Passwort zurücksetzen"
},
"auth.sign-in.2fa.description": {
"message": "Bitte gib einen Zwei-Faktor-Code ein, um fortzufahren."
"message": "Gib den 6-stelligen Code aus deiner Authentifikator-App oder einen deiner Backup-Codes ein."
},
"auth.sign-in.2fa.label": {
"message": "Zwei-Faktor-Code eingeben"
"message": "Zwei-Faktor-Authentifizierung"
},
"auth.sign-in.2fa.placeholder": {
"message": "Code eingeben..."
},
"auth.sign-in.continue-with-email": {
"message": "Weiter mit E-Mail"
},
"auth.sign-in.continue-with-passkey": {
"message": "Weiter mit Passkey"
},
"auth.sign-in.create-account": {
"message": "Registrieren"
},
"auth.sign-in.forgot-password": {
"message": "Passwort vergessen"
},
"auth.sign-in.last-sign-in": {
"message": "Zuletzt benutzt"
},
"auth.sign-in.no-account": {
"message": "Du hast kein Konto?"
},
"auth.sign-in.sign-in-with": {
"message": "Anmelden mit"
"message": "Bei Modrinth anmelden"
},
"auth.sign-in.title": {
"message": "Anmelden"
},
"auth.sign-up.age-requirement.warning-title": {
"message": "Mindestalter"
},
"auth.sign-up.continue-with-email": {
"message": "Mit E-Mail fortfahren"
},
"auth.sign-up.legal-dislaimer": {
"message": "Durch die Erstellung eines Kontos stimmst du den <terms-link>Nutzungsbedingungen</terms-link> und der <privacy-policy-link>Datenschutzerklärung</privacy-policy-link> von Modrinth zu."
},
"auth.sign-up.show-fewer-options": {
"message": "Zeige weniger Optionen"
},
"auth.sign-up.show-other-options": {
"message": "Zeige weitere Optionen"
},
"auth.sign-up.sign-in-option.title": {
"message": "Du hast bereits ein Konto?"
},
@@ -753,11 +885,14 @@
"message": "Registrieren"
},
"auth.sign-up.title.sign-up-with": {
"message": "Registrieren mit"
"message": "Ein Konto erstellen"
},
"auth.verify-email.action.account-settings": {
"message": "Kontoeinstellungen"
},
"auth.verify-email.action.discover-mods": {
"message": "Mods entdecken"
},
"auth.verify-email.already-verified.description": {
"message": "Deine E-Mail wurde bereits bestätigt!"
},
@@ -776,6 +911,15 @@
"auth.verify-email.failed-verification.title": {
"message": "E-Mail-Verifizierung fehlgeschlagen"
},
"auth.verify-email.notification.email-sent.description": {
"message": "Eine E-Mail mit einem Link zur Verifizierung deines Accounts wurde an {email} gesendet."
},
"auth.verify-email.notification.email-sent.title": {
"message": "E-Mail gesendet"
},
"auth.verify-email.notification.error-occurred.title": {
"message": "Ein Fehler ist aufgetreten"
},
"auth.verify-email.post-verification.description": {
"message": "Deine E-Mail-Adresse wurde erfolgreich bestätigt!"
},
@@ -1490,9 +1634,6 @@
"dashboard.overview.notifications.loading": {
"message": "Benachrichtigungen werden geladen..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Du kannst mehrere Projekte gleichzeitig bearbeiten, indem du sie unten auswählst."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Serverprojekte unterstützen Massenbearbeitung nicht"
},
@@ -1568,24 +1709,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Bitte überprüfe die Umgebungsmetadaten"
},
"dashboard.projects.sort.ascending": {
"message": "Aufsteigend"
},
"dashboard.projects.sort.descending": {
"message": "Absteigend"
},
"dashboard.projects.sort.option.name": {
"message": "Name"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Typ"
},
"dashboard.projects.table.icon": {
"message": "Icon"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -3098,45 +3221,21 @@
"project.details.licensed": {
"message": "Lizenziert unter"
},
"project.download.game-version": {
"message": "Spielversion: {version}"
},
"project.download.game-version-error": {
"message": "Fehler: Keine Spielversion gefunden"
},
"project.download.game-version-tooltip": {
"message": "{title} ist nur für {version} verfügbar"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} unterstützt {gameVersion} für {platform} nicht"
},
"project.download.install-with-app": {
"message": "Mit Modrinth App installieren"
},
"project.download.no-app": {
"message": "Du hast die Modrinth App nicht?"
},
"project.download.no-versions-available": {
"message": "Keine Versionen für {gameVersion} und {platform} verfügbar."
},
"project.download.platform": {
"message": "Plattform: {platform}"
},
"project.download.platform-error": {
"message": "Fehler: Keine Platform gefunden"
},
"project.download.platform-tooltip": {
"message": "{title} ist nur für {platform} verfügbar"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} unterstützt {platform} für die {gameVersion} nicht"
},
"project.download.search-game-versions": {
"message": "Spielversionen durchsuchen..."
},
"project.download.search-game-versions-label": {
"message": "Spielversionen durchuschen..."
},
"project.download.select-game-version": {
"message": "Spielversion auswählen"
},
@@ -3327,43 +3426,76 @@
"message": "URL"
},
"project.settings.permissions.attention-needed.description.proj-approved": {
"message": "Bitte lege Nachweise vor, dass du die Erlaubnis zur Weiterverbreitung folgender Dateien hast; alle zurückgehaltenen Versionen werden automatisch veröffentlicht."
"message": "Bitte lege Nachweise vor, dass du die Erlaubnis zur Weiterverbreitung folgender Dateien hast. Danach werden die zurückgehaltenen Versionen automatisch veröffentlicht."
},
"project.settings.permissions.attention-needed.description.proj-draft": {
"message": "Bitte lege Nachweise vor, dass du die Erlaubnis zur Weiterverbreitung aller folgenden Dateien hast, bevor du dein Projekt zur Überprüfung einreichen kannst."
"message": "Bitte lege Nachweise vor, dass du die Erlaubnis zur Weiterverbreitung aller folgenden Dateien hast, bevor du dein Projekt zur Überprüfung einreichst."
},
"project.settings.permissions.attention-needed.title": {
"message": "Unbekannter eingebetteter Inhalt"
"message": "Unbekannter externer Inhalt"
},
"project.settings.permissions.bad-proof.description": {
"message": "Das Moderationsteam von Modrinth hat die von dir für einige externe Inhalte vorgelegten Berechtigungsnachweise abgelehnt. Bitte überprüfe die unten aufgeführten abgelehnten Einträge und lege zulässige Nachweise vor oder entfernen die Inhalte."
},
"project.settings.permissions.bad-proof.title": {
"message": "Einige Nachweise wurden abgelehnt"
},
"project.settings.permissions.collapse-all": {
"message": "Alle ausblenden"
},
"project.settings.permissions.completed.description": {
"message": "Alle externen Inhalte haben Quellenangaben."
"message": "Alle externen Inhalte sind mit Erlaubnisangaben versehen, und die Quellenangaben wurden angegeben."
},
"project.settings.permissions.completed.title": {
"message": "Quellenangaben vollständig!"
"message": "Genehmigungen abgeschlossen!"
},
"project.settings.permissions.empty-state.description": {
"message": "Keine deiner Versionen enthält externe Inhalte, du musst du dir keine Gedanken über die Einholung von Genehmigungen machen."
"message": "Keine der Versionen deines Projekts enthält externe Inhalte, weshalb du dir keine Gedanken über die Einholung von Genehmigungen machen musst."
},
"project.settings.permissions.empty-state.heading": {
"message": "Du bist startklar!"
},
"project.settings.permissions.expand-all": {
"message": "Alle anzeigen"
},
"project.settings.permissions.fail.description": {
"message": "Du hast keine Berechtigung, einige der von dir hinzugefügten externen Inhalte weiterzuverbreiten. Entferne die urheberrechtsverletzenden Inhalte, um auf Modrinth veröffentlichen zu können."
"message": "Möglicherweise verfügst du nicht über die erforderliche Genehmigung zur Weitergabe einiger externer Inhalte in deinem Projekt. Um dein Projekt auf Modrinth zu veröffentlichen, entferne bitte diese Inhalte oder lege einen Nachweis vor, dass du über die erforderliche Genehmigung zur Nutzung verfügst."
},
"project.settings.permissions.fail.title": {
"message": "Bestimmte Inhalte können nicht enthalten sein"
},
"project.settings.permissions.info-banner.description": {
"message": "Wenn du Inhalte einbindest, welche nicht auf Modrinth gehostet werden, musst du uns deren Quelle mitteilen und bestätigen, dass du die Berechtigung zur Verbreitung der Dateien hast. In <link>unserer Anleitung</link> lernst du, wie du dies am besten machst!"
"message": "Wenn du Inhalte einbindest, welche nicht auf Modrinth gehostet werden, musst du uns deren Quelle mitteilen und bestätigen, dass du die Berechtigung zur Verbreitung der Dateien hast. Schau dir <link>unsere Ankündigung zu diesem neuen System</link> an, um mehr zu erfahren!"
},
"project.settings.permissions.info-banner.title": {
"message": "So funktionieren Quellenangaben"
"message": "Erfahre mehr über die Rechte zur Verbreitung"
},
"project.settings.permissions.learn-more": {
"message": "Mehr erfahren"
},
"project.settings.permissions.no-results": {
"message": "Keine externen Dateien entsprechen deiner Suche."
},
"project.settings.permissions.not-allowed.description": {
"message": "Einige der enthaltenen externen Inhalte dürfen auf Modrinth nicht verbreitet werden, da sie gegen unsere Inhaltsrichtlinien verstoßen und daher entfernt werden müssen."
},
"project.settings.permissions.pending-approval-count": {
"message": "{count, plural, =0 {Keine Quellenangaben müssen genehmigt werden} one {# Quellenangabe muss genehmigt werden} other {# Quellenangaben müssen genehmigt werden}}"
},
"project.settings.permissions.search-placeholder": {
"message": "Durchsuche {count} {count, plural, one {externes Projekt} other {externe Projekte}}..."
"message": "Durchsuche {count} {count, plural, one {Projekt} other {Projekten}}..."
},
"project.settings.permissions.sort.most-files": {
"message": "Meiste Dateien"
},
"project.settings.permissions.sort.recently-edited": {
"message": "Kürzlich bearbeitet"
},
"project.settings.permissions.sort.rejected": {
"message": "Abgelehnt"
},
"project.settings.permissions.sort.status": {
"message": "Status"
},
"project.settings.title": {
"message": "Einstellungen"
@@ -3923,6 +4055,48 @@
"settings.account.security.email.title": {
"message": "E-Mail"
},
"settings.account.security.passkey.add": {
"message": "Passkey hinzufügen"
},
"settings.account.security.passkey.add-modal.name.description": {
"message": "Stell sicher, dass du etwas nimmst, was du dir gut merken kannst, damit du den Passkey später identifizieren kannst."
},
"settings.account.security.passkey.add-modal.name.label": {
"message": "Name"
},
"settings.account.security.passkey.add-modal.name.placeholder": {
"message": "Mein Passkey"
},
"settings.account.security.passkey.description": {
"message": "Verwalte deine gespeicherten Passkeys oder füge einen neuen hinzu."
},
"settings.account.security.passkey.modal.added": {
"message": "Vor {ago} hinzugefügt"
},
"settings.account.security.passkey.modal.last-used": {
"message": "Zuletzt {ago} verwendet"
},
"settings.account.security.passkey.modal.loading": {
"message": "Passkeys werden geladen…"
},
"settings.account.security.passkey.modal.never-used": {
"message": "Nie verwendet"
},
"settings.account.security.passkey.modal.no-passkeys": {
"message": "Du hast keine registrierten Passkeys."
},
"settings.account.security.passkey.remove.description": {
"message": "Dadurch wird der Passkey „{name}“ endgültig gelöscht. Du kannst dich mit ihm nicht mehr anmelden."
},
"settings.account.security.passkey.remove.title": {
"message": "Möchtest du diesen Passkey wirklich löschen?"
},
"settings.account.security.passkey.rename-modal.header": {
"message": "Passkey umbenennen"
},
"settings.account.security.passkey.title": {
"message": "Passkeys verwalten"
},
"settings.account.security.password.action.add": {
"message": "Passwort hinzufügen"
},
@@ -4535,6 +4709,48 @@
"ui.newsletter-button.tooltip": {
"message": "Abonniere den Modrinth-Newsletter"
},
"version.all-versions": {
"message": "Alle Versionen"
},
"version.confirm-delete.description": {
"message": "Diese Version wird endgültig gelöscht. Dieser Vorgang kann nicht rückgängig gemacht werden."
},
"version.confirm-delete.proceed": {
"message": "Version löschen"
},
"version.confirm-delete.title": {
"message": "Möchtest du diese Version wirklich löschen?"
},
"version.dependency.view-project": {
"message": "Projekt anzeigen"
},
"version.dependency.view-version": {
"message": "Version anzeigen"
},
"version.download.download-dependency": {
"message": "Abhängigkeit herunterladen"
},
"version.download.no-primary-file": {
"message": "Fehler: Keine primäre Datei gefunden"
},
"version.download.optional-resource-pack": {
"message": "Optionales Ressourcenpaket"
},
"version.download.required-resource-pack": {
"message": "Erforderliches Ressourcenpaket"
},
"version.edit.button": {
"message": "Bearbeiten"
},
"version.edit.details": {
"message": "Details bearbeiten"
},
"version.edit.files": {
"message": "Dateien bearbeiten"
},
"version.edit.metadata": {
"message": "Metadaten bearbeiten"
},
"version.environment.none.description": {
"message": "Die Umgebung für diese Version wurde nicht angegeben."
},
@@ -4546,5 +4762,56 @@
},
"version.environment.unknown.title": {
"message": "Unbekannte Umgebung"
},
"version.package-as-mod.button": {
"message": "Als Mod verpacken"
},
"version.package-as-mod.description": {
"message": "Dadurch wird eine neue Version mit Unterstützung für die ausgewählten Mod-Loader erstellt. Du wirst zur neuen Version weitergeleitet und kannst diese nach deinen Wünschen bearbeiten."
},
"version.package-as-mod.header": {
"message": "Datenpaket als Mod packen"
},
"version.package-as-mod.mod-loaders": {
"message": "Modloader"
},
"version.package-as-mod.mod-loaders.description": {
"message": "Die Modloader, für die du dein Datenpaket packen möchtest."
},
"version.package-as-mod.mod-loaders.placeholder": {
"message": "Modloader auswählen..."
},
"version.package-as-mod.submit-button": {
"message": "Datenpaket packen"
},
"version.section.content.dev-info": {
"message": "Informationen für Entwickler"
},
"version.section.content.dev-info.gradle-snippet": {
"message": "build.gradle:"
},
"version.section.content.dev-info.maven-coordinates": {
"message": "Maven-Koordinaten:"
},
"version.section.content.dev-info.maven-description": {
"message": "Projekte auf Modrinth sind automatisch über ein Maven-Repository für die Verwendung mit JVM-Build-Tools wie <gradle-link>Gradle</gradle-link> verfügbar. Um mehr über die Maven-API von Modrinth zu erfahren, <article-link>klicke hier</article-link>."
},
"version.section.content.dev-info.maven-note": {
"message": "Hinweis: Falls verfügbar, solltest du stattdessen das Maven-Repository des Entwicklers verwenden, da dieses Informationen zu transitiven Abhängigkeiten enthält, die in der Maven-API von Modrinth fehlen. Außerdem kann es zu doppelten Abhängigkeiten kommen, wenn du für deine Abhängigkeiten sowohl Modrinth- als auch andere Maven-Repositorys verwendest, da die Gruppen-ID bei der Bereitstellung über die Maven-API von Modrinth abweicht."
},
"version.section.content.dev-info.version-id": {
"message": "Versions-ID:"
},
"version.supplementary-resources.copy-hash-sha1": {
"message": "SHA-1 kopieren"
},
"version.supplementary-resources.copy-hash-sha512": {
"message": "SHA-512 kopieren"
},
"version.unknown-embedded-content.description": {
"message": "Diese Version wird derzeit zurückgehalten und ist nicht öffentlich gelistet. Bitte lege Nachweise vor, dass du zur Verbreitung bestimmter darin enthaltener Dateien berechtigt bist."
},
"version.unknown-embedded-content.title": {
"message": "Wegen unbekannten eingebetteten Inhalten zurückgehalten"
}
}
+129 -42
View File
@@ -518,6 +518,9 @@
"analytics.value.unknown": {
"message": "Unknown"
},
"analytics.value.unknown-dependent-tooltip": {
"message": "There's no metadata to determine which dependent project this download attributes to."
},
"analytics.value.unmonetized": {
"message": "Unmonetized"
},
@@ -1634,9 +1637,6 @@
"dashboard.overview.notifications.loading": {
"message": "Loading notifications..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "You can edit multiple projects at once by selecting them below."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Server projects do not support bulk editing"
},
@@ -1712,23 +1712,11 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Please review environment metadata"
},
"dashboard.projects.sort.ascending": {
"message": "Ascending"
"dashboard.projects.selection-bar.aria-label": {
"message": "Selected projects actions"
},
"dashboard.projects.sort.descending": {
"message": "Descending"
},
"dashboard.projects.sort.option.name": {
"message": "Name"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Type"
},
"dashboard.projects.table.icon": {
"message": "Icon"
"dashboard.projects.selection-bar.selected-count": {
"message": "{count, plural, one {# project selected} other {# projects selected}}"
},
"dashboard.projects.table.id": {
"message": "ID"
@@ -1736,6 +1724,9 @@
"dashboard.projects.table.name": {
"message": "Name"
},
"dashboard.projects.table.select-all-bulk-editable": {
"message": "Select all projects that support bulk editing"
},
"dashboard.projects.table.status": {
"message": "Status"
},
@@ -2681,6 +2672,9 @@
"layout.nav.upgrade-to-modrinth-plus": {
"message": "Upgrade to Modrinth+"
},
"moderation.exclude-technical-review": {
"message": "Exclude TR"
},
"moderation.moderate": {
"message": "Moderate"
},
@@ -2696,6 +2690,45 @@
"moderation.page.technicalReview": {
"message": "Tech review"
},
"modpack-scan-modal.failed": {
"message": "Failed"
},
"modpack-scan-modal.load-versions-error": {
"message": "Failed to load versions: {error}"
},
"modpack-scan-modal.loading-versions": {
"message": "Loading versions..."
},
"modpack-scan-modal.new-files": {
"message": "New Files"
},
"modpack-scan-modal.new-groups": {
"message": "New Groups"
},
"modpack-scan-modal.no-files": {
"message": "No files found."
},
"modpack-scan-modal.not-scanned": {
"message": "Not scanned"
},
"modpack-scan-modal.override-files": {
"message": "Override Files ({count})"
},
"modpack-scan-modal.pack-file-name": {
"message": "Pack File Name"
},
"modpack-scan-modal.scan-all-files": {
"message": "Scan All Files"
},
"modpack-scan-modal.scan-error": {
"message": "Some files failed to scan: {error}"
},
"modpack-scan-modal.scanning": {
"message": "Scanning..."
},
"modpack-scan-modal.title": {
"message": "Modpack Scan ({scanned}/{total} Files)"
},
"muralpay.account-type.checking": {
"message": "Checking"
},
@@ -3242,44 +3275,80 @@
"project.details.licensed": {
"message": "Licensed"
},
"project.download.game-version": {
"message": "Game version: {version}"
"project.download.additional-files-title": {
"message": "Additional files"
},
"project.download.game-version-error": {
"message": "Error: no game versions found"
"project.download.base-game-version-incompatible-tooltip": {
"message": "This game version is incompatible with the base project."
},
"project.download.game-version-tooltip": {
"message": "{title} is only available for {version}"
"project.download.base-loader-incompatible-tooltip": {
"message": "This loader is incompatible with the base project."
},
"project.download.compatible-version-title": {
"message": "Compatible version"
},
"project.download.dependencies-title": {
"message": "Dependencies"
},
"project.download.dependency-already-installed": {
"message": "This dependency is already installed"
},
"project.download.dependency-conflicting": {
"message": "This dependency conflicts with another dependency"
},
"project.download.dependency-download-file": {
"message": "Download {filename}"
},
"project.download.dependency-download-file-with-size": {
"message": "Download {filename} ({size})"
},
"project.download.dependency-duplicate": {
"message": "This dependency is already included"
},
"project.download.dependency-missing-version": {
"message": "This dependency version is unavailable"
},
"project.download.dependency-no-compatible-version": {
"message": "No compatible version is available for this dependency"
},
"project.download.dependency-quilt-fabric-api": {
"message": "Fabric API is skipped for Quilt"
},
"project.download.dependency-unavailable": {
"message": "This dependency cannot be downloaded"
},
"project.download.download-version": {
"message": "Download {version}"
},
"project.download.duplicate-dependencies-hidden": {
"message": "Duplicate dependencies are hidden"
},
"project.download.file-unavailable": {
"message": "This file cannot be downloaded"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} does not support {gameVersion} for {platform}"
},
"project.download.install-with-app": {
"message": "Install with Modrinth App"
"project.download.install-with-app-description": {
"message": "Automatically install the correct version and dependencies."
},
"project.download.manually": {
"message": "Download manually"
},
"project.download.no-app": {
"message": "Don't have Modrinth App?"
},
"project.download.no-game-versions-found": {
"message": "No game versions found"
},
"project.download.no-versions-available": {
"message": "No versions available for {gameVersion} and {platform}."
},
"project.download.platform": {
"message": "Platform: {platform}"
},
"project.download.platform-error": {
"message": "Error: no platforms found"
},
"project.download.platform-tooltip": {
"message": "{title} is only available for {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} does not support {platform} for {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Search game versions..."
},
"project.download.search-game-versions-label": {
"message": "Search game versions..."
"message": "Select game version"
},
"project.download.select-game-version": {
"message": "Select game version"
@@ -3287,12 +3356,27 @@
"project.download.select-platform": {
"message": "Select platform"
},
"project.download.selected-version-download-all": {
"message": "Download all (.zip)"
},
"project.download.selected-version-downloading": {
"message": "Downloading... ({current}/{total})"
},
"project.download.selected-version-failed-text": {
"message": "One or more version files could not be downloaded. Please try again."
},
"project.download.selected-version-failed-title": {
"message": "Could not download version"
},
"project.download.show-all-versions": {
"message": "Show all versions"
},
"project.download.title": {
"message": "Download {title}"
},
"project.download.unknown-loader": {
"message": "Unknown loader"
},
"project.environment.migration-no-permission.message": {
"message": "We've just overhauled the Environments system on Modrinth and new options are now available. You don't have permission to modify these settings, but please let another member of the project know that the environment metadata needs to be verified."
},
@@ -4122,7 +4206,7 @@
"message": "Last used {ago}"
},
"settings.account.security.passkey.modal.loading": {
"message": "Loading passkeys"
"message": "Loading passkeys..."
},
"settings.account.security.passkey.modal.never-used": {
"message": "Never used"
@@ -4773,7 +4857,7 @@
"message": "View version"
},
"version.download.download-dependency": {
"message": "Download dependency"
"message": "Select a version to download"
},
"version.download.no-primary-file": {
"message": "Error: No primary file found"
@@ -4784,6 +4868,9 @@
"version.download.required-resource-pack": {
"message": "Required resource pack"
},
"version.download.version": {
"message": "Download {version} ({size})"
},
"version.edit.button": {
"message": "Edit"
},
+284 -59
View File
@@ -731,12 +731,72 @@
"auth.authorize.authorize-app-name": {
"message": "Autorizar {appName}"
},
"auth.authorize.error.missing-parameters": {
"message": "Faltan los parámetros de consulta OAuth obligatorios."
},
"auth.authorize.error.no-redirect-url": {
"message": "No se encontró una ubicación de redirección en la respuesta"
},
"auth.authorize.errro-title": {
"message": "Se produjo un error"
},
"auth.authorize.redirect-url": {
"message": "Serás redirigido a <redirect-url>{url}</redirect-url>"
},
"auth.continue-with-provider": {
"message": "Continuar con {provider}"
},
"auth.create-account.age-requirement.warning-title": {
"message": "Requisito de edad"
},
"auth.create-account.complete-sign-up": {
"message": "Completar el registro"
},
"auth.create-account.date-of-birth.invalid.text": {
"message": "Por favor, ingresa una fecha de nacimiento válida. El año no puede ser 0000."
},
"auth.create-account.date-of-birth.invalid.title": {
"message": "Fecha de nacimiento no válida"
},
"auth.create-account.date-of-birth.label": {
"message": "Fecha de nacimiento"
},
"auth.create-account.date-of-birth.placeholder": {
"message": "Selecciona tu fecha de nacimiento"
},
"auth.create-account.date-of-birth.required.text": {
"message": "Por favor, ingresa tu fecha de nacimiento antes de continuar."
},
"auth.create-account.date-of-birth.required.title": {
"message": "Se requiere la fecha de nacimiento"
},
"auth.create-account.date-of-birth.under13-helper": {
"message": "No cumples con el requisito de edad para crear una cuenta en Modrinth."
},
"auth.create-account.info-panel.source-code-link": {
"message": "Código fuente relevante"
},
"auth.create-account.info-panel.text": {
"message": "No almacenamos tu fecha de nacimiento. Solo la utilizamos durante el registro para verificar el cumplimiento de la ley COPPA."
},
"auth.create-account.page-title": {
"message": "Crear cuenta"
},
"auth.create-account.security-check.label": {
"message": "Control de seguridad"
},
"auth.create-account.subscribe.label": {
"message": "Manténme al tanto de las cosas geniales en las que está trabajando Modrinth por correo electrónico"
},
"auth.create-account.title": {
"message": "Crear una cuenta"
},
"auth.create-account.username.label": {
"message": "Nombre de usuario"
},
"auth.create-account.username.placeholder": {
"message": "Ingresa tu nombre de usuario"
},
"auth.reset-password.method-choice.action": {
"message": "Enviar correo de recuperación"
},
@@ -771,23 +831,53 @@
"message": "Restablece tu contraseña"
},
"auth.sign-in.2fa.description": {
"message": "Por favor, introduce un código de verificación en dos pasos para continuar."
"message": "Ingresa el código de 6 dígitos de tu aplicación de autenticación o uno de tus códigos de respaldo."
},
"auth.sign-in.2fa.label": {
"message": "Introduce el código de verificación en dos pasos"
"message": "Autenticación de dos factores"
},
"auth.sign-in.2fa.placeholder": {
"message": "Introduce el código..."
},
"auth.sign-in.continue-with-email": {
"message": "Continuar con el correo electrónico"
},
"auth.sign-in.continue-with-passkey": {
"message": "Continuar con la clave de acceso"
},
"auth.sign-in.create-account": {
"message": "Registrarse"
},
"auth.sign-in.forgot-password": {
"message": "Olvidé mi contraseña"
},
"auth.sign-in.last-sign-in": {
"message": "Último inicio de sesión"
},
"auth.sign-in.no-account": {
"message": "¿No tienes una cuenta?"
},
"auth.sign-in.sign-in-with": {
"message": "Iniciar sesión con"
"message": "Inicia sesión en Modrinth"
},
"auth.sign-in.title": {
"message": "Iniciar sesión"
},
"auth.sign-up.age-requirement.warning-title": {
"message": "Requisito de edad"
},
"auth.sign-up.continue-with-email": {
"message": "Continuar con el correo electrónico"
},
"auth.sign-up.legal-dislaimer": {
"message": "Al crear una cuenta, aceptas los <terms-link>Términos</terms-link> y la <privacy-policy-link>Política de privacidad</privacy-policy-link> de Modrinth."
},
"auth.sign-up.show-fewer-options": {
"message": "Mostrar menos opciones"
},
"auth.sign-up.show-other-options": {
"message": "Mostrar otras opciones"
},
"auth.sign-up.sign-in-option.title": {
"message": "¿Ya tienes una cuenta?"
},
@@ -795,11 +885,14 @@
"message": "Registrarse"
},
"auth.sign-up.title.sign-up-with": {
"message": "Registrarse con"
"message": "Crear una cuenta"
},
"auth.verify-email.action.account-settings": {
"message": "Configuración de cuenta"
},
"auth.verify-email.action.discover-mods": {
"message": "Descubre mods"
},
"auth.verify-email.already-verified.description": {
"message": "¡Tu correo ya está verificado!"
},
@@ -818,6 +911,15 @@
"auth.verify-email.failed-verification.title": {
"message": "Error al verificar el correo"
},
"auth.verify-email.notification.email-sent.description": {
"message": "Se ha enviado un correo electrónico con un enlace para verificar tu cuenta a {email}."
},
"auth.verify-email.notification.email-sent.title": {
"message": "Correo electrónico enviado"
},
"auth.verify-email.notification.error-occurred.title": {
"message": "Se produjo un error"
},
"auth.verify-email.post-verification.description": {
"message": "¡Tu correo ha sido verificado correctamente!"
},
@@ -1532,9 +1634,6 @@
"dashboard.overview.notifications.loading": {
"message": "Cargando notificaciones..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Puedes editar varios proyectos a la vez seleccionándolos a continuación."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Los proyectos no son compatible con la edición masiva de servidores"
},
@@ -1610,24 +1709,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Por favor revisa los metadatos de entorno"
},
"dashboard.projects.sort.ascending": {
"message": "Ascendente"
},
"dashboard.projects.sort.descending": {
"message": "Descendente"
},
"dashboard.projects.sort.option.name": {
"message": "Nombre"
},
"dashboard.projects.sort.option.status": {
"message": "Estado"
},
"dashboard.projects.sort.option.type": {
"message": "Tipo"
},
"dashboard.projects.table.icon": {
"message": "Icono"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -3140,45 +3221,21 @@
"project.details.licensed": {
"message": "Con licencia"
},
"project.download.game-version": {
"message": "Versión del juego: {version}"
},
"project.download.game-version-error": {
"message": "Error: no se encontraron versiones del juego"
},
"project.download.game-version-tooltip": {
"message": "{title} solo está disponible para {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} no soporta {gameVersion} para {platform}"
},
"project.download.install-with-app": {
"message": "Instalar con la Modrinth App"
},
"project.download.no-app": {
"message": "¿No tienes la Modrinth App?"
},
"project.download.no-versions-available": {
"message": "No hay versiones disponibles para {gameVersion} y {platform}."
},
"project.download.platform": {
"message": "Plataforma: {platform}"
},
"project.download.platform-error": {
"message": "Error: no se encontraron plataformas"
},
"project.download.platform-tooltip": {
"message": "{title} solo está disponible para {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} no soporta {platform} para {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Buscar versiones del juego..."
},
"project.download.search-game-versions-label": {
"message": "Buscar versiones del juego..."
},
"project.download.select-game-version": {
"message": "Selecciona la versión del juego"
},
@@ -3369,43 +3426,76 @@
"message": "URL"
},
"project.settings.permissions.attention-needed.description.proj-approved": {
"message": "Por favor, proporciona pruebas de que tienes permiso para redistribuir todos estos archivos y cualquier versión retenida se publicará automáticamente."
"message": "Por favor, proporcione prueba de que tiene permiso para redistribuir todos los siguientes archivos. Una vez completado, las versiones retenidas se publicarán automáticamente."
},
"project.settings.permissions.attention-needed.description.proj-draft": {
"message": "Por favor, proporciona pruebas de que tienes permiso para redistribuir todos estos archivos antes de enviar tu proyecto a revisión."
"message": "Por favor, proporcione prueba de que tiene permiso para redistribuir todos los siguientes archivos antes de enviar su proyecto para revisión."
},
"project.settings.permissions.attention-needed.title": {
"message": "Incluye contenido desconocido"
"message": "Contenido externo desconocido"
},
"project.settings.permissions.bad-proof.description": {
"message": "El equipo de moderación de Modrinth ha rechazado la información de permisos que proporcionaste para algún contenido externo. Por favor, revise los elementos rechazados a continuación y proporcione pruebas aceptables o elimine el contenido."
},
"project.settings.permissions.bad-proof.title": {
"message": "Algunas pruebas fueron rechazadas."
},
"project.settings.permissions.collapse-all": {
"message": "Colapsar todo"
},
"project.settings.permissions.completed.description": {
"message": "Todo el contenido externo proporciona atribuciones."
"message": "Todo el contenido externo tiene información de permisos y se han proporcionado las atribuciones."
},
"project.settings.permissions.completed.title": {
"message": Atribuciones completadas!"
"message": Permisos completados!"
},
"project.settings.permissions.empty-state.description": {
"message": "Ninguna de tus versiones presenta contenido externo, por lo que no necesitas preocuparte de obtener permisos."
"message": "Ninguna de las versiones de tu proyecto contiene contenido externo, así que no necesitas preocuparte por obtener permisos."
},
"project.settings.permissions.empty-state.heading": {
"message": "¡Ya estás listo!"
},
"project.settings.permissions.expand-all": {
"message": "Expandir todo"
},
"project.settings.permissions.fail.description": {
"message": "No tienes permiso de redistribuir parte del contenido externo que añadiste. Para poder publicar en Modrinth, quite el contenido infractor."
"message": "Es posible que no tengas permiso para redistribuir parte del contenido externo en tu proyecto. Para publicar en Modrinth, por favor elimina este contenido o proporciona prueba de que tienes permiso para usarlo."
},
"project.settings.permissions.fail.title": {
"message": "No se puede incluir parte del contenido"
},
"project.settings.permissions.info-banner.description": {
"message": "Si incluyes contenido que no está alojado en Modrinth, debes indicarnos de dónde es y verificar que tienes permiso para distribuir los archivos. ¡Mira <link>nuestra guía</link> para saber cómo hacerlo correctamente!"
"message": "Si incluyes contenido que no esté alojado en Modrinth, debes informarnos de dónde proviene y verificar que tienes permiso para distribuir los archivos. Consulta <link>nuestro anuncio de este nuevo sistema</link> para obtener más información."
},
"project.settings.permissions.info-banner.title": {
"message": "Aprende cómo funcionan las atribuciones"
"message": "Aprende sobre los permisos de distribución"
},
"project.settings.permissions.learn-more": {
"message": "Aprender más"
},
"project.settings.permissions.no-results": {
"message": "No hay archivos externos que coincidan con tu búsqueda."
},
"project.settings.permissions.not-allowed.description": {
"message": "Parte del contenido externo incluido no puede ser distribuido en Modrinth porque viola nuestras Reglas de Contenido y debe ser eliminado."
},
"project.settings.permissions.pending-approval-count": {
"message": "{count, plural, =0 {No se necesita aprobación para las atribuciones} one {# atribución necesita aprobación} other {# atribuciones necesitan aprobación}}"
},
"project.settings.permissions.search-placeholder": {
"message": "Busca {count} {count, plural, one {proyecto externo} other {proyectos externos}}..."
"message": "Buscar {count} {count, plural, one {proyecto} other {proyectos}}..."
},
"project.settings.permissions.sort.most-files": {
"message": "La mayoría de los archivos"
},
"project.settings.permissions.sort.recently-edited": {
"message": "Recientemente editado"
},
"project.settings.permissions.sort.rejected": {
"message": "Rechazado"
},
"project.settings.permissions.sort.status": {
"message": "Estado"
},
"project.settings.title": {
"message": "Configuración"
@@ -3965,6 +4055,48 @@
"settings.account.security.email.title": {
"message": "Correo electrónico"
},
"settings.account.security.passkey.add": {
"message": "Agregar clave de acceso"
},
"settings.account.security.passkey.add-modal.name.description": {
"message": "Asegúrate de elegir algo fácil de recordar, para que puedas identificar esta contraseña más adelante."
},
"settings.account.security.passkey.add-modal.name.label": {
"message": "Nombre"
},
"settings.account.security.passkey.add-modal.name.placeholder": {
"message": "Mi clave de acceso"
},
"settings.account.security.passkey.description": {
"message": "Administra tus claves de acceso registradas o agrega una nueva."
},
"settings.account.security.passkey.modal.added": {
"message": "Agregado {ago}"
},
"settings.account.security.passkey.modal.last-used": {
"message": "Último uso {ago}"
},
"settings.account.security.passkey.modal.loading": {
"message": "Cargando claves de acceso…"
},
"settings.account.security.passkey.modal.never-used": {
"message": "Nunca usado"
},
"settings.account.security.passkey.modal.no-passkeys": {
"message": "No tienes ninguna clave de acceso registrada."
},
"settings.account.security.passkey.remove.description": {
"message": "Esto eliminará de forma permanente la clave de acceso \"{name}\". Ya no podrás iniciar sesión con ella."
},
"settings.account.security.passkey.remove.title": {
"message": "¿Estás seguro de que quieres eliminar esta clave de acceso?"
},
"settings.account.security.passkey.rename-modal.header": {
"message": "Renombrar clave de acceso"
},
"settings.account.security.passkey.title": {
"message": "Administrar claves de acceso"
},
"settings.account.security.password.action.add": {
"message": "Añadir contraseña"
},
@@ -4577,6 +4709,48 @@
"ui.newsletter-button.tooltip": {
"message": "Suscríbete a las noticias de Modrinth"
},
"version.all-versions": {
"message": "Todas las versiones"
},
"version.confirm-delete.description": {
"message": "Esta versión será eliminada permanentemente. Esta acción no se puede deshacer."
},
"version.confirm-delete.proceed": {
"message": "Eliminar versión"
},
"version.confirm-delete.title": {
"message": "¿Estás seguro de que quieres eliminar esta versión?"
},
"version.dependency.view-project": {
"message": "Ver proyecto"
},
"version.dependency.view-version": {
"message": "Ver versión"
},
"version.download.download-dependency": {
"message": "Descargar dependencia"
},
"version.download.no-primary-file": {
"message": "Error: No se encontró el archivo principal"
},
"version.download.optional-resource-pack": {
"message": "Paquete de recursos opcional"
},
"version.download.required-resource-pack": {
"message": "Paquete de recursos requerido"
},
"version.edit.button": {
"message": "Editar"
},
"version.edit.details": {
"message": "Editar detalles"
},
"version.edit.files": {
"message": "Editar archivos"
},
"version.edit.metadata": {
"message": "Editar metadatos"
},
"version.environment.none.description": {
"message": "No se ha especificado el entorno para esta versión."
},
@@ -4588,5 +4762,56 @@
},
"version.environment.unknown.title": {
"message": "Entorno desconocido"
},
"version.package-as-mod.button": {
"message": "Empaquetar como mod"
},
"version.package-as-mod.description": {
"message": "Esto creará una nueva versión con soporte para los cargadores de mods seleccionados. Serás redirigido a la nueva versión y podrás editarla a tu gusto."
},
"version.package-as-mod.header": {
"message": "Empaquetar datapack como mod"
},
"version.package-as-mod.mod-loaders": {
"message": "Cargadores de mods"
},
"version.package-as-mod.mod-loaders.description": {
"message": "Los cargadores de mods para los que te gustaría empaquetar tu paquete de datos"
},
"version.package-as-mod.mod-loaders.placeholder": {
"message": "Elige cargadores de mods..."
},
"version.package-as-mod.submit-button": {
"message": "Paquete de datos"
},
"version.section.content.dev-info": {
"message": "Información del desarrollador"
},
"version.section.content.dev-info.gradle-snippet": {
"message": "build.gradle:"
},
"version.section.content.dev-info.maven-coordinates": {
"message": "Coordenadas de Maven:"
},
"version.section.content.dev-info.maven-description": {
"message": "Los proyectos en Modrinth están automáticamente disponibles a través de un repositorio Maven para su uso con herramientas de construcción de JVM como <gradle-link>Gradle</gradle-link>. Para obtener más información sobre la API de Modrinth Maven, <article-link>haga clic aquí</article-link>."
},
"version.section.content.dev-info.maven-note": {
"message": "Nota: Cuando esté disponible, deberías usar el repositorio maven del creador en su lugar, ya que tendrá información sobre las dependencias transitivas que la API de Modrinth Maven no tiene. También puedes terminar con dependencias duplicadas si usas una mezcla de repositorios Maven de Modrinth y no Modrinth para tus dependencias, porque el identificador de grupo será diferente cuando se sirva a través de la API de Maven de Modrinth."
},
"version.section.content.dev-info.version-id": {
"message": "ID de versión:"
},
"version.supplementary-resources.copy-hash-sha1": {
"message": "Copiar SHA-1"
},
"version.supplementary-resources.copy-hash-sha512": {
"message": "Copiar SHA-512"
},
"version.unknown-embedded-content.description": {
"message": "Esta versión está actualmente retenida y no está listada públicamente. Por favor, proporcione prueba de que tiene permiso para redistribuir ciertos archivos incluidos."
},
"version.unknown-embedded-content.title": {
"message": "Retenido debido a contenido incrustado desconocido"
}
}
+136 -67
View File
@@ -770,18 +770,9 @@
"auth.reset-password.title.long": {
"message": "Restablecer tu contraseña"
},
"auth.sign-in.2fa.description": {
"message": "Por favor introduce el código de autenticación de dos factores para continuar."
},
"auth.sign-in.2fa.label": {
"message": "Introduce el código de autenticación de dos factores"
},
"auth.sign-in.2fa.placeholder": {
"message": "Introducir código..."
},
"auth.sign-in.sign-in-with": {
"message": "Iniciar sesión con"
},
"auth.sign-in.title": {
"message": "Iniciar sesión"
},
@@ -794,9 +785,6 @@
"auth.sign-up.title": {
"message": "Registro"
},
"auth.sign-up.title.sign-up-with": {
"message": "Registrarse con"
},
"auth.verify-email.action.account-settings": {
"message": "Ajustes de cuenta"
},
@@ -1529,9 +1517,6 @@
"dashboard.overview.notifications.loading": {
"message": "Cargando notificaciones..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Puedes editar múltiples proyectos a la vez seleccionándolos abajo."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Proyectos de servidor no soportan edición masiva"
},
@@ -1604,24 +1589,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Por favor revise el entorno del metadata"
},
"dashboard.projects.sort.ascending": {
"message": "Ascendiendo"
},
"dashboard.projects.sort.descending": {
"message": "Descendiendo"
},
"dashboard.projects.sort.option.name": {
"message": "Nombre"
},
"dashboard.projects.sort.option.status": {
"message": "Estado"
},
"dashboard.projects.sort.option.type": {
"message": "Tipo"
},
"dashboard.projects.table.icon": {
"message": "Icono"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -3134,45 +3101,21 @@
"project.details.licensed": {
"message": "Con licencia"
},
"project.download.game-version": {
"message": "Versión del juego: {version}"
},
"project.download.game-version-error": {
"message": "Error: no se han encontrado versiones del juego"
},
"project.download.game-version-tooltip": {
"message": "{title} solo está disponible para {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} no está soportado para la versión {gameVersion} de {platform}"
},
"project.download.install-with-app": {
"message": "Instalar con la aplicación Modrinth"
},
"project.download.no-app": {
"message": "¿No tienes la aplicación Modrinth?"
},
"project.download.no-versions-available": {
"message": "No hay versiones disponibles para {gameVersion} y {platform}."
},
"project.download.platform": {
"message": "Plataforma: {platform}"
},
"project.download.platform-error": {
"message": "Error: plataforma no encontrada"
},
"project.download.platform-tooltip": {
"message": "{title} olo está disponible para {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} no está soportado para {platform} en la {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Buscar versiones del juego..."
},
"project.download.search-game-versions-label": {
"message": "Buscar versiones del juego..."
},
"project.download.select-game-version": {
"message": "Selecciona la versión del juego"
},
@@ -3363,43 +3306,76 @@
"message": "URL"
},
"project.settings.permissions.attention-needed.description.proj-approved": {
"message": "Por favor, proporciona pruebas de que tienes permiso para redistribuir todos estos archivos y cualquier versión retenida se publicará automáticamente."
"message": "Por favor, proporciona una prueba de que tienes permiso para redistribuir todos los siguientes archivos. Una vez completado, las versiones retenidas se publicarán automáticamente."
},
"project.settings.permissions.attention-needed.description.proj-draft": {
"message": "Por favor, proporciona pruebas de que tienes permiso para redistribuir todos estos archivos antes de enviar tu proyecto a revisión."
"message": "Por favor, proporciona una prueba de que tiene permiso para redistribuir todos los siguientes archivos antes de enviar su proyecto para su revisión."
},
"project.settings.permissions.attention-needed.title": {
"message": "Incluye contenido desconocido"
"message": "Contenido externo desconocido"
},
"project.settings.permissions.bad-proof.description": {
"message": "El equipo de moderación de Modrinth ha rechazado la información de permisos que proporcionaste para cierto contenido externo. Revisa los elementos rechazados a continuación y proporciona una prueba aceptable o elimina el contenido."
},
"project.settings.permissions.bad-proof.title": {
"message": "Algunas pruebas fueron rechazadas"
},
"project.settings.permissions.collapse-all": {
"message": "Desbloquear todo"
},
"project.settings.permissions.completed.description": {
"message": "Todo el contenido externo proporciona atribuciones."
"message": "Todo el contenido externo cuenta con información de permisos y se han proporcionado las atribuciones correspondientes."
},
"project.settings.permissions.completed.title": {
"message": Atribuciones completadas!"
"message": Permisos completados!"
},
"project.settings.permissions.empty-state.description": {
"message": "Ninguna de tus versiones presenta contenido externo, por lo que no necesitas preocuparte de obtener permisos."
"message": "Ninguna de las versiones de tu proyecto contiene contenido externo, por lo que no necesitas preocuparte por obtener permisos."
},
"project.settings.permissions.empty-state.heading": {
"message": "¡Ya estás listo!"
},
"project.settings.permissions.expand-all": {
"message": "Expandir todo"
},
"project.settings.permissions.fail.description": {
"message": "No tienes permiso de redistribuir parte del contenido externo que añadiste. Para poder publicar en Modrinth, quita el contenido infractor."
"message": "Es posible que no tengas permiso para redistribuir parte del contenido externo en tu proyecto. Para publicar en Modrinth, por favor elimina este contenido o proporciona una prueba de que tienes permiso para usarlo."
},
"project.settings.permissions.fail.title": {
"message": "No se puede incluir parte del contenido"
},
"project.settings.permissions.info-banner.description": {
"message": "Si incluyes contenido que no está alojado en Modrinth, necesitas comunicarnos de dónde viene y verificar que tienes permiso para distribuir los archivos. ¡Mira <link>nuestra guía</link> para saber cómo hacerlo correctamente!"
"message": "Si incluyes contenido que no esté alojado en Modrinth, debes informarnos de dónde proviene y verificar que tienes permiso para distribuir los archivos. ¡Consulta <link>nuestro anuncio de este nuevo sistema</link> para obtener más información!"
},
"project.settings.permissions.info-banner.title": {
"message": "Aprende cómo funcionan las atribuciones"
"message": "Más información sobre los permisos de distribución"
},
"project.settings.permissions.learn-more": {
"message": "Saber más"
},
"project.settings.permissions.no-results": {
"message": "No hay archivos externos que coincidan con tu búsqueda."
},
"project.settings.permissions.not-allowed.description": {
"message": "Parte del contenido externo incluido no puede distribuirse en Modrinth porque infringe nuestras Normas de Contenido y debe eliminarse."
},
"project.settings.permissions.pending-approval-count": {
"message": "{count, plural, =0 {No hay atribuciones que necesiten aprobación} one {Una atribución necesita aprobación} other {# atribuciones necesitan aprobación}}"
},
"project.settings.permissions.search-placeholder": {
"message": "Buscar {count} {count, plural, one {proyecto externo} other {proyectos externos}}..."
"message": "Buscar {count} {count, plural, one {proyecto} other {proyectos}}..."
},
"project.settings.permissions.sort.most-files": {
"message": "La mayoría de los archivos"
},
"project.settings.permissions.sort.recently-edited": {
"message": "Recientemente editado"
},
"project.settings.permissions.sort.rejected": {
"message": "Rechazado"
},
"project.settings.permissions.sort.status": {
"message": "Estado"
},
"project.settings.title": {
"message": "Ajustes"
@@ -4571,6 +4547,48 @@
"ui.newsletter-button.tooltip": {
"message": "Suscríbete al boletín de noticias de Modrinth"
},
"version.all-versions": {
"message": "Todas las versiones"
},
"version.confirm-delete.description": {
"message": "Esta versión será permanentemente eliminado. Esta acción no se puede deshacer."
},
"version.confirm-delete.proceed": {
"message": "Eliminar versión"
},
"version.confirm-delete.title": {
"message": "¿Estás seguro de que quieres eliminar esta versión?"
},
"version.dependency.view-project": {
"message": "Ver proyecto"
},
"version.dependency.view-version": {
"message": "Ver versión"
},
"version.download.download-dependency": {
"message": "Descargar dependencia"
},
"version.download.no-primary-file": {
"message": "Error: No se encontró el archivo principal"
},
"version.download.optional-resource-pack": {
"message": "Resourse pack opcional"
},
"version.download.required-resource-pack": {
"message": "Resourse pack requerido"
},
"version.edit.button": {
"message": "Editar"
},
"version.edit.details": {
"message": "Editar detalles"
},
"version.edit.files": {
"message": "Editar archivos"
},
"version.edit.metadata": {
"message": "Editar metadatos"
},
"version.environment.none.description": {
"message": "El entorno para esta versión no ha sido especificado."
},
@@ -4582,5 +4600,56 @@
},
"version.environment.unknown.title": {
"message": "Entorno desconocido"
},
"version.package-as-mod.button": {
"message": "Paquete como mod"
},
"version.package-as-mod.description": {
"message": "Esto creará una nueva versión con soporte a los loader seleccionados. Serás redireccionado a la nueva versión para que puedas editarla a tu gusto."
},
"version.package-as-mod.header": {
"message": "Empaquetar datapack como mod"
},
"version.package-as-mod.mod-loaders": {
"message": "Loaders de mods"
},
"version.package-as-mod.mod-loaders.description": {
"message": "Los loaders para los que te gustaría empaquetar tu datapack."
},
"version.package-as-mod.mod-loaders.placeholder": {
"message": "Elige los loaders..."
},
"version.package-as-mod.submit-button": {
"message": "Empaquetar datapack"
},
"version.section.content.dev-info": {
"message": "Información del desarrollador"
},
"version.section.content.dev-info.gradle-snippet": {
"message": "build.gradle:"
},
"version.section.content.dev-info.maven-coordinates": {
"message": "Coordenadas de Maven:"
},
"version.section.content.dev-info.maven-description": {
"message": "Los proyectos en Modrinth están disponibles automáticamente a través de un repositorio Maven para su uso con herramientas de compilación JVM como <gradle-link>Gradle</gradle-link>. Para obtener más información sobre la API Maven de Modrinth, <article-link>presiona aquí</article-link>."
},
"version.section.content.dev-info.maven-note": {
"message": "Nota: Cuando esté disponible, debería usar el repositorio Maven del creador, ya que contendrá información de dependencia transitiva que la API Maven de Modrinth no tiene. También podría terminar con dependencias duplicadas si usa una combinación de repositorios Maven de Modrinth y de otros proveedores para sus dependencias, porque el identificador de grupo será diferente cuando se sirva a través de la API Maven de Modrinth."
},
"version.section.content.dev-info.version-id": {
"message": "ID de la versión:"
},
"version.supplementary-resources.copy-hash-sha1": {
"message": "Copiar SHA-1"
},
"version.supplementary-resources.copy-hash-sha512": {
"message": "Copiar SHA-512"
},
"version.unknown-embedded-content.description": {
"message": "Esta versión está actualmente retenida y no está listada públicamente. Por favor, proporcione prueba de que tiene permiso para redistribuir ciertos archivos incluidos."
},
"version.unknown-embedded-content.title": {
"message": "Retenido debido a contenido incrustado desconocido"
}
}
+24 -30
View File
@@ -8,6 +8,24 @@
"admin.billing.error.not-found": {
"message": "Käyttäjää ei löydetty"
},
"analytics.action.add": {
"message": "Lisää"
},
"analytics.action.cancel": {
"message": "Peruuta"
},
"analytics.action.refresh": {
"message": "Päivitä"
},
"analytics.action.reset": {
"message": "Palauta"
},
"analytics.breakdown.country": {
"message": "Valtio"
},
"analytics.breakdown.dependent-on": {
"message": "Riippuu kohteesta"
},
"app-marketing.download.description": {
"message": "Työpöytä sovelluksemme on saatavilla kaikilla alustoilla, valitse haluamasi versio."
},
@@ -254,18 +272,9 @@
"auth.reset-password.title.long": {
"message": "Palauta salasanasi"
},
"auth.sign-in.2fa.description": {
"message": "Syötä 2-vaiheisen tunnistautumisen koodi jatkaaksesi."
},
"auth.sign-in.2fa.label": {
"message": "Syötä 2-vaiheisen tunnistautumisen koodi"
},
"auth.sign-in.2fa.placeholder": {
"message": "Anna koodi..."
},
"auth.sign-in.sign-in-with": {
"message": "Kirjaudu sisään käyttäen"
},
"auth.sign-in.title": {
"message": "Kirjaudu sisään"
},
@@ -278,9 +287,6 @@
"auth.sign-up.title": {
"message": "Rekisteröidy"
},
"auth.sign-up.title.sign-up-with": {
"message": "Reskiteröidy käyttäen"
},
"auth.verify-email.action.account-settings": {
"message": "Tilin asetukset"
},
@@ -335,6 +341,12 @@
"collection.delete-modal.title": {
"message": "Oletko varma että haluat poistaa tämän kokoelman?"
},
"collection.description": {
"message": "{description} - Katso kokoelma {name}, jonka on luonut {username}, Modrinthissa"
},
"collection.description.following": {
"message": "Automattisesti luotu kokoelma kaikista projekteista joita seuraat."
},
"collection.editing": {
"message": "Muokataan kokoelmaa"
},
@@ -599,24 +611,6 @@
"dashboard.projects.project.icon-alt": {
"message": "Kuvake projektille {title}"
},
"dashboard.projects.sort.ascending": {
"message": "Nouseva"
},
"dashboard.projects.sort.descending": {
"message": "Laskeva"
},
"dashboard.projects.sort.option.name": {
"message": "Nimi"
},
"dashboard.projects.sort.option.status": {
"message": "Tila"
},
"dashboard.projects.sort.option.type": {
"message": "Tyyppi"
},
"dashboard.projects.table.icon": {
"message": "Kuvake"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -386,18 +386,9 @@
"auth.reset-password.title.long": {
"message": "Baguhin ang iyong password"
},
"auth.sign-in.2fa.description": {
"message": "Pakilagay ng two-factor code upang makapagpatuloy."
},
"auth.sign-in.2fa.label": {
"message": "Ilagay ang two-factor code"
},
"auth.sign-in.2fa.placeholder": {
"message": "Ilagay ang code..."
},
"auth.sign-in.sign-in-with": {
"message": "Mag-sign in gamit ang"
},
"auth.sign-in.title": {
"message": "Mag-sign In"
},
@@ -410,9 +401,6 @@
"auth.sign-up.title": {
"message": "Mag-sign Up"
},
"auth.sign-up.title.sign-up-with": {
"message": "Mag-sign up gamit ang"
},
"auth.verify-email.action.account-settings": {
"message": "Mga setting sa account"
},
@@ -1010,18 +998,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Pakisuri sa metadata sa environment"
},
"dashboard.projects.sort.option.name": {
"message": "Pangalan"
},
"dashboard.projects.sort.option.status": {
"message": "Estado"
},
"dashboard.projects.sort.option.type": {
"message": "Uri"
},
"dashboard.projects.table.icon": {
"message": "Ikono"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -2432,45 +2408,21 @@
"project.details.licensed": {
"message": "Lisensiyang"
},
"project.download.game-version": {
"message": "Bersiyon ng laro: {version}"
},
"project.download.game-version-error": {
"message": "Error: walang mahanap na mga bersiyon ng laro"
},
"project.download.game-version-tooltip": {
"message": "Ang {title} ay magagamit lamang sa {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "Hindi masuporta ng {title} ang {gameVersion} para sa {platform}"
},
"project.download.install-with-app": {
"message": "I-install gamit ang Modrinth App"
},
"project.download.no-app": {
"message": "Wala kang Modrinth App?"
},
"project.download.no-versions-available": {
"message": "Walang bersiyong magagamit para sa {gameVersion} at {platform}."
},
"project.download.platform": {
"message": "Plataporma: {platform}"
},
"project.download.platform-error": {
"message": "Error: walang mahanap na platform"
},
"project.download.platform-tooltip": {
"message": "Ang {title} ay magagamit lamang sa {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "Hindi masuport ng {title} ang {platform} para sa {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Maghanap ng mga bersiyon ng laro..."
},
"project.download.search-game-versions-label": {
"message": "Maghanap ng mga bersiyon ng laro..."
},
"project.download.select-game-version": {
"message": "Piliin ang lahat ng bersiyon ng laro"
},
@@ -2585,9 +2537,6 @@
"project.settings.general.url.title": {
"message": "URL"
},
"project.settings.permissions.info-banner.description": {
"message": "Kung magsasama ka ng mga kontentong hindi naka-host sa Modrinth, kailangan niyong ipaalam sa amin sa pinanggalingan nito at matiyak na pinahintulutang mapakalat ang mga file. Tingnan ang <link>aming gabay</link> upang matuto kung papaano ito magawa nang maayos!"
},
"project.settings.title": {
"message": "Mga Setting"
},
+284 -59
View File
@@ -731,12 +731,72 @@
"auth.authorize.authorize-app-name": {
"message": "Autoriser {appName}"
},
"auth.authorize.error.missing-parameters": {
"message": "Paramètres de requête d'authentification obligatoires manquants."
},
"auth.authorize.error.no-redirect-url": {
"message": "Pas d'adresse de redirection trouvée dans la réponse"
},
"auth.authorize.errro-title": {
"message": "Une Erreur est Survenue"
},
"auth.authorize.redirect-url": {
"message": "Vous serez redirigé vers <redirect-url>{url}</redirect-url>"
},
"auth.continue-with-provider": {
"message": "Continuer avec {provider}"
},
"auth.create-account.age-requirement.warning-title": {
"message": "Conditions d'âge"
},
"auth.create-account.complete-sign-up": {
"message": "Terminer l'inscription"
},
"auth.create-account.date-of-birth.invalid.text": {
"message": "Veuillez entrer une année de naissance valide. L'année ne peut pas être 0000."
},
"auth.create-account.date-of-birth.invalid.title": {
"message": "Date de naissance invalide"
},
"auth.create-account.date-of-birth.label": {
"message": "Date de naissance"
},
"auth.create-account.date-of-birth.placeholder": {
"message": "Choisissez votre date de naissance"
},
"auth.create-account.date-of-birth.required.text": {
"message": "Veuillez entrer votre date de naissance avant de continuer."
},
"auth.create-account.date-of-birth.required.title": {
"message": "Date de naissance requise"
},
"auth.create-account.date-of-birth.under13-helper": {
"message": "Vous ne rencontrez pas les conditions d'âge requises pour créer un compte sur Modrinth."
},
"auth.create-account.info-panel.source-code-link": {
"message": "Code source pertinent"
},
"auth.create-account.info-panel.text": {
"message": "Nous ne conservons pas votre date de naissance. Nous l'utilisons uniquement lors de l'inscription pour vérifier la conformité avec la loi COPPA."
},
"auth.create-account.page-title": {
"message": "Créer un Compte"
},
"auth.create-account.security-check.label": {
"message": "Vérification de sécurité"
},
"auth.create-account.subscribe.label": {
"message": "Me tenir au courant des trucs cools sur lesquels Modrinth travaille par e-mail"
},
"auth.create-account.title": {
"message": "Créer un Compte"
},
"auth.create-account.username.label": {
"message": "Pseudo"
},
"auth.create-account.username.placeholder": {
"message": "Entrez un pseudo"
},
"auth.reset-password.method-choice.action": {
"message": "Envoyez un e-mail de récupération"
},
@@ -771,23 +831,53 @@
"message": "Réinitialiser votre mot de passe"
},
"auth.sign-in.2fa.description": {
"message": "Veuillez entrer un code à double facteur pour continuer."
"message": "Entrez le code à 6 chiffres de votre application d'authentification, ou un de vos codes de secours."
},
"auth.sign-in.2fa.label": {
"message": "Saisir le code à double facteur"
"message": "Authentification à deux facteurs"
},
"auth.sign-in.2fa.placeholder": {
"message": "Saisir le code..."
},
"auth.sign-in.continue-with-email": {
"message": "Continuer avec un E-mail"
},
"auth.sign-in.continue-with-passkey": {
"message": "Continuer avec une clé d'accès"
},
"auth.sign-in.create-account": {
"message": "S'inscrire"
},
"auth.sign-in.forgot-password": {
"message": "Mot de passe oublié"
},
"auth.sign-in.last-sign-in": {
"message": "Dernière utilisation"
},
"auth.sign-in.no-account": {
"message": "Vous n'avez pas de compte ?"
},
"auth.sign-in.sign-in-with": {
"message": "Se connecter avec"
"message": "Se connecter à Modrinth"
},
"auth.sign-in.title": {
"message": "Se connecter"
},
"auth.sign-up.age-requirement.warning-title": {
"message": "Conditions d'âge"
},
"auth.sign-up.continue-with-email": {
"message": "Continuer avec un E-mail"
},
"auth.sign-up.legal-dislaimer": {
"message": "En créant un compte, vous acceptez les <terms-link>Conditions d'utilisation</terms-link> et la <privacy-policy-link>Politique de confidentialité</privacy-policy-link> de Modrinth."
},
"auth.sign-up.show-fewer-options": {
"message": "Voir moins d'options"
},
"auth.sign-up.show-other-options": {
"message": "Voir plus d'options"
},
"auth.sign-up.sign-in-option.title": {
"message": "Vous avez déjà un compte ?"
},
@@ -795,11 +885,14 @@
"message": "S'inscrire"
},
"auth.sign-up.title.sign-up-with": {
"message": "S'inscrire avec"
"message": "Créer un Compte"
},
"auth.verify-email.action.account-settings": {
"message": "Paramètres du compte"
},
"auth.verify-email.action.discover-mods": {
"message": "Découvrez des mods"
},
"auth.verify-email.already-verified.description": {
"message": "Votre adresse e-mail est déjà vérifiée !"
},
@@ -818,6 +911,15 @@
"auth.verify-email.failed-verification.title": {
"message": "La vérification de l'adresse e-mail a échouée"
},
"auth.verify-email.notification.email-sent.description": {
"message": "Un e-mail avec un lien pour vérifier votre compte a été envoyé à {email}."
},
"auth.verify-email.notification.email-sent.title": {
"message": "E-mail envoyé"
},
"auth.verify-email.notification.error-occurred.title": {
"message": "Une erreur est survenue"
},
"auth.verify-email.post-verification.description": {
"message": "Votre adresse e-mail a été vérifiée avec succès !"
},
@@ -1532,9 +1634,6 @@
"dashboard.overview.notifications.loading": {
"message": "Chargement des notifications..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Vous pouvez modifier plusieurs projets en même temps en les sélectionnant ci-dessous."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Les projets du serveur ne prennent pas en charge l'édition en masse"
},
@@ -1610,24 +1709,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Merci de revoir les métadonnées environnementales"
},
"dashboard.projects.sort.ascending": {
"message": "Ascendant"
},
"dashboard.projects.sort.descending": {
"message": "Descendant"
},
"dashboard.projects.sort.option.name": {
"message": "Nom"
},
"dashboard.projects.sort.option.status": {
"message": "Statut"
},
"dashboard.projects.sort.option.type": {
"message": "Type"
},
"dashboard.projects.table.icon": {
"message": "Icône"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -3140,45 +3221,21 @@
"project.details.licensed": {
"message": "License"
},
"project.download.game-version": {
"message": "Version du jeu : {version}"
},
"project.download.game-version-error": {
"message": "Erreur : pas de versions du jeu trouvées"
},
"project.download.game-version-tooltip": {
"message": "{title} n'est disponible que pour {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} ne supporte pas {gameVersion} pour {platform}"
},
"project.download.install-with-app": {
"message": "Installer avec Modrinth App"
},
"project.download.no-app": {
"message": "Vous n'avez pas Modrinth App ?"
},
"project.download.no-versions-available": {
"message": "Aucune version disponible pour {gameVersion} et {platform}."
},
"project.download.platform": {
"message": "Plateforme : {platform}"
},
"project.download.platform-error": {
"message": "Erreur : pas de plateformes trouvées"
},
"project.download.platform-tooltip": {
"message": "{title} est que disponible pour {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} ne supporte pas {platform} pour {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Recherchez une version du jeu..."
},
"project.download.search-game-versions-label": {
"message": "Recherchez une version du jeu..."
},
"project.download.select-game-version": {
"message": "Sélectionnez la version du jeu"
},
@@ -3369,43 +3426,76 @@
"message": "URL"
},
"project.settings.permissions.attention-needed.description.proj-approved": {
"message": "Veuillez prouver que vous avez la permission de redistribuer tous les fichiers suivants et que toutes les versions retenues seront automatiquement publiées."
"message": "Veuillez fournir la preuve que vous êtes autorisé à redistribuer tous les fichiers suivants. Une fois cette étape terminée, les versions actuellement retenues seront automatiquement publiées."
},
"project.settings.permissions.attention-needed.description.proj-draft": {
"message": "Veuillez fournir la preuve que vous avez l'autorisation de redistribuer tous les fichiers suivants avant de pouvoir soumettre votre projet pour évaluation."
"message": "Veuillez fournir la preuve que vous êtes autorisé à redistribuer tous les fichiers suivants avant de soumettre votre projet pour examen."
},
"project.settings.permissions.attention-needed.title": {
"message": "Contenu intégré inconnu"
"message": "Contenu externe inconnu"
},
"project.settings.permissions.bad-proof.description": {
"message": "L'équipe de modération de Modrinth a rejeté les informations d'autorisation que vous avez fournies pour certains contenus externes. Veuillez examiner les éléments rejetés ci-dessous et fournir une preuve acceptable lub supprimer le contenu."
},
"project.settings.permissions.bad-proof.title": {
"message": "Certaines preuves ont été rejetées"
},
"project.settings.permissions.collapse-all": {
"message": "Tout réduire"
},
"project.settings.permissions.completed.description": {
"message": "Tout le contenu externe est accompagné d'une attribution."
"message": "Toutes les informations d'autorisation et les attributions ont été fournies pour l'ensemble du contenu externe."
},
"project.settings.permissions.completed.title": {
"message": "Attributions terminées !"
"message": "Autorisations terminées !"
},
"project.settings.permissions.empty-state.description": {
"message": "Aucune de vos versions ne contient de contenu externe, vous n'avez donc pas à vous soucier d'obtenir d'autorisations."
"message": "Aucune des versions de votre projet ne contient de contenu externe, vous n'avez donc pas à vous soucier d'obtenir des autorisations."
},
"project.settings.permissions.empty-state.heading": {
"message": "Vous êtes prêt !"
},
"project.settings.permissions.expand-all": {
"message": "Tout développer"
},
"project.settings.permissions.fail.description": {
"message": "Vous n'êtes pas autorisé à rediffuser certains des contenus externes que vous avez ajoutés. Pour pouvoir publier sur Modrinth, veuillez supprimer les contenus litigieux."
"message": "Il se peut que vous n'ayez pas l'autorisation de redistribuer une partie du contenu externe de votre projet. Pour pouvoir publier na Modrinth, veuillez supprimer ce contenu ou fournir la preuve que vous avez l'autorisation de l'utiliser."
},
"project.settings.permissions.fail.title": {
"message": "Certains contenus ne peuvent pas être inclus"
},
"project.settings.permissions.info-banner.description": {
"message": "Si vous incluez du contenu qui nest pas sur Modrinth, vous devez nous faire savoir doù il vient et vérifier que vous avez la permission de distribuer les fichiers. Jettez un coup d’œil à <link>notre guide</link> pour apprendre comment faire cela proprement !"
"message": "Si vous incluez du contenu qui n'est pas hébergé sur Modrinth, vous devez nous indiquer sa provenance et vérifier que vous avez l'autorisation de distribuer te pliki. Découvrez <link>notre annonce de ce nouveau système</link> pour en savoir plus !"
},
"project.settings.permissions.info-banner.title": {
"message": "Découvrez comment fonctionnent les attributions"
"message": "En savoir plus sur les autorisations de distribution"
},
"project.settings.permissions.learn-more": {
"message": "En savoir plus"
},
"project.settings.permissions.no-results": {
"message": "Aucun fichier externe ne correspond à votre recherche."
},
"project.settings.permissions.not-allowed.description": {
"message": "Une partie du contenu externe inclus ne peut pas être distribuée sur Modrinth car elle enfreint nos règles relatives au contenu et doit être supprimée."
},
"project.settings.permissions.pending-approval-count": {
"message": "{count, plural, =0 {Aucune attribution n'a besoin d'approbation} one {# attribution a besoin d'approbation} other {# attributions ont besoin d'approbation}}"
},
"project.settings.permissions.search-placeholder": {
"message": "Rechercher {count} {count, plural, one {projet externe} other {projets externes}}..."
"message": "Rechercher {count} {count, plural, one {projet} other {projets}}..."
},
"project.settings.permissions.sort.most-files": {
"message": "La plupart des fichiers"
},
"project.settings.permissions.sort.recently-edited": {
"message": "Modifié récemment"
},
"project.settings.permissions.sort.rejected": {
"message": "Rejeté"
},
"project.settings.permissions.sort.status": {
"message": "Statut"
},
"project.settings.title": {
"message": "Paramètres"
@@ -3965,6 +4055,48 @@
"settings.account.security.email.title": {
"message": "E-mail"
},
"settings.account.security.passkey.add": {
"message": "Ajouter une clé d'accès"
},
"settings.account.security.passkey.add-modal.name.description": {
"message": "Veillez à choisir un nom facile à retenir, afin de pouvoir identifier tę klucz d'accès plus tard."
},
"settings.account.security.passkey.add-modal.name.label": {
"message": "Nom"
},
"settings.account.security.passkey.add-modal.name.placeholder": {
"message": "Ma clé d'accès"
},
"settings.account.security.passkey.description": {
"message": "Gérez vos clés d'accès enregistrées ou ajoutez-en une nouvelle."
},
"settings.account.security.passkey.modal.added": {
"message": "Ajouté il y a {ago}"
},
"settings.account.security.passkey.modal.last-used": {
"message": "Dernière utilisation il y a {ago}"
},
"settings.account.security.passkey.modal.loading": {
"message": "Chargement des clés d'accès…"
},
"settings.account.security.passkey.modal.never-used": {
"message": "Jamais utilisée"
},
"settings.account.security.passkey.modal.no-passkeys": {
"message": "Vous n'avez aucune clé d'accès enregistrée."
},
"settings.account.security.passkey.remove.description": {
"message": "Cela supprimera définitivement la clé d'accès \"{name}\". Vous ne pourrez plus l'utiliser pour vous connecter."
},
"settings.account.security.passkey.remove.title": {
"message": "Êtes-vous sûr de vouloir supprimer cette clé d'accès ?"
},
"settings.account.security.passkey.rename-modal.header": {
"message": "Renommer la clé d'accès"
},
"settings.account.security.passkey.title": {
"message": "Gérer les clés d'accès"
},
"settings.account.security.password.action.add": {
"message": "Ajouter un mot de passe"
},
@@ -4577,6 +4709,48 @@
"ui.newsletter-button.tooltip": {
"message": "S'abonner au journal Modrinth"
},
"version.all-versions": {
"message": "Toutes les versions"
},
"version.confirm-delete.description": {
"message": "Cette version sera définitivement supprimée. Cette action est irréversible."
},
"version.confirm-delete.proceed": {
"message": "Supprimer la version"
},
"version.confirm-delete.title": {
"message": "Êtes-vous sûr de vouloir supprimer cette version ?"
},
"version.dependency.view-project": {
"message": "Voir le projet"
},
"version.dependency.view-version": {
"message": "Voir la version"
},
"version.download.download-dependency": {
"message": "Télécharger la dépendance"
},
"version.download.no-primary-file": {
"message": "Erreur : aucun fichier principal trouvé"
},
"version.download.optional-resource-pack": {
"message": "Pack de ressources facultatif"
},
"version.download.required-resource-pack": {
"message": "Pack de ressources requis"
},
"version.edit.button": {
"message": "Modifier"
},
"version.edit.details": {
"message": "Modifier les détails"
},
"version.edit.files": {
"message": "Modifier los pliki"
},
"version.edit.metadata": {
"message": "Modifier les métadonnées"
},
"version.environment.none.description": {
"message": "L'environnement pour cette version n'a pas été spécifié."
},
@@ -4588,5 +4762,56 @@
},
"version.environment.unknown.title": {
"message": "Environnement Inconnue"
},
"version.package-as-mod.button": {
"message": "Packager comme mod"
},
"version.package-as-mod.description": {
"message": "Cela créera une nouvelle version prenant en charge les chargeurs de mods sélectionnés. Vous serez redirigé vers la nouvelle version et pourrez la modifier à votre guise."
},
"version.package-as-mod.header": {
"message": "Empaqueter le pack de données en mod"
},
"version.package-as-mod.mod-loaders": {
"message": "Chargeurs de mods"
},
"version.package-as-mod.mod-loaders.description": {
"message": "Les chargeurs de mods pour lesquels vous souhaitez packager votre data pack."
},
"version.package-as-mod.mod-loaders.placeholder": {
"message": "Choisir les chargeurs de mods..."
},
"version.package-as-mod.submit-button": {
"message": "Packager le data pack"
},
"version.section.content.dev-info": {
"message": "Informations de développement"
},
"version.section.content.dev-info.gradle-snippet": {
"message": "build.gradle :"
},
"version.section.content.dev-info.maven-coordinates": {
"message": "Coordonnées Maven :"
},
"version.section.content.dev-info.maven-description": {
"message": "Les projets sur Modrinth sont automatiquement disponibles via un dépôt Maven pour une utilisation avec des outils de build JVM tels que <gradle-link>Gradle</gradle-link>. Pour en savoir plus sur l'API Maven de Modrinth, <article-link>cliquez ici</article-link>."
},
"version.section.content.dev-info.maven-note": {
"message": "Remarque : Lorsque cela est possible, il est préférable d'utiliser le dépôt Maven du créateur, car il contient des informations sur les dépendances transitives que l'API Maven de Modrinth ne fournit pas. Vous risquez également de vous retrouver avec des dépendances en double si vous combinez des dépôts Maven Modrinth et non-Modrinth pour vos dépendances, car l'identifiant de groupe (group ID) différera lorsqu'il est fourni via l'API Maven de Modrinth."
},
"version.section.content.dev-info.version-id": {
"message": "ID de version :"
},
"version.supplementary-resources.copy-hash-sha1": {
"message": "Copier SHA-1"
},
"version.supplementary-resources.copy-hash-sha512": {
"message": "Copier SHA-512"
},
"version.unknown-embedded-content.description": {
"message": "Cette version est actuellement retenue et ne figure pas dans la liste publique. Veuillez fournir la preuve que vous êtes autorisé à redistribuer certains des fichiers inclus."
},
"version.unknown-embedded-content.title": {
"message": "Masqué en raison d'un contenu intégré inconnu"
}
}
@@ -254,18 +254,9 @@
"auth.reset-password.title.long": {
"message": "הפס סיסמתכם"
},
"auth.sign-in.2fa.description": {
"message": "כתבו את הקוד אימות דו-שלבי שלכם כדי להמשיך."
},
"auth.sign-in.2fa.label": {
"message": "כתבו את האימות דו-שלבי"
},
"auth.sign-in.2fa.placeholder": {
"message": "כתבו קוד..."
},
"auth.sign-in.sign-in-with": {
"message": "הכנס אם"
},
"auth.sign-in.title": {
"message": "הכנס"
},
@@ -278,9 +269,6 @@
"auth.sign-up.title": {
"message": "הרשם"
},
"auth.sign-up.title.sign-up-with": {
"message": "הרשם אם"
},
"auth.verify-email.action.account-settings": {
"message": "הגדרות חשבון"
},
@@ -2039,45 +2027,21 @@
"project.details.licensed": {
"message": "ברישיון"
},
"project.download.game-version": {
"message": "גרסת המשחק: {version}"
},
"project.download.game-version-error": {
"message": "שגיאה: לא נמצאו גרסאות משחק"
},
"project.download.game-version-tooltip": {
"message": "{title} זמין עבור {version} בלבד"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} אינו תומך ב-{gameVersion} עבור {platform}"
},
"project.download.install-with-app": {
"message": "התקן באמצעות Modrinth App"
},
"project.download.no-app": {
"message": "אין לכם את אפליקציית Modrinth?"
},
"project.download.no-versions-available": {
"message": "אין גרסאות זמינות עבור {gameVersion} ו-{platform}."
},
"project.download.platform": {
"message": "פלטפורמה: {platform}"
},
"project.download.platform-error": {
"message": "שגיאה: לא נמצאו פלטפורמות"
},
"project.download.platform-tooltip": {
"message": "{title} זמין עבור {platform} בלבד"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} אינו תומך ב-{platform} עבור {gameVersion}"
},
"project.download.search-game-versions": {
"message": "חיפוש גרסאות משחק..."
},
"project.download.search-game-versions-label": {
"message": "חיפוש גרסאות משחק..."
},
"project.download.select-game-version": {
"message": "בחירת גרסת משחק"
},
+6 -63
View File
@@ -38,6 +38,9 @@
"analytics.breakdown.loader": {
"message": "Betöltő"
},
"analytics.breakdown.members": {
"message": "Tag"
},
"analytics.breakdown.monetization": {
"message": "Bevételszerzés"
},
@@ -221,6 +224,9 @@
"analytics.filter.search.download-sources": {
"message": "Letöltési források keresése..."
},
"analytics.filter.search.members": {
"message": "Tagok keresése... "
},
"analytics.filter.search.project-versions": {
"message": "Projektverziók keresése..."
},
@@ -680,18 +686,9 @@
"auth.reset-password.title.long": {
"message": "Jelszavad visszaállítása"
},
"auth.sign-in.2fa.description": {
"message": "Kérlek írd be a kétlépcsős hitelesítés kódját a folytatáshoz."
},
"auth.sign-in.2fa.label": {
"message": "Írd be a kétlépcsős hitelesítés kódját"
},
"auth.sign-in.2fa.placeholder": {
"message": "Kód beírása..."
},
"auth.sign-in.sign-in-with": {
"message": "Bejelentkezés ezzel"
},
"auth.sign-in.title": {
"message": "Bejelentkezés"
},
@@ -704,9 +701,6 @@
"auth.sign-up.title": {
"message": "Regisztráció"
},
"auth.sign-up.title.sign-up-with": {
"message": "Regisztráció ezzel"
},
"auth.verify-email.action.account-settings": {
"message": "Fiókbeállítások"
},
@@ -1388,9 +1382,6 @@
"dashboard.overview.notifications.loading": {
"message": "Értesítések betöltése..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Több projektet is szerkeszthetsz egyszerre, ha kiválasztod őket alább."
},
"dashboard.projects.empty": {
"message": "Még nincsenek projektjeid. Kattints a fenti zöld gombra a kezdéshez."
},
@@ -1451,24 +1442,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Kérlek ellenőrizd a környezeti metaadatokat"
},
"dashboard.projects.sort.ascending": {
"message": "Növekvő"
},
"dashboard.projects.sort.descending": {
"message": "Csökkenő"
},
"dashboard.projects.sort.option.name": {
"message": "Név"
},
"dashboard.projects.sort.option.status": {
"message": "Állapot"
},
"dashboard.projects.sort.option.type": {
"message": "Típus"
},
"dashboard.projects.table.icon": {
"message": "Ikon"
},
"dashboard.projects.table.id": {
"message": "Azonosító"
},
@@ -2945,45 +2918,21 @@
"project.details.licensed": {
"message": "Licensz:"
},
"project.download.game-version": {
"message": "Játékverzió: {version}"
},
"project.download.game-version-error": {
"message": "Hiba: nem található játékverzió"
},
"project.download.game-version-tooltip": {
"message": "{title} csak erre a verzióra érthető el: {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "A(z) {title} nem támogatja ezt a verziót: {platform} {gameVersion}"
},
"project.download.install-with-app": {
"message": "Letöltés a Modrinth Appal"
},
"project.download.no-app": {
"message": "Nincs meg a Modrinth App? "
},
"project.download.no-versions-available": {
"message": "Nem érhető el verzió ehhez: {platform} {gameVersion}"
},
"project.download.platform": {
"message": "Platform: {platform}"
},
"project.download.platform-error": {
"message": "Hiba: nem található platform"
},
"project.download.platform-tooltip": {
"message": "A(z) {title} csak erre érthető el: {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "A(z) {title} nem támogatja ezt a verziót: {platform} {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Játékverziók keresése..."
},
"project.download.search-game-versions-label": {
"message": "Játékverziók keresése..."
},
"project.download.select-game-version": {
"message": "Játékverzió kiválasztása"
},
@@ -3128,18 +3077,12 @@
"project.settings.general.url.title": {
"message": "Link"
},
"project.settings.permissions.empty-state.description": {
"message": "Egyik verziód sem tartalmaz külső tartalmat, így nem kell aggódnod a jogosultságok beszerzése miatt."
},
"project.settings.permissions.empty-state.heading": {
"message": "Kész is van!"
},
"project.settings.permissions.learn-more": {
"message": "További információ"
},
"project.settings.permissions.search-placeholder": {
"message": "Keresés {count} külső projekt között..."
},
"project.settings.title": {
"message": "Beállítások"
},
@@ -473,18 +473,9 @@
"auth.reset-password.title.long": {
"message": "Atur ulang kata sandi Anda"
},
"auth.sign-in.2fa.description": {
"message": "Mohon masukkan kode autentikasi dwifaktor untuk melanjutkan."
},
"auth.sign-in.2fa.label": {
"message": "Masukkan kode dwifaktor"
},
"auth.sign-in.2fa.placeholder": {
"message": "Masukkan kode..."
},
"auth.sign-in.sign-in-with": {
"message": "Masuk dengan"
},
"auth.sign-in.title": {
"message": "Masuk"
},
@@ -497,9 +488,6 @@
"auth.sign-up.title": {
"message": "Daftar"
},
"auth.sign-up.title.sign-up-with": {
"message": "Daftar dengan"
},
"auth.verify-email.action.account-settings": {
"message": "Pengaturan akun"
},
@@ -2435,45 +2423,21 @@
"project.details.licensed": {
"message": "Berlisensi"
},
"project.download.game-version": {
"message": "Versi permainan: {version}"
},
"project.download.game-version-error": {
"message": "Kesalahan: tidak ada versi permainan yang ditemukan"
},
"project.download.game-version-tooltip": {
"message": "{title} hanya tersedia untuk {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} tidak mendukung {gameVersion} untuk {platform}"
},
"project.download.install-with-app": {
"message": "Pasang dengan Modrinth App"
},
"project.download.no-app": {
"message": "Tidak memiliki Modrinth App?"
},
"project.download.no-versions-available": {
"message": "Tidak ada versi tersedia untuk {gameVersion} dan {platform}."
},
"project.download.platform": {
"message": "Platform: {platform}"
},
"project.download.platform-error": {
"message": "Kesalahan: tidak ada platform yang ditemukan"
},
"project.download.platform-tooltip": {
"message": "{title} hanya tersedia untuk {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} tidak mendukung {platform} untuk {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Cari versi permainan..."
},
"project.download.search-game-versions-label": {
"message": "Cari versi permainan..."
},
"project.download.select-game-version": {
"message": "Pilih versi permainan"
},
+284 -59
View File
@@ -725,12 +725,72 @@
"auth.authorize.authorize-app-name": {
"message": "Autorizza {appName}"
},
"auth.authorize.error.missing-parameters": {
"message": "Parametri di query OAuth mancanti."
},
"auth.authorize.error.no-redirect-url": {
"message": "Nessun link di reindirizzamento trovato nella risposta"
},
"auth.authorize.errro-title": {
"message": "Si è verificato un errore"
},
"auth.authorize.redirect-url": {
"message": "Sarai reindirizzato a <redirect-url>{url}</redirect-url>"
},
"auth.continue-with-provider": {
"message": "Continua con {provider}"
},
"auth.create-account.age-requirement.warning-title": {
"message": "Età richiesta"
},
"auth.create-account.complete-sign-up": {
"message": "Completa la registrazione"
},
"auth.create-account.date-of-birth.invalid.text": {
"message": "Inserisci una data di nascita valida. L'anno non può essere 0000."
},
"auth.create-account.date-of-birth.invalid.title": {
"message": "Data di nascita non valida"
},
"auth.create-account.date-of-birth.label": {
"message": "Data di nascita"
},
"auth.create-account.date-of-birth.placeholder": {
"message": "Seleziona la tua data di nascita"
},
"auth.create-account.date-of-birth.required.text": {
"message": "Inserisci la tua data di nascita prima di continuare."
},
"auth.create-account.date-of-birth.required.title": {
"message": "Data di nascita richiesta"
},
"auth.create-account.date-of-birth.under13-helper": {
"message": "Non soddisfi i requisiti di età necessari per creare un account su Modrinth."
},
"auth.create-account.info-panel.source-code-link": {
"message": "Codice sorgente rilevante"
},
"auth.create-account.info-panel.text": {
"message": "Non memorizziamo la tua data di nascita. La utilizziamo solo durante la registrazione per verificare la conformità alla normativa COPPA."
},
"auth.create-account.page-title": {
"message": "Crea account"
},
"auth.create-account.security-check.label": {
"message": "Controllo di sicurezza"
},
"auth.create-account.subscribe.label": {
"message": "Tienimi aggiornato sulle fantastiche cose a cui Modrinth sta lavorando tramite email"
},
"auth.create-account.title": {
"message": "Crea un account"
},
"auth.create-account.username.label": {
"message": "Nome utente"
},
"auth.create-account.username.placeholder": {
"message": "Inserisci il nome utente"
},
"auth.reset-password.method-choice.action": {
"message": "Invia email di recupero"
},
@@ -765,23 +825,53 @@
"message": "Reimposta la password"
},
"auth.sign-in.2fa.description": {
"message": "Inserisci il codice 2FA per continuare."
"message": "Inserisci il codice a 6 cifre dalla tua app di autenticazione oppure uno dei tuoi codici di backup."
},
"auth.sign-in.2fa.label": {
"message": "Inserisci un codice 2FA"
"message": "Autenticazione a due fattori"
},
"auth.sign-in.2fa.placeholder": {
"message": "Inserisci il codice..."
},
"auth.sign-in.continue-with-email": {
"message": "Continua con l'email"
},
"auth.sign-in.continue-with-passkey": {
"message": "Continua con passkey"
},
"auth.sign-in.create-account": {
"message": "Registrati"
},
"auth.sign-in.forgot-password": {
"message": "Password dimenticata"
},
"auth.sign-in.last-sign-in": {
"message": "Ultimo utilizzo"
},
"auth.sign-in.no-account": {
"message": "Non hai un account?"
},
"auth.sign-in.sign-in-with": {
"message": "Accedi con"
"message": "Accedi a Modrinth"
},
"auth.sign-in.title": {
"message": "Accedi"
},
"auth.sign-up.age-requirement.warning-title": {
"message": "Età richiesta"
},
"auth.sign-up.continue-with-email": {
"message": "Continua con l'email"
},
"auth.sign-up.legal-dislaimer": {
"message": "Creando un''account, accetti i <terms-link>termini d''uso</terms-link> e l''<privacy-policy-link>informativa sulla privacy</privacy-policy-link> di Modrinth."
},
"auth.sign-up.show-fewer-options": {
"message": "Mostra meno opzioni"
},
"auth.sign-up.show-other-options": {
"message": "Mostra altre opzioni"
},
"auth.sign-up.sign-in-option.title": {
"message": "Hai già un account?"
},
@@ -789,11 +879,14 @@
"message": "Registrati"
},
"auth.sign-up.title.sign-up-with": {
"message": "Accedi con"
"message": "Crea un account"
},
"auth.verify-email.action.account-settings": {
"message": "Impostazioni account"
},
"auth.verify-email.action.discover-mods": {
"message": "Esplora mod"
},
"auth.verify-email.already-verified.description": {
"message": "La tua email è già stata verificata!"
},
@@ -812,6 +905,15 @@
"auth.verify-email.failed-verification.title": {
"message": "Errore nella verifica dell'email"
},
"auth.verify-email.notification.email-sent.description": {
"message": "È stata inviata un'email con il link per verificare il tuo account a {email}."
},
"auth.verify-email.notification.email-sent.title": {
"message": "Email inviata"
},
"auth.verify-email.notification.error-occurred.title": {
"message": "Si è verificato un errore"
},
"auth.verify-email.post-verification.description": {
"message": "Il tuo indirizzo email è stato verificato con successo!"
},
@@ -1526,9 +1628,6 @@
"dashboard.overview.notifications.loading": {
"message": "Caricando le notifiche..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Puoi modificare più progetti contemporaneamente selezionandoli qui sotto."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Non puoi modificare più server contemporaneamente"
},
@@ -1601,24 +1700,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Si prega di rivedere i metadati d'ambiente"
},
"dashboard.projects.sort.ascending": {
"message": "Crescente"
},
"dashboard.projects.sort.descending": {
"message": "Decrescente"
},
"dashboard.projects.sort.option.name": {
"message": "Nome"
},
"dashboard.projects.sort.option.status": {
"message": "Stato"
},
"dashboard.projects.sort.option.type": {
"message": "Tipo"
},
"dashboard.projects.table.icon": {
"message": "Icona"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -2052,7 +2133,7 @@
"message": "Avvia il tuo server"
},
"hosting-marketing.hero.host-with-modrinth": {
"message": "Affida il tuo prossimo server a Modrinth Hosting"
"message": "Scegli Modrinth Hosting per il tuo nuovo server"
},
"hosting-marketing.hero.hosting-description": {
"message": "Modrinth Hosting è il modo più facile per gestire il tuo server personale per Minecraft: Java Edition. Installa e gioca alle tue mod e pacchetti preferiti, tutto tramite la piattaforma Modrinth."
@@ -3131,45 +3212,21 @@
"project.details.licensed": {
"message": "Licenza"
},
"project.download.game-version": {
"message": "Versione del gioco: {version}"
},
"project.download.game-version-error": {
"message": "Errore: nessuna versione del gioco trovata"
},
"project.download.game-version-tooltip": {
"message": "{title} è disponibile solo per {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} non supporta {platform} per {gameVersion}"
},
"project.download.install-with-app": {
"message": "Installa con Modrinth App"
},
"project.download.no-app": {
"message": "Non hai Modrinth App?"
},
"project.download.no-versions-available": {
"message": "Nessuna versione disponibile per {gameVersion} e {platform}."
},
"project.download.platform": {
"message": "Piattaforma: {platform}"
},
"project.download.platform-error": {
"message": "Errore: nessuna piattaforma trovata"
},
"project.download.platform-tooltip": {
"message": "{title} è disponibile solo per {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} non supporta {platform} per {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Cerca versioni del gioco..."
},
"project.download.search-game-versions-label": {
"message": "Cerca tra le versioni del gioco..."
},
"project.download.select-game-version": {
"message": "Seleziona la versione del gioco"
},
@@ -3360,43 +3417,76 @@
"message": "URL"
},
"project.settings.permissions.attention-needed.description.proj-approved": {
"message": "Dimostra di avere il permesso di ridistribuire tutti i seguenti file, e le versioni sospese verranno pubblicate automaticamente."
"message": "Dimostra di avere il permesso di ridistribuire tutti i file seguenti. Una volta fatto, le versioni sospese verranno pubblicate automaticamente."
},
"project.settings.permissions.attention-needed.description.proj-draft": {
"message": "Dimostra di avere il permesso di ridistribuire tutti i seguenti file prima di presentare il tuo progetto alla revisione."
"message": "Dimostra di avere il permesso di ridistribuire tutti i file seguenti prima di presentare il progetto alla revisione."
},
"project.settings.permissions.attention-needed.title": {
"message": "Contenuti di origine sconosciuta"
},
"project.settings.permissions.bad-proof.description": {
"message": "Il team di moderazione di Modrinth ha rifiutato i permessi che hai dimostrato per alcuni contenuti esterni. Ricontrolla gli elementi rifiutati riportati di seguito e fornisci delle prove valide oppure rimuovi i contenuti."
},
"project.settings.permissions.bad-proof.title": {
"message": "Alcune prove sono state rifiutate"
},
"project.settings.permissions.collapse-all": {
"message": "Comprimi tutto"
},
"project.settings.permissions.completed.description": {
"message": "Sono state fornite attribuzioni per tutti i contenuti esterni."
"message": "Tutti i contenuti esterni hanno ricevuto i permessi e tutte le attribuzioni sono state fornite."
},
"project.settings.permissions.completed.title": {
"message": "Attribuzioni complete!"
"message": "Permessi completi!"
},
"project.settings.permissions.empty-state.description": {
"message": "Nessuna versione include contenuti esterni, quindi non è necessario dimostrare alcun permesso."
"message": "Nessuna versione del progetto include contenuti esterni, quindi non è necessario dimostrare alcun permesso."
},
"project.settings.permissions.empty-state.heading": {
"message": "Tutto a posto!"
},
"project.settings.permissions.expand-all": {
"message": "Espandi tutto"
},
"project.settings.permissions.fail.description": {
"message": "Non hai il permesso di ridistribuire alcuni dei contenuti esterni che hai incluso. Per pubblicare su Modrinth, rimuovi i contenuti illeciti."
"message": "Potresti non avere il permesso di ridistribuire alcuni dei contenuti esterni contenuti nel progetto. Per pubblicare su Modrinth, rimuovili o dimostra di avere il permesso di usarli."
},
"project.settings.permissions.fail.title": {
"message": "Alcuni contenuti non possono essere pubblicati"
},
"project.settings.permissions.info-banner.description": {
"message": "Se includi dei contenuti esterni a Modrinth, devi dichiarare la loro origine e dimostrare di avere il permesso di ridistribuirli. Controlla la <link>nostra guida</link> per farlo nel modo giusto!"
"message": "Se includi dei contenuti esterni a Modrinth, devi dichiarare la loro origine e dimostrare di avere il permesso di ridistribuirli. Controlla <link>il nostro annuncio su questo nuovo sistema</link> per scoprire di più!"
},
"project.settings.permissions.info-banner.title": {
"message": "Come funzionano le attribuzioni"
"message": "Scopri di più sui permessi di distribuzione"
},
"project.settings.permissions.learn-more": {
"message": "Scopri di più"
},
"project.settings.permissions.no-results": {
"message": "Nessun file esterno corrisponde alla tua ricerca."
},
"project.settings.permissions.not-allowed.description": {
"message": "Alcuni dei contenuti esterni inclusi non possono essere distribuiti su Modrinth e devono essere rimossi in quanto violano le nostre Regole sui contenuti."
},
"project.settings.permissions.pending-approval-count": {
"message": "{count, plural, =0 {Nessuna attribuzione necessita} one {# attribuzione necessita} other {# attribuzioni necessitano}} di approvazione"
},
"project.settings.permissions.search-placeholder": {
"message": "Cerca tra {count, plural, one {# progetto esterno} other {# progetti esterni}}..."
"message": "Cerca tra {count} {count, plural, one {progetto} other {progetti}}..."
},
"project.settings.permissions.sort.most-files": {
"message": "Numero di file"
},
"project.settings.permissions.sort.recently-edited": {
"message": "Modificati di recente"
},
"project.settings.permissions.sort.rejected": {
"message": "Rifiutati"
},
"project.settings.permissions.sort.status": {
"message": "Stato"
},
"project.settings.title": {
"message": "Impostazioni"
@@ -3938,6 +4028,48 @@
"settings.account.security.email.title": {
"message": "Email"
},
"settings.account.security.passkey.add": {
"message": "Aggiungi passkey"
},
"settings.account.security.passkey.add-modal.name.description": {
"message": "Assicurati di scegliere un nome facile da ricordare, così da poter identificare la passkey più tardi."
},
"settings.account.security.passkey.add-modal.name.label": {
"message": "Nome"
},
"settings.account.security.passkey.add-modal.name.placeholder": {
"message": "Passkey personale"
},
"settings.account.security.passkey.description": {
"message": "Gestisci le tue passkey o aggiungine una nuova."
},
"settings.account.security.passkey.modal.added": {
"message": "Aggiunta {ago}"
},
"settings.account.security.passkey.modal.last-used": {
"message": "Ultimo utilizzo {ago}"
},
"settings.account.security.passkey.modal.loading": {
"message": "Caricando le passkey…"
},
"settings.account.security.passkey.modal.never-used": {
"message": "Mai usata"
},
"settings.account.security.passkey.modal.no-passkeys": {
"message": "Non hai passkey registrate."
},
"settings.account.security.passkey.remove.description": {
"message": "Questo rimuoverà la passkey \"{name}\" permanentemente. Non potrai più accedere con questa."
},
"settings.account.security.passkey.remove.title": {
"message": "Vuoi davvero eliminare questa passkey?"
},
"settings.account.security.passkey.rename-modal.header": {
"message": "Rinomina passkey"
},
"settings.account.security.passkey.title": {
"message": "Gestisci passkey"
},
"settings.account.security.password.action.add": {
"message": "Aggiungi password"
},
@@ -4550,6 +4682,48 @@
"ui.newsletter-button.tooltip": {
"message": "Iscriviti alla newsletter di Modrinth"
},
"version.all-versions": {
"message": "Tutte le versioni"
},
"version.confirm-delete.description": {
"message": "Questa versione verrà eliminata permanentemente. Questa azione non può essere annullata."
},
"version.confirm-delete.proceed": {
"message": "Elimina versione"
},
"version.confirm-delete.title": {
"message": "Vuoi davvero eliminare questa versione?"
},
"version.dependency.view-project": {
"message": "Mostra progetto"
},
"version.dependency.view-version": {
"message": "Mostra versione"
},
"version.download.download-dependency": {
"message": "Scarica dipendenza"
},
"version.download.no-primary-file": {
"message": "Errore: nessun file primario trovato"
},
"version.download.optional-resource-pack": {
"message": "Pacchetto di risorse facoltativo"
},
"version.download.required-resource-pack": {
"message": "Pacchetto di risorse obbligatorio"
},
"version.edit.button": {
"message": "Modifica"
},
"version.edit.details": {
"message": "Modifica dettagli"
},
"version.edit.files": {
"message": "Modifica file"
},
"version.edit.metadata": {
"message": "Modifica metadati"
},
"version.environment.none.description": {
"message": "L'ambiente per questa versione non è stato specificato."
},
@@ -4561,5 +4735,56 @@
},
"version.environment.unknown.title": {
"message": "Ambiente sconosciuto"
},
"version.package-as-mod.button": {
"message": "Impacchetta come mod"
},
"version.package-as-mod.description": {
"message": "Questo creerà una nuova versione con il supporto ai loader selezionati. Sarai reindirizzato alla nuova versione così da modificarla a tuo piacimento."
},
"version.package-as-mod.header": {
"message": "Impacchetta in una mod"
},
"version.package-as-mod.mod-loaders": {
"message": "Loader"
},
"version.package-as-mod.mod-loaders.description": {
"message": "I loader per cui verrà impacchettato il pacchetto di dati."
},
"version.package-as-mod.mod-loaders.placeholder": {
"message": "Scegli i loader..."
},
"version.package-as-mod.submit-button": {
"message": "Impacchetta"
},
"version.section.content.dev-info": {
"message": "Informazioni sullo sviluppatore"
},
"version.section.content.dev-info.gradle-snippet": {
"message": "build.gradle:"
},
"version.section.content.dev-info.maven-coordinates": {
"message": "Coordinate Maven:"
},
"version.section.content.dev-info.maven-description": {
"message": "I progetti su Modrinth sono automaticamente disponibili tramite una repository su Maven per uso con strumenti di sviluppo come <gradle-link>Gradle</gradle-link>. Per saperne di più sull'API Maven di Modrinth, <article-link>clicca qui</article-link>."
},
"version.section.content.dev-info.maven-note": {
"message": "Nota: quando disponibile, dovresti usare la repository Maven dell'autore, in quanto conterrà informazioni transitive sulle dipendenze che l'API Maven di Modrinth non ha. Inoltre, usando altre repository non di Modrinth insieme a queste, potresti finire con dipendenze duplicate, poiché l'identificatore del gruppo risulterà diverso quando fornito dall'API."
},
"version.section.content.dev-info.version-id": {
"message": "ID di versione:"
},
"version.supplementary-resources.copy-hash-sha1": {
"message": "Copia SHA-1"
},
"version.supplementary-resources.copy-hash-sha512": {
"message": "Copia SHA-512"
},
"version.unknown-embedded-content.description": {
"message": "Questa versione è attualmente sospesa e non elencata pubblicamente. Devi dimostrare di avere il permesso di ridistribuire alcuni dei file presenti."
},
"version.unknown-embedded-content.title": {
"message": "Sospesa per attribuzioni incomplete"
}
}
+63 -60
View File
@@ -48,7 +48,7 @@
"message": "メンバー"
},
"analytics.breakdown.monetization": {
"message": "収益"
"message": "収益の発生"
},
"analytics.breakdown.none.selected": {
"message": "分析 - デフォルト"
@@ -102,7 +102,7 @@
"message": "プロジェクトのイベントがありません。"
},
"analytics.chart.controls.previous-period": {
"message": "1期前の描画"
"message": "前の描画"
},
"analytics.chart.controls.project-events": {
"message": "プロジェクト"
@@ -158,6 +158,15 @@
"analytics.filter.search.countries": {
"message": "国を検索…"
},
"analytics.filter.search.dependent-projects": {
"message": "プロジェクトを検索..."
},
"analytics.filter.search.download-sources": {
"message": "ソースを検索..."
},
"analytics.filter.search.members": {
"message": "メンバーを検索..."
},
"analytics.filter.search.project-versions": {
"message": "プロジェクトバージョンを検索…"
},
@@ -167,9 +176,60 @@
"analytics.graph.title.downloads": {
"message": "ダウンロードの推移"
},
"analytics.graph.title.playtime": {
"message": "プレイ時間の推移"
},
"analytics.graph.title.revenue": {
"message": "収益の推移"
},
"analytics.graph.title.views": {
"message": "表示の推移"
},
"analytics.group-by.1h": {
"message": "1時間"
},
"analytics.group-by.6h": {
"message": "6時間"
},
"analytics.group-by.date": {
"message": "日付"
},
"analytics.group-by.day": {
"message": "1日"
},
"analytics.group-by.month": {
"message": "1月"
},
"analytics.group-by.selected.day": {
"message": "日足"
},
"analytics.group-by.selected.hour": {
"message": "1時間足"
},
"analytics.group-by.selected.month": {
"message": "月足"
},
"analytics.group-by.selected.six-hours": {
"message": "6時間足"
},
"analytics.group-by.selected.week": {
"message": "週足"
},
"analytics.group-by.selected.year": {
"message": "年足"
},
"analytics.group-by.week": {
"message": "1週"
},
"analytics.group-by.year": {
"message": "1年"
},
"analytics.loading.fetching-results": {
"message": "データを取得中..."
},
"analytics.options.loading": {
"message": "ロード中..."
},
"analytics.project-event.project-approved": {
"message": "承認済み"
},
@@ -201,7 +261,7 @@
"message": "ダウンロード"
},
"analytics.stat.monetization-banner.body": {
"message": "Modrinthを通じて行われた閲覧およびダウンロードが収益の対象となります。\nまた、Webからの場合は不正防止のためのフィルターを通過する必要があり、アプリからの場合は先述のフィルターに加え、Modrinthにログインされたユーザーに限ります。\n注意として、すべてのプロジェクトにおいて、収益の対象となる操作の割合はほぼ均一に保たれるため、最終的な収益で不公平が生まれることはありません。"
"message": "Modrinthを通じて行われた閲覧およびダウンロードが収益の対象となります。また、Webからの場合は不正防止のためのフィルターを通過する必要があり、アプリからの場合は先述のフィルターに加え、Modrinthにログインされたユーザーに限ります。注意として、すべてのプロジェクトにおいて、収益の対象となる操作の割合はほぼ均一に保たれるため、最終的な収益で不公平が生まれることはありません。"
},
"analytics.stat.monetization-banner.learn-more": {
"message": "もっと詳しく"
@@ -530,18 +590,9 @@
"auth.reset-password.title.long": {
"message": "パスワードを再設定する"
},
"auth.sign-in.2fa.description": {
"message": "続行するには二要素認証コードを入力してください。"
},
"auth.sign-in.2fa.label": {
"message": "二要素認証コードを入力"
},
"auth.sign-in.2fa.placeholder": {
"message": "コードを入力…"
},
"auth.sign-in.sign-in-with": {
"message": "外部アカウントでログイン"
},
"auth.sign-in.title": {
"message": "ログイン"
},
@@ -554,9 +605,6 @@
"auth.sign-up.title": {
"message": "アカウント作成"
},
"auth.sign-up.title.sign-up-with": {
"message": "外部アカウントで作成"
},
"auth.verify-email.action.account-settings": {
"message": "アカウント設定"
},
@@ -1163,9 +1211,6 @@
"dashboard.overview.notifications.loading": {
"message": "通知を読み込み中…"
},
"dashboard.projects.bulk-edit-hint": {
"message": "以下で選択することで、複数のプロジェクトを一括で編集できます。"
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "サーバープロジェクトでは一括編集を利用できません"
},
@@ -1238,24 +1283,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "環境メタデータを確認してください"
},
"dashboard.projects.sort.ascending": {
"message": "昇順"
},
"dashboard.projects.sort.descending": {
"message": "降順"
},
"dashboard.projects.sort.option.name": {
"message": "名前"
},
"dashboard.projects.sort.option.status": {
"message": "ステータス"
},
"dashboard.projects.sort.option.type": {
"message": "種類"
},
"dashboard.projects.table.icon": {
"message": "アイコン"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -2702,45 +2729,21 @@
"project.details.licensed": {
"message": "ライセンス"
},
"project.download.game-version": {
"message": "ゲームバージョン: {version}"
},
"project.download.game-version-error": {
"message": "エラー: ゲームバージョンが見つかりません"
},
"project.download.game-version-tooltip": {
"message": "{title}は{version}でのみ利用可能です"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title}は{platform}の{gameVersion}に対応していません"
},
"project.download.install-with-app": {
"message": "Modrinth Appでインストール"
},
"project.download.no-app": {
"message": "Modrinth Appをお持ちでないですか?"
},
"project.download.no-versions-available": {
"message": "{gameVersion}および{platform}向けのバージョンは利用できません。"
},
"project.download.platform": {
"message": "プラットフォーム: {platform}"
},
"project.download.platform-error": {
"message": "エラー: プラットフォームが見つかりません"
},
"project.download.platform-tooltip": {
"message": "{title}は{platform}でのみ利用可能です"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title}は{gameVersion}の{platform}に対応していません"
},
"project.download.search-game-versions": {
"message": "ゲームバージョンを検索…"
},
"project.download.search-game-versions-label": {
"message": "ゲームバージョンを検索…"
},
"project.download.select-game-version": {
"message": "ゲームバージョンを選択"
},
@@ -266,18 +266,9 @@
"auth.reset-password.title.long": {
"message": "비밀번호 재설정"
},
"auth.sign-in.2fa.description": {
"message": "진행하려면 2단계 인증 코드를 입력해 주세요."
},
"auth.sign-in.2fa.label": {
"message": "2단계 인증 코드 입력"
},
"auth.sign-in.2fa.placeholder": {
"message": "코드 입력..."
},
"auth.sign-in.sign-in-with": {
"message": "다음을 통해 로그인"
},
"auth.sign-in.title": {
"message": "로그인"
},
@@ -290,9 +281,6 @@
"auth.sign-up.title": {
"message": "회원 가입"
},
"auth.sign-up.title.sign-up-with": {
"message": "다음 계정으로 가입"
},
"auth.verify-email.action.account-settings": {
"message": "계정 설정"
},
@@ -1010,9 +998,6 @@
"dashboard.overview.notifications.loading": {
"message": "알림 불러오는 중..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "아래에서 여러 프로젝트를 선택하면 한 번에 편집할 수 있습니다."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "서버 프로젝트는 일괄 편집을 지원하지 않습니다"
},
@@ -1082,24 +1067,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "환경 메타데이터를 검토해 주세요"
},
"dashboard.projects.sort.ascending": {
"message": "오름차순"
},
"dashboard.projects.sort.descending": {
"message": "내림차순"
},
"dashboard.projects.sort.option.name": {
"message": "이름"
},
"dashboard.projects.sort.option.status": {
"message": "상태"
},
"dashboard.projects.sort.option.type": {
"message": "유형"
},
"dashboard.projects.table.icon": {
"message": "아이콘"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -2576,45 +2543,21 @@
"project.details.licensed": {
"message": "라이선스"
},
"project.download.game-version": {
"message": "게임 버전: {version}"
},
"project.download.game-version-error": {
"message": "오류: 게임 버전을 찾을 수 없습니다"
},
"project.download.game-version-tooltip": {
"message": "{title}은(는) {version}에서만 사용할 수 있습니다"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title}은(는) {platform}용 {gameVersion}을(를) 지원하지 않습니다"
},
"project.download.install-with-app": {
"message": "Modrinth App으로 설치"
},
"project.download.no-app": {
"message": "Modrinth 앱을 설치하지 않으셨나요?"
},
"project.download.no-versions-available": {
"message": "{gameVersion} 및 {platform}용 버전이 없습니다."
},
"project.download.platform": {
"message": "플랫폼: {platform}"
},
"project.download.platform-error": {
"message": "오류: 플랫폼을 찾을 수 없음"
},
"project.download.platform-tooltip": {
"message": "{title} 은(는) {platform} 에서만 사용할 수 있습니다"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} 은(는) {gameVersion} 용 {platform} 을(를) 지원하지 않습니다."
},
"project.download.search-game-versions": {
"message": "게임 버전 검색..."
},
"project.download.search-game-versions-label": {
"message": "게임 버전 검색..."
},
"project.download.select-game-version": {
"message": "게임 버전 선택"
},
@@ -2804,45 +2747,15 @@
"project.settings.general.url.title": {
"message": "URL"
},
"project.settings.permissions.attention-needed.description.proj-approved": {
"message": "다음 파일들을 재배포할 권한이 있음을 증명하는 자료를 제출 바랍니다. 제출 시 보류된 버전은 자동으로 공개됩니다."
},
"project.settings.permissions.attention-needed.description.proj-draft": {
"message": "프로젝트 검토를 위해 제출하기 전에 다음 파일들을 재배포할 권한이 있음을 증명하는 자료를 제출해 주세요."
},
"project.settings.permissions.attention-needed.title": {
"message": "알 수 없는 내장 콘텐츠"
},
"project.settings.permissions.completed.description": {
"message": "모든 외부 콘텐츠에는 출처가 명시되어 있습니다."
},
"project.settings.permissions.completed.title": {
"message": "출처 표기 완료됨!"
},
"project.settings.permissions.empty-state.description": {
"message": "어떤 버전에도 외부 콘텐츠가 포함되어 있지 않으므로 권한을 얻는 걸 걱정하지 않아도 됩니다."
},
"project.settings.permissions.empty-state.heading": {
"message": "준비됨!"
},
"project.settings.permissions.fail.description": {
"message": "추가한 외부 콘텐츠 중 일부를 재배포할 권한이 없습니다. Modrinth에 게시하려면 저작권 침해 콘텐츠를 삭제해야 합니다."
},
"project.settings.permissions.fail.title": {
"message": "일부 콘텐츠는 포함될 수 없습니다"
},
"project.settings.permissions.info-banner.description": {
"message": "Modrinth에 호스팅되지 않은 콘텐츠를 포함하는 경우, 해당 콘텐츠의 출처를 알리고 파일 배포 권한이 있는지 확인해야 합니다. <link>저희 지침</link>을 참고해 어떻게 처리하는지 알아보세요!"
},
"project.settings.permissions.info-banner.title": {
"message": "출처 표기 방식 알아보기"
},
"project.settings.permissions.learn-more": {
"message": "더보기"
},
"project.settings.permissions.search-placeholder": {
"message": "{count}개의 {count, plural, other {외부 프로젝트}} 검색..."
},
"project.settings.title": {
"message": "설정"
},
@@ -656,18 +656,9 @@
"auth.reset-password.title.long": {
"message": "Tetap semula kata laluan anda"
},
"auth.sign-in.2fa.description": {
"message": "Sila masukkan kod dua faktor untuk meneruskan."
},
"auth.sign-in.2fa.label": {
"message": "Masukkan kod dua faktor"
},
"auth.sign-in.2fa.placeholder": {
"message": "Masukkan kod..."
},
"auth.sign-in.sign-in-with": {
"message": "Daftar masuk dengan"
},
"auth.sign-in.title": {
"message": "Daftar Masuk"
},
@@ -680,9 +671,6 @@
"auth.sign-up.title": {
"message": "Daftar"
},
"auth.sign-up.title.sign-up-with": {
"message": "Daftar dengan"
},
"auth.verify-email.action.account-settings": {
"message": "Tetapan akaun"
},
@@ -1379,9 +1367,6 @@
"dashboard.overview.notifications.loading": {
"message": "Sedang memuat pemberitahuan..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Anda boleh menyunting berbilang projek sekaligus dengan memilihnya di bawah."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Projek pelayan tidak menyokong penyuntingan pukal"
},
@@ -1451,24 +1436,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Sila semak metadata persekitaran"
},
"dashboard.projects.sort.ascending": {
"message": "Menaik"
},
"dashboard.projects.sort.descending": {
"message": "Menurun"
},
"dashboard.projects.sort.option.name": {
"message": "Nama"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Jenis"
},
"dashboard.projects.table.icon": {
"message": "Ikon"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -2951,45 +2918,21 @@
"project.details.licensed": {
"message": "Berlesen"
},
"project.download.game-version": {
"message": "Versi permainan: {version}"
},
"project.download.game-version-error": {
"message": "Ralat: tiada versi permainan dijumpai"
},
"project.download.game-version-tooltip": {
"message": "{title} hanya tersedia untuk {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} tidak menyokong {gameVersion} untuk {platform}"
},
"project.download.install-with-app": {
"message": "Pasang dengan Modrinth App"
},
"project.download.no-app": {
"message": "Tidak ada Modrinth App?"
},
"project.download.no-versions-available": {
"message": "Tiada versi tersedia untuk {gameVersion} dan {platform}."
},
"project.download.platform": {
"message": "Platform: {platform}"
},
"project.download.platform-error": {
"message": "Ralat: tiada platform dijumpai"
},
"project.download.platform-tooltip": {
"message": "{title} hanya tersedia untuk {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} tidak menyokong {platform} untuk {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Cari versi permainan..."
},
"project.download.search-game-versions-label": {
"message": "Cari versi permainan..."
},
"project.download.select-game-version": {
"message": "Pilih versi permainan"
},
@@ -3179,45 +3122,15 @@
"project.settings.general.url.title": {
"message": "URL"
},
"project.settings.permissions.attention-needed.description.proj-approved": {
"message": "Sila berikan bukti bahawa anda mempunyai kebenaran untuk mengedarkan semula semua fail berikut dan sebarang versi yang ditahan akan diterbitkan secara automatik."
},
"project.settings.permissions.attention-needed.description.proj-draft": {
"message": "Sila berikan bukti bahawa anda mempunyai kebenaran untuk mengedarkan semula semua fail berikut sebelum anda boleh menghantar projek anda untuk semakan."
},
"project.settings.permissions.attention-needed.title": {
"message": "Kandungan terbenam yang tidak diketahui"
},
"project.settings.permissions.completed.description": {
"message": "Semua kandungan luaran mempunyai atribusi yang disediakan."
},
"project.settings.permissions.completed.title": {
"message": "Atribusi selesai!"
},
"project.settings.permissions.empty-state.description": {
"message": "Tiada satu pun versi anda mengandungi kandungan luaran, jadi anda tidak perlu risau tentang mendapatkan kebenaran."
},
"project.settings.permissions.empty-state.heading": {
"message": "Semuanya sudah siap!"
},
"project.settings.permissions.fail.description": {
"message": "Anda tidak mempunyai kebenaran untuk mengedarkan semula beberapa kandungan luaran yang ditambahkan. Untuk menerbitkan projek ini di Modrinth, sila buang kandungan yang melanggar hak."
},
"project.settings.permissions.fail.title": {
"message": "Sesetengah kandungan tidak boleh disertakan"
},
"project.settings.permissions.info-banner.description": {
"message": "Jika anda memasukkan kandungan yang tidak dihoskan di Modrinth, anda perlu memberitahu kami dari mana ia berasal dan mengesahkan bahawa anda mempunyai kebenaran untuk mengedarkan fail tersebut. Lihat <link>panduan kami</link> untuk mengetahui cara untuk melakukannya dengan betul!"
},
"project.settings.permissions.info-banner.title": {
"message": "Ketahui cara atribusi berfungsi"
},
"project.settings.permissions.learn-more": {
"message": "Ketahui lebih lanjut"
},
"project.settings.permissions.search-placeholder": {
"message": "Cari {count} {count, plural, other {projek luaran}}..."
},
"project.settings.title": {
"message": "Tetapan"
},
@@ -617,18 +617,9 @@
"auth.reset-password.title.long": {
"message": "Uw wachtwoord opnieuw instellen"
},
"auth.sign-in.2fa.description": {
"message": "Voer een tweestapsverificatie code in om verder te gaan."
},
"auth.sign-in.2fa.label": {
"message": "Voer twee factor code in"
},
"auth.sign-in.2fa.placeholder": {
"message": "Voer code in..."
},
"auth.sign-in.sign-in-with": {
"message": "Log in met"
},
"auth.sign-in.title": {
"message": "Log in"
},
@@ -638,9 +629,6 @@
"auth.sign-up.title": {
"message": "Aanmelden"
},
"auth.sign-up.title.sign-up-with": {
"message": "Meld je aan met"
},
"auth.verify-email.action.account-settings": {
"message": "Account instellingen"
},
@@ -1370,9 +1358,6 @@
"dashboard.overview.notifications.loading": {
"message": "Notificaties aan het laden..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "U kunt meerdere projecten tegelijkertijd bijwerken door ze hieronder te selecteren."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Massa wijzigingen worden niet ondersteund door server projecten"
},
@@ -1424,12 +1409,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Controller project metadata alstublieft"
},
"dashboard.projects.sort.option.name": {
"message": "Naam"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.table.name": {
"message": "Naam"
},
@@ -2813,45 +2792,21 @@
"project.details.licensed": {
"message": "Gelicentieerd"
},
"project.download.game-version": {
"message": "Spel versie: {version}"
},
"project.download.game-version-error": {
"message": "Error: geen spel-versies gevonden"
},
"project.download.game-version-tooltip": {
"message": "{title} is alleen beschikbaar voor {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} steunt niet {gameVersion} voor {platform}"
},
"project.download.install-with-app": {
"message": "Installeer met de Modrinth App"
},
"project.download.no-app": {
"message": "Heb je de Modrinth App niet?"
},
"project.download.no-versions-available": {
"message": "Geen versies beschikbaar voor {gameVersion} en {platform}."
},
"project.download.platform": {
"message": "Platform: {platform}"
},
"project.download.platform-error": {
"message": "Error: geen platformen gevonden"
},
"project.download.platform-tooltip": {
"message": "{title} is alleen beschikbaar voor {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} steunt niet {platform} voor {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Game-versies zoeken..."
},
"project.download.search-game-versions-label": {
"message": "Zoek game-versies..."
},
"project.download.select-game-version": {
"message": "Selecteer game-versie"
},
@@ -254,18 +254,9 @@
"auth.reset-password.title.long": {
"message": "Tilbakestill passordet dit"
},
"auth.sign-in.2fa.description": {
"message": "Vennligst skriv inn en tofaktor-kode for å fortsette."
},
"auth.sign-in.2fa.label": {
"message": "Skriv inn tofaktor-kode"
},
"auth.sign-in.2fa.placeholder": {
"message": "Skriv inn kode..."
},
"auth.sign-in.sign-in-with": {
"message": "Logg inn med"
},
"auth.sign-in.title": {
"message": "Logg inn"
},
@@ -278,9 +269,6 @@
"auth.sign-up.title": {
"message": "Registrer deg"
},
"auth.sign-up.title.sign-up-with": {
"message": "Registrer deg med"
},
"auth.verify-email.action.account-settings": {
"message": "Kontoinstillinger"
},
@@ -863,9 +851,6 @@
"dashboard.organizations.title": {
"message": "Organiseringer"
},
"dashboard.projects.bulk-edit-hint": {
"message": "Du kan redigere flere prosjekt samtidig ved å velge dem nedafor."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Serverprosjekt støtter ikke massredigering"
},
@@ -2264,45 +2249,21 @@
"project.details.licensed": {
"message": "Lisensert"
},
"project.download.game-version": {
"message": "Spillversjon: {version}"
},
"project.download.game-version-error": {
"message": "Error: ingen spillversjon funnet"
},
"project.download.game-version-tooltip": {
"message": "{title} er bare tilgjengelig for {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} støtter ikke {gameVersion} for {platform}"
},
"project.download.install-with-app": {
"message": "Installer med Modrinth App"
},
"project.download.no-app": {
"message": "Har du ikke en Modrinth App?"
},
"project.download.no-versions-available": {
"message": "Ingen versjoner tilgjengelige for {gameVersion} og {platform}."
},
"project.download.platform": {
"message": "Plattform: {platform}"
},
"project.download.platform-error": {
"message": "Error: Ingen plattformer funnet"
},
"project.download.platform-tooltip": {
"message": "{title} er bare tilgjengelig for {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} støtter ikke {platform} for {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Søk opp spillversjoner..."
},
"project.download.search-game-versions-label": {
"message": "Søk opp spillversjoner..."
},
"project.download.select-game-version": {
"message": "Velg spillversjon"
},
+286 -61
View File
@@ -387,7 +387,7 @@
"message": "Rozkład:"
},
"analytics.query.label.grouped-by": {
"message": "Grupowane wg."
"message": "Grupowane wg"
},
"analytics.query.label.project": {
"message": "Projekt:"
@@ -731,12 +731,72 @@
"auth.authorize.authorize-app-name": {
"message": "Autoryzuj {appName}"
},
"auth.authorize.error.missing-parameters": {
"message": "Brak wymaganych parametrów zapytania OAuth."
},
"auth.authorize.error.no-redirect-url": {
"message": "Nie znaleziono lokalizacji przekierowania w odpowiedzi"
},
"auth.authorize.errro-title": {
"message": "Wystąpił błąd"
},
"auth.authorize.redirect-url": {
"message": "Zostaniesz przekierowany do <redirect-url>{url}</redirect-url>"
},
"auth.continue-with-provider": {
"message": "Kontynuuj przez {provider}"
},
"auth.create-account.age-requirement.warning-title": {
"message": "Wymaganie wiekowe"
},
"auth.create-account.complete-sign-up": {
"message": "Zakończ rejestrację"
},
"auth.create-account.date-of-birth.invalid.text": {
"message": "Prosimy o podanie prawidłowej daty urodzenia. Rok 0000 jest nieprawidłowy."
},
"auth.create-account.date-of-birth.invalid.title": {
"message": "Nieprawidłowa data urodzenia"
},
"auth.create-account.date-of-birth.label": {
"message": "Data urodzenia"
},
"auth.create-account.date-of-birth.placeholder": {
"message": "Wprowadź datę urodzenia"
},
"auth.create-account.date-of-birth.required.text": {
"message": "Prosimy o podanie twojej daty urodzenia przed kontynuowaniem."
},
"auth.create-account.date-of-birth.required.title": {
"message": "Wymagana data urodzenia"
},
"auth.create-account.date-of-birth.under13-helper": {
"message": "Nie spełniasz wymagań wiekowych, aby utworzyć konto na Modrinth."
},
"auth.create-account.info-panel.source-code-link": {
"message": "Kod źródłowy funkcji"
},
"auth.create-account.info-panel.text": {
"message": "Nie zapisujemy Twojej daty urodzenia. Sprawdzamy ją tylko podczas tworzenia konta, by potwierdzić zgodność z COPPA."
},
"auth.create-account.page-title": {
"message": "Utwórz konto"
},
"auth.create-account.security-check.label": {
"message": "Test bezpieczeństwa"
},
"auth.create-account.subscribe.label": {
"message": "Wysyłaj mi nowinki o Modrinth przez e-mail"
},
"auth.create-account.title": {
"message": "Utwórz konto"
},
"auth.create-account.username.label": {
"message": "Nazwa użytkownika"
},
"auth.create-account.username.placeholder": {
"message": "Wprowadź nazwę użytkownika"
},
"auth.reset-password.method-choice.action": {
"message": "Wyślij e-mail do odzyskania konta"
},
@@ -771,23 +831,53 @@
"message": "Zresetuj swoje hasło"
},
"auth.sign-in.2fa.description": {
"message": "Wprowadź otrzymany kod, aby kontynuować."
"message": "Wprowadź 6-znakowy kod z aplikacji autoryzującej lub jeden z kodów zapasowych."
},
"auth.sign-in.2fa.label": {
"message": "Wprowadź otrzymany kod"
"message": "Weryfikacja dwuetapowa"
},
"auth.sign-in.2fa.placeholder": {
"message": "Wprowadź kod..."
},
"auth.sign-in.continue-with-email": {
"message": "Kontynuuj przez e-mail"
},
"auth.sign-in.continue-with-passkey": {
"message": "Kontynuuj przez klucz logowania"
},
"auth.sign-in.create-account": {
"message": "Zarejestruj się"
},
"auth.sign-in.forgot-password": {
"message": "Nie pamiętam hasła"
},
"auth.sign-in.last-sign-in": {
"message": "Ostatnio użyty"
},
"auth.sign-in.no-account": {
"message": "Nie masz konta?"
},
"auth.sign-in.sign-in-with": {
"message": "Zaloguj się przez"
"message": "Zaloguj się na Modrinth"
},
"auth.sign-in.title": {
"message": "Zaloguj się"
},
"auth.sign-up.age-requirement.warning-title": {
"message": "Wymaganie wiekowe"
},
"auth.sign-up.continue-with-email": {
"message": "Kontynuuj przez e-mail"
},
"auth.sign-up.legal-dislaimer": {
"message": "Tworząc konto, wyrażasz zgodę na <terms-link>Warunki</terms-link> i <privacy-policy-link>Politykę Prywatności</privacy-policy-link> Modrinth."
},
"auth.sign-up.show-fewer-options": {
"message": "Pokaż mniej opcji"
},
"auth.sign-up.show-other-options": {
"message": "Pokaż inne opcje"
},
"auth.sign-up.sign-in-option.title": {
"message": "Masz już konto?"
},
@@ -795,11 +885,14 @@
"message": "Zarejestruj się"
},
"auth.sign-up.title.sign-up-with": {
"message": "Zarejestruj się przez"
"message": "Utwórz konto"
},
"auth.verify-email.action.account-settings": {
"message": "Ustawienia konta"
},
"auth.verify-email.action.discover-mods": {
"message": "Odkrywaj modyfikacje"
},
"auth.verify-email.already-verified.description": {
"message": "Twój e-mail jest już zweryfikowany!"
},
@@ -818,6 +911,15 @@
"auth.verify-email.failed-verification.title": {
"message": "Weryfikacja e-maila nie powiodła się"
},
"auth.verify-email.notification.email-sent.description": {
"message": "E-mail z linkiem do weryfikacji Twojego konta został wysłany na adres {email}."
},
"auth.verify-email.notification.email-sent.title": {
"message": "E-mail wysłany"
},
"auth.verify-email.notification.error-occurred.title": {
"message": "Wystąpił błąd"
},
"auth.verify-email.post-verification.description": {
"message": "Twój adres e-mail został pomyślnie zweryfikowany!"
},
@@ -1532,9 +1634,6 @@
"dashboard.overview.notifications.loading": {
"message": "Ładowanie powiadomień..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Możesz edytować kilka projektów naraz, zaznaczając je poniżej."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Projekty serwerów nie wspierają grupowej edycji"
},
@@ -1607,24 +1706,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Sprawdź metadane środowiska"
},
"dashboard.projects.sort.ascending": {
"message": "Rosnąco"
},
"dashboard.projects.sort.descending": {
"message": "Malejąco"
},
"dashboard.projects.sort.option.name": {
"message": "Nazwa"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Rodzaj"
},
"dashboard.projects.table.icon": {
"message": "Ikona"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -3134,45 +3215,21 @@
"project.details.licensed": {
"message": "Licencja"
},
"project.download.game-version": {
"message": "Wersja gry: {version}"
},
"project.download.game-version-error": {
"message": "Błąd: nie znaleziono wersji gry"
},
"project.download.game-version-tooltip": {
"message": "{title} jest dostępny tylko dla {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} nie obsługuje {gameVersion} dla {platform}"
},
"project.download.install-with-app": {
"message": "Zainstaluj za pomocą Modrinth App"
},
"project.download.no-app": {
"message": "Nie masz Modrinth App?"
},
"project.download.no-versions-available": {
"message": "Brak dostępnych wersji dla {gameVersion} i {platform}."
},
"project.download.platform": {
"message": "Platforma: {platform}"
},
"project.download.platform-error": {
"message": "Błąd: nie znaleziono żadnych platform"
},
"project.download.platform-tooltip": {
"message": "{title} jest dostępny tylko dla {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} nie obsługuje {platform} dla {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Szukaj wersji gry..."
},
"project.download.search-game-versions-label": {
"message": "Szukaj wersji gry..."
},
"project.download.select-game-version": {
"message": "Wybierz wersję gry"
},
@@ -3363,43 +3420,76 @@
"message": "URL"
},
"project.settings.permissions.attention-needed.description.proj-approved": {
"message": "Prosimy o dostarczenie dowodu, że posiadasz pozwolenie na rozpowszechnianie wszystkich poniższych plików, a wszelkie wstrzymane wersje zostaną automatycznie opublikowane."
"message": "Prosimy o dostarczenie dowodu, że posiadasz pozwolenie na rozpowszechnianie wszystkich poniższych plików. Po dostarczeniu dowodu wszelkie wstrzymane wersje zostaną automatycznie opublikowane."
},
"project.settings.permissions.attention-needed.description.proj-draft": {
"message": "Przed przesłaniem projektu do oceny prosimy o pokazanie, że posiadasz pozwolenie na rozpowszechnianie wszystkich poniższych plików."
"message": "Przed przesłaniem projektu do przeglądu prosimy o pokazanie, że posiadasz pozwolenie na rozpowszechnianie wszystkich poniższych plików."
},
"project.settings.permissions.attention-needed.title": {
"message": "Nieznana osadzona treść"
"message": "Nieznana zewnętrzna zawartość"
},
"project.settings.permissions.bad-proof.description": {
"message": "Zespół moderatorów Modrinth odrzucił podane informacje o zezwoleniach dla niektórej zawartości. Podaj poprawne dowody lub usuń podaną niżej zawartość."
},
"project.settings.permissions.bad-proof.title": {
"message": "Niektóre dowody zostały odrzucone"
},
"project.settings.permissions.collapse-all": {
"message": "Zwiń wszystkie"
},
"project.settings.permissions.completed.description": {
"message": "Wszystkie zewnętrzne treści mają podane źródła."
"message": "Wszystkie zewnętrzne treści zawierają informacje o prawach autorskich, a źródła zostały podane."
},
"project.settings.permissions.completed.title": {
"message": "Atrybuty przypisane!"
"message": "Uprawnienia gotowe!"
},
"project.settings.permissions.empty-state.description": {
"message": "Żadna z Twoich wersji nie zawiera treści zewnętrznych, więc nie musisz martwić się o uzyskanie zezwoleń."
"message": "Żadne z wersji Twojego projektu nie zawiera zewnętrznej zawartości, więc nie musisz martwić się o uzyskanie zezwoleń."
},
"project.settings.permissions.empty-state.heading": {
"message": "Wszystko gotowe!"
},
"project.settings.permissions.expand-all": {
"message": "Rozwiń wszytkie"
},
"project.settings.permissions.fail.description": {
"message": "Nie masz uprawnień do redystrybucji części dodanych przez siebie treści zewnętrznych. Aby publikować na Modrinth, usuń treści naruszające prawa autorskie."
"message": "Możesz nie mieć uprawnień do redystrybucji kilku zewnętrznych treści w twoim projekcie. Żeby publikować na Modrinth, proszę usunąć tę treść albo \nwysłać dowód, który potwierdza, że masz permisje do użycia go."
},
"project.settings.permissions.fail.title": {
"message": "Niektórych treści nie można uwzględnić"
},
"project.settings.permissions.info-banner.description": {
"message": "Jeśli zamieszczasz treści, które nie są hostowane na Modrinth, musisz poinformować nas, skąd pochodzą i potwierdzić, że masz pozwolenie na ich dystrybucję. Sprawdź <link>nasz poradnik</link>, aby dowiedzieć się, jak to zrobić poprawnie!"
"message": "Jeśli zamieszczasz treści, które nie są hostowane na Modrinth, musisz poinformować nas, skąd pochodzą i potwierdzić, że masz pozwolenie na ich dystrybucję. Zobacz <link>nasze ogłoszenie o nowym systemie</link>, aby dowiedzieć się więcej!"
},
"project.settings.permissions.info-banner.title": {
"message": "Dowiedz się, jak działają atrybuty"
"message": "Dowiedz się więcej o uprawnieniach dystrybucji"
},
"project.settings.permissions.learn-more": {
"message": "Dowiedz się więcej"
},
"project.settings.permissions.no-results": {
"message": "Nie znaleziono żadnego pliku zewnętrznego pasującego do Twojego wyszukiwania."
},
"project.settings.permissions.not-allowed.description": {
"message": "Niektóra zewnętrzna zawartość na może być dystrybuowana przez Modrinth i musi być usunięta, ponieważ jest niezgodna z naszymi Zasadami dotyczącymi treści."
},
"project.settings.permissions.pending-approval-count": {
"message": "{count, plural, =0 {Żadna atrybucja nie potrzebuje sprawdzenia} one {# atrybucja potrzebuje sprawdzenia} few{# atrybucje potrzebują sprawdzenia} other {# atrybucji potrzebuje sprawdzenia}}"
},
"project.settings.permissions.search-placeholder": {
"message": "Szukaj w {count} {count, plural, one {projekcie zewnętrznym} other {projektach zewnętrznych}}..."
"message": "Szukaj wśród {count} {count, plural, one {projektu} other {projektów}}..."
},
"project.settings.permissions.sort.most-files": {
"message": "Najwięcej plików"
},
"project.settings.permissions.sort.recently-edited": {
"message": "Ostatnio edytowane"
},
"project.settings.permissions.sort.rejected": {
"message": "Odrzucone"
},
"project.settings.permissions.sort.status": {
"message": "Status"
},
"project.settings.title": {
"message": "Ustawienia"
@@ -3959,6 +4049,48 @@
"settings.account.security.email.title": {
"message": "E-mail"
},
"settings.account.security.passkey.add": {
"message": "Dodaj klucz logowania"
},
"settings.account.security.passkey.add-modal.name.description": {
"message": "Wybierz coś, co zapamiętasz, by móć później rozpoznać ten klucz logowania."
},
"settings.account.security.passkey.add-modal.name.label": {
"message": "Nazwa"
},
"settings.account.security.passkey.add-modal.name.placeholder": {
"message": "Moje klucze logowania"
},
"settings.account.security.passkey.description": {
"message": "Zarządzaj kluczami logowania lub dodaj nowe."
},
"settings.account.security.passkey.modal.added": {
"message": "Dodano {ago}"
},
"settings.account.security.passkey.modal.last-used": {
"message": "Ostatnio użyty {ago}"
},
"settings.account.security.passkey.modal.loading": {
"message": "Ładowanie kluczy logowania…"
},
"settings.account.security.passkey.modal.never-used": {
"message": "Nigdy nie użyty"
},
"settings.account.security.passkey.modal.no-passkeys": {
"message": "Nie masz żadnych kluczy logowania."
},
"settings.account.security.passkey.remove.description": {
"message": "To trwale usunie klucz logowania \"{name}\". Nie będzie można się nim zalogować."
},
"settings.account.security.passkey.remove.title": {
"message": "Czy na pewno chcesz usunąć ten klucz logowania?"
},
"settings.account.security.passkey.rename-modal.header": {
"message": "Zmień nazwę klucza logowania"
},
"settings.account.security.passkey.title": {
"message": "Zarządzaj kluczami logowania"
},
"settings.account.security.password.action.add": {
"message": "Dodaj hasło"
},
@@ -4146,7 +4278,7 @@
"message": "Kiedy autoryzujesz aplikacje ze swoim kontem Modrinth, dajesz jej dostęp do swojego konta. Możesz tutaj zawsze zarządzać oraz przeglądać stan aplikacji z dostępem do Twojego konta."
},
"settings.authorizations.empty-state": {
"message": "Nie udało się nam wyświetlić twoich zautoryzowanych aplikacji, pracujemy nad tym, aby to naprawić. Odwiedź tę stronę później, w innym czasie!"
"message": "Nie udało się nam wyświetlić twoich zautoryzowanych aplikacji, pracujemy nad tym, aby to naprawić. Odwiedź tę stronę później!"
},
"settings.authorizations.head-title": {
"message": "Autoryzacje"
@@ -4571,6 +4703,48 @@
"ui.newsletter-button.tooltip": {
"message": "Subskrybuj do newslettera Modrinth"
},
"version.all-versions": {
"message": "Wszystkie wersje"
},
"version.confirm-delete.description": {
"message": "Ta wersja zostanie trwale usunięta. Tej akcji nie będzie można cofnąć."
},
"version.confirm-delete.proceed": {
"message": "Usuń wersję"
},
"version.confirm-delete.title": {
"message": "Czy na pewno chcesz usunąć tę wersję?"
},
"version.dependency.view-project": {
"message": "Pokaż projekt"
},
"version.dependency.view-version": {
"message": "Pokaż wersję"
},
"version.download.download-dependency": {
"message": "Pobierz zależność"
},
"version.download.no-primary-file": {
"message": "Błąd: Nie znaleziono pliku głównego"
},
"version.download.optional-resource-pack": {
"message": "Opcjonalna paczka zasobów"
},
"version.download.required-resource-pack": {
"message": "Wymagana paczka zasobów"
},
"version.edit.button": {
"message": "Edytuj"
},
"version.edit.details": {
"message": "Edytuj szczegóły"
},
"version.edit.files": {
"message": "Edytuj pliki"
},
"version.edit.metadata": {
"message": "Edytuj metadane"
},
"version.environment.none.description": {
"message": "Środowisko dla tej wersji nie zostało określone."
},
@@ -4582,5 +4756,56 @@
},
"version.environment.unknown.title": {
"message": "Nieznane środowisko"
},
"version.package-as-mod.button": {
"message": "Zapakuj jako mod"
},
"version.package-as-mod.description": {
"message": "Stworzy to nową wersję wspierającą wybrane loadery modów. Po przekierowaniu możesz dalej edytować nową wersję."
},
"version.package-as-mod.header": {
"message": "Zapakuj paczkę danych jako mod"
},
"version.package-as-mod.mod-loaders": {
"message": "Loadery modów"
},
"version.package-as-mod.mod-loaders.description": {
"message": "Loadery modów, dla których ma być zapakowana ta paczka danych."
},
"version.package-as-mod.mod-loaders.placeholder": {
"message": "Wybierz loadery modów..."
},
"version.package-as-mod.submit-button": {
"message": "Zapakuj paczkę danych"
},
"version.section.content.dev-info": {
"message": "Informacje dla twórców"
},
"version.section.content.dev-info.gradle-snippet": {
"message": "build.gradle:"
},
"version.section.content.dev-info.maven-coordinates": {
"message": "Koordynaty Maven:"
},
"version.section.content.dev-info.maven-description": {
"message": "Projekty na Modrinth są automatycznie dostępne przez repozytorium Maven do użytku z narzędziami takimi jak <gradle-link>Gradle</gradle-link>. By dowiedzieć się więcej o API Maven Modrinth, <article-link>kliknij tutaj</article-link>."
},
"version.section.content.dev-info.maven-note": {
"message": "Uwaga: Jeśli jest to możliwe, zalecanie jest używanie repozytorium Maven od twórcy projektu, ponieważ może zawierać przejściowe informacje o zależnościach, o których nie wie API Maven Modrinth. Możesz także skończyć z duplikatami niektórych zależności mieszając repozytoria Maven z i spoza Modrinth, ponieważ identyfikatory grup będą się różnić."
},
"version.section.content.dev-info.version-id": {
"message": "Identyfikator wersji:"
},
"version.supplementary-resources.copy-hash-sha1": {
"message": "Kopiuj SHA-1"
},
"version.supplementary-resources.copy-hash-sha512": {
"message": "Kopiuj SHA-512"
},
"version.unknown-embedded-content.description": {
"message": "Ta wersja jest aktualnie wstrzymana i nie jest widoczna publicznie. Podaj dowód na to, że możesz rozpowszechniać niektóre zawarte pliki."
},
"version.unknown-embedded-content.title": {
"message": "Wstrzymane z powodu nieznanej zewnętrznej zawartości"
}
}
+284 -59
View File
@@ -731,12 +731,72 @@
"auth.authorize.authorize-app-name": {
"message": "Autorizar {appName}"
},
"auth.authorize.error.missing-parameters": {
"message": "Parâmetros de consulta OAuth necessários faltando."
},
"auth.authorize.error.no-redirect-url": {
"message": "Sem redirecionamento encontrado na resposta"
},
"auth.authorize.errro-title": {
"message": "Ocorreu Um Erro"
},
"auth.authorize.redirect-url": {
"message": "Você será redirecionado para <redirect-url>{url}</redirect-url>"
},
"auth.continue-with-provider": {
"message": "Continuar com {provider}"
},
"auth.create-account.age-requirement.warning-title": {
"message": "Requisito de idade"
},
"auth.create-account.complete-sign-up": {
"message": "Concluir registro"
},
"auth.create-account.date-of-birth.invalid.text": {
"message": "Insira uma data de nascimento válida. O ano não pode ser 0000."
},
"auth.create-account.date-of-birth.invalid.title": {
"message": "Data de nascimento inválida"
},
"auth.create-account.date-of-birth.label": {
"message": "Data de nascimento"
},
"auth.create-account.date-of-birth.placeholder": {
"message": "Selecione sua data de nascimento"
},
"auth.create-account.date-of-birth.required.text": {
"message": "Primeiro, insira sua data de nascimento para prosseguir."
},
"auth.create-account.date-of-birth.required.title": {
"message": "Data de nascimento necessária"
},
"auth.create-account.date-of-birth.under13-helper": {
"message": "Você não atende ao requisito de idade para criar uma conta no Modrinth."
},
"auth.create-account.info-panel.source-code-link": {
"message": "Código-fonte relevante"
},
"auth.create-account.info-panel.text": {
"message": "Não armazenamos sua data de nascimento. Só usamos durante o registro para validar os cumprimentos COPPA."
},
"auth.create-account.page-title": {
"message": "Criar conta"
},
"auth.create-account.security-check.label": {
"message": "Verificação de segurança"
},
"auth.create-account.subscribe.label": {
"message": "Mantenha-me informado por e-mail sobre coisas legais que o Modrinth está trabalhando"
},
"auth.create-account.title": {
"message": "Criar uma Conta"
},
"auth.create-account.username.label": {
"message": "Nome de usuário"
},
"auth.create-account.username.placeholder": {
"message": "Inserir nome de usuário"
},
"auth.reset-password.method-choice.action": {
"message": "Enviar e-mail de recuperação"
},
@@ -771,23 +831,53 @@
"message": "Redefina sua senha"
},
"auth.sign-in.2fa.description": {
"message": "Insira o código de dois fatores para prosseguir."
"message": "Insira o código de 6 dígitos do aplicativo de autenticação ou um dos códigos de backup."
},
"auth.sign-in.2fa.label": {
"message": "Insira o código de dois fatores"
"message": "Autenticação de dois fatores"
},
"auth.sign-in.2fa.placeholder": {
"message": "Insira o código..."
},
"auth.sign-in.continue-with-email": {
"message": "Continuar com e-mail"
},
"auth.sign-in.continue-with-passkey": {
"message": "Continuar com chave de acesso"
},
"auth.sign-in.create-account": {
"message": "Entrar"
},
"auth.sign-in.forgot-password": {
"message": "Esqueci a senha"
},
"auth.sign-in.last-sign-in": {
"message": "Último uso"
},
"auth.sign-in.no-account": {
"message": "Não possui uma conta?"
},
"auth.sign-in.sign-in-with": {
"message": "Iniciar sessão com"
"message": "Entrar no Modrinth"
},
"auth.sign-in.title": {
"message": "Iniciar sessão"
},
"auth.sign-up.age-requirement.warning-title": {
"message": "Requisito de idade"
},
"auth.sign-up.continue-with-email": {
"message": "Continuar com e-mail"
},
"auth.sign-up.legal-dislaimer": {
"message": "Ao criar uma conta, você concorda com os <terms-link>Termos</terms-link> e a <privacy-policy-link>Política de Privacidade</privacy-policy-link>."
},
"auth.sign-up.show-fewer-options": {
"message": "Exibir menos opções"
},
"auth.sign-up.show-other-options": {
"message": "Exibir outras opções"
},
"auth.sign-up.sign-in-option.title": {
"message": "Já possui uma conta?"
},
@@ -795,11 +885,14 @@
"message": "Criar conta"
},
"auth.sign-up.title.sign-up-with": {
"message": "Criar conta com"
"message": "Criar uma Conta"
},
"auth.verify-email.action.account-settings": {
"message": "Configuração da conta"
},
"auth.verify-email.action.discover-mods": {
"message": "Descobrir mods"
},
"auth.verify-email.already-verified.description": {
"message": "Seu e-mail já está verificado!"
},
@@ -818,6 +911,15 @@
"auth.verify-email.failed-verification.title": {
"message": "A verificação de e-mail falhou"
},
"auth.verify-email.notification.email-sent.description": {
"message": "Um e-mail foi enviado para {email} com um link para verificar sua conta."
},
"auth.verify-email.notification.email-sent.title": {
"message": "E-mail enviado"
},
"auth.verify-email.notification.error-occurred.title": {
"message": "Ocorreu um erro"
},
"auth.verify-email.post-verification.description": {
"message": "Seu e-mail foi verificado com sucesso!"
},
@@ -1529,9 +1631,6 @@
"dashboard.overview.notifications.loading": {
"message": "Carregando notificações..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Você pode editar vários projetos em simultâneo, selecionando-os abaixo."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Os projetos de servidor não suportam edição em massa"
},
@@ -1607,24 +1706,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Por favor, revise os metadados do ambiente"
},
"dashboard.projects.sort.ascending": {
"message": "Crescente"
},
"dashboard.projects.sort.descending": {
"message": "Decrescente"
},
"dashboard.projects.sort.option.name": {
"message": "Nome"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Tipo"
},
"dashboard.projects.table.icon": {
"message": "Ícone"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -3131,45 +3212,21 @@
"project.details.licensed": {
"message": "Licença"
},
"project.download.game-version": {
"message": "Versão do jogo: {version}"
},
"project.download.game-version-error": {
"message": "Erro: nenhuma versão do jogo encontrada"
},
"project.download.game-version-tooltip": {
"message": "{title} só está disponível para {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} não suporta a {gameVersion} para {platform}"
},
"project.download.install-with-app": {
"message": "Instalar com o Modrinth App"
},
"project.download.no-app": {
"message": "Não tem o Modrinth App?"
},
"project.download.no-versions-available": {
"message": "Nenhuma versão disponível para {gameVersion} e {platform}."
},
"project.download.platform": {
"message": "Plataforma: {platform}"
},
"project.download.platform-error": {
"message": "Erro: nenhuma plataforma encontrada"
},
"project.download.platform-tooltip": {
"message": "{title} só está disponível para {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} não suporta {platform} para {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Buscar versões do jogo..."
},
"project.download.search-game-versions-label": {
"message": "Buscar versões do jogo..."
},
"project.download.select-game-version": {
"message": "Selecionar versão do jogo"
},
@@ -3360,43 +3417,76 @@
"message": "URL"
},
"project.settings.permissions.attention-needed.description.proj-approved": {
"message": "Forneça a prova que possui permissão para redistribuir todos os seguintes arquivos e a versão retida será publicada automaticamente."
"message": "Forneça a prova que possui permissão para redistribuir todos os seguintes arquivos. Após a conclusão, as versões retidas serão publicadas automaticamente."
},
"project.settings.permissions.attention-needed.description.proj-draft": {
"message": "Forneça a prova que possui permissão para redistribuir todos os seguintes arquivos antes de apresentar seu projeto para revisão."
"message": "Forneça a prova que possui permissão para redistribuir todos os seguintes arquivos antes de enviar seu projeto para revisão."
},
"project.settings.permissions.attention-needed.title": {
"message": "Conteúdo incluso desconhecido"
"message": "Conteúdo externo desconhecido"
},
"project.settings.permissions.bad-proof.description": {
"message": "A equipe de moderação do Modrinth rejeitou as informações de permissão que você forneceu para alguns conteúdos externos. Por favor, revise os itens rejeitados abaixo e forneça provas aceitáveis ou remova o conteúdo."
},
"project.settings.permissions.bad-proof.title": {
"message": "Algumas provas foram rejeitadas"
},
"project.settings.permissions.collapse-all": {
"message": "Recolher tudo"
},
"project.settings.permissions.completed.description": {
"message": "Todos os conteúdos externos possuem atribuição inclusa."
"message": "Todo o conteúdo externo possui informações de permissão e as atribuições foram fornecidas."
},
"project.settings.permissions.completed.title": {
"message": "Atribuições concluídas!"
"message": "Permissões concluídas!"
},
"project.settings.permissions.empty-state.description": {
"message": "Nenhuma de suas versões contém conteúdo externo, não há o que se preocupar sobre adquirir permissões."
"message": "Nenhuma das versões do seu projeto contém conteúdo externo, não há o que se preocupar sobre adquirir permissões."
},
"project.settings.permissions.empty-state.heading": {
"message": "Tudo joia!"
},
"project.settings.permissions.expand-all": {
"message": "Expandir tudo"
},
"project.settings.permissions.fail.description": {
"message": "Você não possui permissão para redistribuir algum dos conteúdos externos que adicionou. Para poder publicar no Modrinth, remova os conteúdos que infringem."
"message": "Você pode não ter permissão para redistribuir parte do conteúdo externo do seu projeto. Para publicar no Modrinth, remova esse conteúdo ou forneça um comprovante de que você tem permissão para usá-lo."
},
"project.settings.permissions.fail.title": {
"message": "Alguns conteúdos não puderam ser incluídos"
},
"project.settings.permissions.info-banner.description": {
"message": "Se você incluir conteúdo que não é fornecido pelo Modrinth, você precisa nos contar de onde isso vem e verificar que você tem permissão para distribuir os arquivos. Veja <link>nosso guia</link> para saber mais como fazer do jeito certo!"
"message": "Se você incluir conteúdo que não é fornecido pelo Modrinth, você precisa nos contar de onde isso vem e verificar que você tem permissão para distribuir os arquivos. Confira <link>nosso anúncio sobre este novo sistema</link> para saber mais!"
},
"project.settings.permissions.info-banner.title": {
"message": "Saiba como atribuições funcionam"
"message": "Saiba mais sobre permissões de distribuição"
},
"project.settings.permissions.learn-more": {
"message": "Saber mais"
},
"project.settings.permissions.no-results": {
"message": "Nenhum arquivo externo corresponde à sua busca."
},
"project.settings.permissions.not-allowed.description": {
"message": "Alguns dos conteúdos externos incluídos não podem ser distribuídos no Modrinth porque violam nossas Regras de Conteúdo e devem ser removidos."
},
"project.settings.permissions.pending-approval-count": {
"message": "{count, plural, =0 {Nenhuma atribuição precisa de aprovação} one {# atribuição precisa de aprovação} other {# atribuições precisam de aprovação}}"
},
"project.settings.permissions.search-placeholder": {
"message": "Buscar {count} {count, plural,one {projeto externo} other {projetos externos}}..."
"message": "Buscar {count} {count, plural, one {projeto} other {projetos}}..."
},
"project.settings.permissions.sort.most-files": {
"message": "Maioria dos arquivos"
},
"project.settings.permissions.sort.recently-edited": {
"message": "Editado recentemente"
},
"project.settings.permissions.sort.rejected": {
"message": "Rejeitado"
},
"project.settings.permissions.sort.status": {
"message": "Status"
},
"project.settings.title": {
"message": "Configurações"
@@ -3956,6 +4046,48 @@
"settings.account.security.email.title": {
"message": "E-mail"
},
"settings.account.security.passkey.add": {
"message": "Adicionar chave de acesso"
},
"settings.account.security.passkey.add-modal.name.description": {
"message": "Certifique-se de adicionar algo memorável, para poder identificar mais tarde."
},
"settings.account.security.passkey.add-modal.name.label": {
"message": "Nome"
},
"settings.account.security.passkey.add-modal.name.placeholder": {
"message": "Minha chave de acesso"
},
"settings.account.security.passkey.description": {
"message": "Gerencie suas chaves de acesso registradas ou adicione uma nova."
},
"settings.account.security.passkey.modal.added": {
"message": "Adicionado {ago}"
},
"settings.account.security.passkey.modal.last-used": {
"message": "Usado pela última vez em {ago}"
},
"settings.account.security.passkey.modal.loading": {
"message": "Carregando chaves de acesso…"
},
"settings.account.security.passkey.modal.never-used": {
"message": "Nunca usado"
},
"settings.account.security.passkey.modal.no-passkeys": {
"message": "Você não possui chaves de acesso registradas."
},
"settings.account.security.passkey.remove.description": {
"message": "Isso removerá permanentemente a chave de acesso \"{name}\". Você não poderá mais entrar usando ela."
},
"settings.account.security.passkey.remove.title": {
"message": "Tem certeza que quer remover esta chave de acesso?"
},
"settings.account.security.passkey.rename-modal.header": {
"message": "Renomear chave de acesso"
},
"settings.account.security.passkey.title": {
"message": "Gerenciar chaves de acesso"
},
"settings.account.security.password.action.add": {
"message": "Adicionar senha"
},
@@ -4568,6 +4700,48 @@
"ui.newsletter-button.tooltip": {
"message": "Inscreva-se no boletim informativo do Modrinth"
},
"version.all-versions": {
"message": "Todas as versões"
},
"version.confirm-delete.description": {
"message": "Esta versão será excluída permanentemente. Esta ação não pode ser desfeita."
},
"version.confirm-delete.proceed": {
"message": "Excluir versão"
},
"version.confirm-delete.title": {
"message": "Tem certeza de que deseja excluir esta versão?"
},
"version.dependency.view-project": {
"message": "Ver projeto"
},
"version.dependency.view-version": {
"message": "Ver versão"
},
"version.download.download-dependency": {
"message": "Baixar dependência"
},
"version.download.no-primary-file": {
"message": "Erro: Nenhum arquivo primário encontrado"
},
"version.download.optional-resource-pack": {
"message": "Pacote de recursos opcional"
},
"version.download.required-resource-pack": {
"message": "Pacote de recursos necessário"
},
"version.edit.button": {
"message": "Editar"
},
"version.edit.details": {
"message": "Editar detalhes"
},
"version.edit.files": {
"message": "Editar arquivos"
},
"version.edit.metadata": {
"message": "Editar metadados"
},
"version.environment.none.description": {
"message": "O ambiente para esta versão não foi especificado."
},
@@ -4579,5 +4753,56 @@
},
"version.environment.unknown.title": {
"message": "Ambiente desconhecido"
},
"version.package-as-mod.button": {
"message": "Empacotar como mod"
},
"version.package-as-mod.description": {
"message": "Isso criará uma versão com suporte para os carregadores de mods selecionados. Você será redirecionado para a nova versão e poderá editá-la como quiser."
},
"version.package-as-mod.header": {
"message": "Empacotar pacote de dados como mod"
},
"version.package-as-mod.mod-loaders": {
"message": "Carregadores de mods"
},
"version.package-as-mod.mod-loaders.description": {
"message": "Os carregadores de mods para os quais você gostaria de empacotar seu pacote de dados."
},
"version.package-as-mod.mod-loaders.placeholder": {
"message": "Escolher carregadores de mods..."
},
"version.package-as-mod.submit-button": {
"message": "Empacotar pacote de dados"
},
"version.section.content.dev-info": {
"message": "Informações do desenvolvedor"
},
"version.section.content.dev-info.gradle-snippet": {
"message": "build.gradle:"
},
"version.section.content.dev-info.maven-coordinates": {
"message": "Coordenadas do Maven:"
},
"version.section.content.dev-info.maven-description": {
"message": "Os projetos no Modrinth são disponibilizados automaticamente através de um repositório Maven para uso com ferramentas de compilação JVM, como o <gradle-link>Gradle</gradle-link>. Para saber mais sobre a API Maven do Modrinth, <article-link>clique aqui</article-link>."
},
"version.section.content.dev-info.maven-note": {
"message": "Nota: Quando disponível, você deve usar o repositório Maven do criador, pois ele conterá informações de dependências transitivas que a API Maven do Modrinth não possui. Você também pode acabar com dependências duplicadas se usar uma mistura de repositórios Maven do Modrinth e de fora do Modrinth para suas dependências, porque o identificador de grupo (group identifier) será diferente quando servido através da API Maven do Modrinth."
},
"version.section.content.dev-info.version-id": {
"message": "ID da versão:"
},
"version.supplementary-resources.copy-hash-sha1": {
"message": "Copiar SHA-1"
},
"version.supplementary-resources.copy-hash-sha512": {
"message": "Copiar SHA-512"
},
"version.unknown-embedded-content.description": {
"message": "Esta versão está atualmente retida e não está listada publicamente. Por favor, forneça comprovante de que você tem permissão para redistribuir determinados arquivos incluídos."
},
"version.unknown-embedded-content.title": {
"message": "Retido devido a conteúdo incorporado desconhecido"
}
}
@@ -254,18 +254,9 @@
"auth.reset-password.title.long": {
"message": "Redefine a tua palavra-passe"
},
"auth.sign-in.2fa.description": {
"message": "Insere um código de dois fatores para continuar."
},
"auth.sign-in.2fa.label": {
"message": "Autenticação de dois fatores"
},
"auth.sign-in.2fa.placeholder": {
"message": "Inserir código..."
},
"auth.sign-in.sign-in-with": {
"message": "Iniciar sessão com"
},
"auth.sign-in.title": {
"message": "Iniciar sessão"
},
@@ -278,9 +269,6 @@
"auth.sign-up.title": {
"message": "Criar conta"
},
"auth.sign-up.title.sign-up-with": {
"message": "Criar conta com"
},
"auth.verify-email.action.account-settings": {
"message": "Definições de conta"
},
@@ -833,18 +821,6 @@
"dashboard.projects.links.wiki-page.label": {
"message": "Página da Wiki"
},
"dashboard.projects.sort.option.name": {
"message": "Nome"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Tipo"
},
"dashboard.projects.table.icon": {
"message": "Ícone"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -2246,45 +2222,21 @@
"project.details.licensed": {
"message": "Licenciado"
},
"project.download.game-version": {
"message": "Versão do jogo: {version}"
},
"project.download.game-version-error": {
"message": "Erro: nenhuma versão do jogo encontrada"
},
"project.download.game-version-tooltip": {
"message": "{title} apenas está disponível para {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} não suporta {gameVersion} para {platform}"
},
"project.download.install-with-app": {
"message": "Instala com a Modrinth App"
},
"project.download.no-app": {
"message": "Não tens a Modrinth App?"
},
"project.download.no-versions-available": {
"message": "Nenhuma versão disponível para {gameVersion} e {platform}."
},
"project.download.platform": {
"message": "Plataforma: {platform}"
},
"project.download.platform-error": {
"message": "Erro: nenhuma plataforma encontrada"
},
"project.download.platform-tooltip": {
"message": "{title} apenas está disponível para {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} não suporta {platform} para {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Procurar versões do jogo..."
},
"project.download.search-game-versions-label": {
"message": "Procurar versões do jogo..."
},
"project.download.select-game-version": {
"message": "Selecionar versão do jogo"
},
@@ -248,18 +248,9 @@
"auth.reset-password.title.long": {
"message": "Resetează-ți parola"
},
"auth.sign-in.2fa.description": {
"message": "Te rugăm să introduci codul de autorizare în doi pași (2FA) pentru a continua."
},
"auth.sign-in.2fa.label": {
"message": "Introduceți codul 2FA"
},
"auth.sign-in.2fa.placeholder": {
"message": "Introdu codul..."
},
"auth.sign-in.sign-in-with": {
"message": "Conectează-te cu"
},
"auth.sign-in.title": {
"message": "Conectare"
},
@@ -272,9 +263,6 @@
"auth.sign-up.title": {
"message": "Înregistrare"
},
"auth.sign-up.title.sign-up-with": {
"message": "Înregistrare cu"
},
"auth.verify-email.action.account-settings": {
"message": "Setările contului"
},
@@ -1427,45 +1415,21 @@
"project.details.licensed": {
"message": "Licență"
},
"project.download.game-version": {
"message": "Versiunea jocului: {version}"
},
"project.download.game-version-error": {
"message": "Eroare: nu s-au găsit versiuni ale jocului"
},
"project.download.game-version-tooltip": {
"message": "{title} este disponibil doar pentru {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} nu este compatibil cu {gameVersion} pentru {platform}"
},
"project.download.install-with-app": {
"message": "Instalează cu Modrinth App"
},
"project.download.no-app": {
"message": "Nu ai Modrinth App?"
},
"project.download.no-versions-available": {
"message": "Nu există versiuni disponibile pentru {gameVersion} și {platform}."
},
"project.download.platform": {
"message": "Platformă: {platform}"
},
"project.download.platform-error": {
"message": "Eroare: nu s-au găsit platforme"
},
"project.download.platform-tooltip": {
"message": "{title} este disponibil doar pentru {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} nu este compatibil cu {platform} pentru {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Caută versiuni ale jocului..."
},
"project.download.search-game-versions-label": {
"message": "Caută versiuni ale jocului..."
},
"project.download.select-game-version": {
"message": "Selectează versiunea jocului"
},
+293 -62
View File
@@ -23,6 +23,15 @@
"analytics.breakdown.country": {
"message": "Страна"
},
"analytics.breakdown.dependent-on": {
"message": "Зависит от"
},
"analytics.breakdown.dependent-project-download": {
"message": "Зависимый проект"
},
"analytics.breakdown.dependent-project-type": {
"message": "Тип зависимого проекта"
},
"analytics.breakdown.download-reason": {
"message": "Причина скачивания"
},
@@ -147,7 +156,7 @@
"message": "Зависит от {project}"
},
"analytics.chart.tooltip.dependent-project-version": {
"message": "{dependentProject} зависит от {dependencyProject} версии {version}"
"message": "{dependentProject} зависит от {dependencyProject}, версия {version}"
},
"analytics.chart.tooltip.duration.days": {
"message": "{count, plural, one {# день} few {# дня} other {# дней}}"
@@ -491,6 +500,9 @@
"analytics.value.no-dependent": {
"message": "Нет"
},
"analytics.value.no-dependent-tooltip": {
"message": "Скачано по иным причинам — не как зависимость"
},
"analytics.value.none": {
"message": "Нет"
},
@@ -713,12 +725,72 @@
"auth.authorize.authorize-app-name": {
"message": "Авторизация {appName}"
},
"auth.authorize.error.missing-parameters": {
"message": "Отсутствуют обязательные параметры запроса OAuth."
},
"auth.authorize.error.no-redirect-url": {
"message": "В ответе не найдена информация для перенаправления"
},
"auth.authorize.errro-title": {
"message": "Произошла ошибка"
},
"auth.authorize.redirect-url": {
"message": "Вы будете перенаправлены на <redirect-url>{url}</redirect-url>"
},
"auth.continue-with-provider": {
"message": "Продолжить с {provider}"
},
"auth.create-account.age-requirement.warning-title": {
"message": "Возрастное ограничение"
},
"auth.create-account.complete-sign-up": {
"message": "Завершить регистрацию"
},
"auth.create-account.date-of-birth.invalid.text": {
"message": "Введите корректную дату рождения."
},
"auth.create-account.date-of-birth.invalid.title": {
"message": "Неверная дата рождения"
},
"auth.create-account.date-of-birth.label": {
"message": "Дата рождения"
},
"auth.create-account.date-of-birth.placeholder": {
"message": "Укажите дату рождения"
},
"auth.create-account.date-of-birth.required.text": {
"message": "Сначала укажите дату рождения."
},
"auth.create-account.date-of-birth.required.title": {
"message": "Необходима дата рождения"
},
"auth.create-account.date-of-birth.under13-helper": {
"message": "Вы не подходите по возрастным требованиям для создания аккаунта на Modrinth."
},
"auth.create-account.info-panel.source-code-link": {
"message": "Соответствующий исходный код"
},
"auth.create-account.info-panel.text": {
"message": "Мы не храним вашу дату рождения. Она используется только при регистрации для соблюдения закона COPPA."
},
"auth.create-account.page-title": {
"message": "Создание аккаунта"
},
"auth.create-account.security-check.label": {
"message": "Проверка безопасности"
},
"auth.create-account.subscribe.label": {
"message": "Держите меня в курсе всего крутого, над чем работает Modrinth"
},
"auth.create-account.title": {
"message": "Создание аккаунта"
},
"auth.create-account.username.label": {
"message": "Имя пользователя"
},
"auth.create-account.username.placeholder": {
"message": "Введите имя"
},
"auth.reset-password.method-choice.action": {
"message": "Отправить письмо"
},
@@ -753,7 +825,7 @@
"message": "Сброс пароля"
},
"auth.sign-in.2fa.description": {
"message": "Введите код подтверждения из приложения."
"message": "Введите 6-значный код в вашем аутентификаторе, или один из резервных кодов."
},
"auth.sign-in.2fa.label": {
"message": "Двухфакторная аутентификация"
@@ -761,15 +833,45 @@
"auth.sign-in.2fa.placeholder": {
"message": "Введите код..."
},
"auth.sign-in.continue-with-email": {
"message": "Продолжить с почтой"
},
"auth.sign-in.continue-with-passkey": {
"message": "Продолжить с ключом доступа"
},
"auth.sign-in.create-account": {
"message": "Зарегистрироваться"
},
"auth.sign-in.forgot-password": {
"message": "Забыли пароль"
},
"auth.sign-in.last-sign-in": {
"message": "Активность"
},
"auth.sign-in.no-account": {
"message": "Нет аккаунта?"
},
"auth.sign-in.sign-in-with": {
"message": "Войдите через"
"message": "Вход на Modrinth"
},
"auth.sign-in.title": {
"message": "Вход"
},
"auth.sign-up.age-requirement.warning-title": {
"message": "Возрастное ограничение"
},
"auth.sign-up.continue-with-email": {
"message": "Продолжить с почтой"
},
"auth.sign-up.legal-dislaimer": {
"message": "Регистрируясь, вы принимаете наши <terms-link>условия</terms-link> и <privacy-policy-link>политику конфиденци­аль­ности</privacy-policy-link>."
},
"auth.sign-up.show-fewer-options": {
"message": "Меньше вариантов"
},
"auth.sign-up.show-other-options": {
"message": "Другие варианты"
},
"auth.sign-up.sign-in-option.title": {
"message": "Уже есть аккаунт?"
},
@@ -777,11 +879,14 @@
"message": "Регистрация"
},
"auth.sign-up.title.sign-up-with": {
"message": "Зарегистрируйтесь через"
"message": "Создать аккаунт"
},
"auth.verify-email.action.account-settings": {
"message": "Настройки аккаунта"
},
"auth.verify-email.action.discover-mods": {
"message": "Найти моды"
},
"auth.verify-email.already-verified.description": {
"message": "Ваша почта уже подтверждена!"
},
@@ -800,6 +905,15 @@
"auth.verify-email.failed-verification.title": {
"message": "Ошибка подтверждения"
},
"auth.verify-email.notification.email-sent.description": {
"message": "На {email} было отправлено письмо со ссылкой для подтверждения аккаунта."
},
"auth.verify-email.notification.email-sent.title": {
"message": "Письмо отправлено"
},
"auth.verify-email.notification.error-occurred.title": {
"message": "Произошла ошибка"
},
"auth.verify-email.post-verification.description": {
"message": "Адрес электронной почты успешно подтверждён!"
},
@@ -1514,9 +1628,6 @@
"dashboard.overview.notifications.loading": {
"message": "Загрузка уведомлений..."
},
"dashboard.projects.bulk-edit-hint": {
"message": "Можно редактировать сразу несколько проектов, выбрав их ниже."
},
"dashboard.projects.bulk-edit.server-disabled": {
"message": "Серверные проекты не поддерживают массовое редактирование"
},
@@ -1592,24 +1703,6 @@
"dashboard.projects.project.review-environment-metadata": {
"message": "Проверьте метаданные среды"
},
"dashboard.projects.sort.ascending": {
"message": "По возрастанию"
},
"dashboard.projects.sort.descending": {
"message": "По убыванию"
},
"dashboard.projects.sort.option.name": {
"message": "Название"
},
"dashboard.projects.sort.option.status": {
"message": "Статус"
},
"dashboard.projects.sort.option.type": {
"message": "Тип"
},
"dashboard.projects.table.icon": {
"message": "Иконка"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -3122,45 +3215,21 @@
"project.details.licensed": {
"message": "Лицензия"
},
"project.download.game-version": {
"message": "Версия игры: {version}"
},
"project.download.game-version-error": {
"message": "Ошибка: версии игры не найдены"
},
"project.download.game-version-tooltip": {
"message": "{title} доступен только для {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} не поддерживает {gameVersion} для {platform}"
},
"project.download.install-with-app": {
"message": "Скачать в Modrinth App"
},
"project.download.no-app": {
"message": "У вас нет Modrinth App?"
},
"project.download.no-versions-available": {
"message": "Нет версий, доступных для {gameVersion} и {platform}."
},
"project.download.platform": {
"message": "Платформа: {platform}"
},
"project.download.platform-error": {
"message": "Ошибка: платформы не найдены"
},
"project.download.platform-tooltip": {
"message": "{title} доступен только для {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} не поддерживает {platform} для {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Поиск версий игры..."
},
"project.download.search-game-versions-label": {
"message": "Поиск версий игры..."
},
"project.download.select-game-version": {
"message": "Выбрать версию игры"
},
@@ -3267,7 +3336,7 @@
"message": "Ваш проект не будет отображаться публично и будет доступен только по прямой ссылке.{requestedStatus, select, unlisted { В соответствии с выбранными вами <visibility-settings-link>настройками видимости</visibility-settings-link>, скорее всего, никаких действий не требуется.} other { Пожалуйста, устраните все замечания модерации, включая указанные в сообщениях ниже, прежде чем повторно отправлять проект на проверку.}}"
},
"project.moderation.admonition.withheld.header": {
"message": "Скрыто командой Modrinth"
"message": "Скрыт модератором"
},
"project.moderation.error.unauthorized": {
"message": "Нет доступа"
@@ -3351,43 +3420,70 @@
"message": "URL"
},
"project.settings.permissions.attention-needed.description.proj-approved": {
"message": "Пожалуйста, предоставьте доказательства, что у вас есть разрешение на распространение всех следующих файлов, а также любые скрытые версии будут опубликованы."
"message": "Пожалуйста, предоставьте доказательства, что у вас есть разрешение на распространение всех следующих файлов. После этого скрытые версии будут опубликованы."
},
"project.settings.permissions.attention-needed.description.proj-draft": {
"message": "Прежде чем отправить проект на рассмотрение, пожалуйста, подтвердите наличие у вас разрешения на распространение всех перечисленных ниже файлов."
"message": "Прежде чем отправить проект на рассмотрение, подтвердите наличие у вас разрешения на распространение всех перечисленных ниже файлов."
},
"project.settings.permissions.attention-needed.title": {
"message": "Неизвестный встроенный контент"
"message": "Неизвестный внешний контент"
},
"project.settings.permissions.bad-proof.description": {
"message": "Команда модераторов Modrinth отклонила предоставленные вами данные для разрешения доступа к некоторому стороннему контенту. Пожалуйста, просмотрите список отклоненных материалов ниже и предоставьте убедительные доказательства или удалите контент."
},
"project.settings.permissions.bad-proof.title": {
"message": "Часть доказательств отклонена"
},
"project.settings.permissions.collapse-all": {
"message": "Свернуть всё"
},
"project.settings.permissions.completed.description": {
"message": "Весь внешний контент сопровождается указанием авторства."
"message": "Для всего стороннего контента указаны разрешения и источники."
},
"project.settings.permissions.completed.title": {
"message": "Указание авторства завершено!"
"message": "Разрешения получены!"
},
"project.settings.permissions.empty-state.description": {
"message": "Ни одна из ваших версий не содержит внешнего контента, поэтому вам не нужно беспокоиться о получении разрешений."
"message": "Ни одна из версий вашего проекта не содержит внешнего контента, поэтому вам не нужно беспокоиться о получении разрешений."
},
"project.settings.permissions.empty-state.heading": {
"message": "Всё подтверждено!"
},
"project.settings.permissions.expand-all": {
"message": "Развернуть всё"
},
"project.settings.permissions.fail.description": {
"message": "Вам запрещено распространять часть добавленного вами внешнего контента. Для публикации на Modrinth удалите контент, нарушающий авторские права."
"message": "Возможно, у вас нет разрешения на распространение части стороннего контента в вашем проекте. Чтобы опубликовать проект на Modrinth, удалите этот контент или предоставьте доказательства того, что у вас есть разрешение на его использование."
},
"project.settings.permissions.fail.title": {
"message": "Некоторый контент не может быть включён"
},
"project.settings.permissions.info-banner.description": {
"message": "Если вы используете контент, который не размещен на Modrinth, вам необходимо сообщить нам, откуда он взят, и подтвердить наличие у вас разрешения на распространение файлов. Ознакомьтесь с <link>нашим руководством</link>, чтобы узнать, как это сделать правильно!"
},
"project.settings.permissions.info-banner.title": {
"message": "Узнайте, как работает атрибуция"
"message": "Узнайте о разрешениях на распространение"
},
"project.settings.permissions.learn-more": {
"message": "Подробнее"
},
"project.settings.permissions.no-results": {
"message": "Сторонние файлы не найдены."
},
"project.settings.permissions.not-allowed.description": {
"message": "Часть внешнего контента не может распространяться на Modrinth за нарушение правил контента и должна быть удалена."
},
"project.settings.permissions.search-placeholder": {
"message": "Поиск среди {count} {count, plural, one {внешнего проекта} other {внешних проектов}}..."
"message": "Поиск по {count, plural, one {# проекту} other {# проектам}}..."
},
"project.settings.permissions.sort.most-files": {
"message": "Количество файлов"
},
"project.settings.permissions.sort.recently-edited": {
"message": "Дата изменения"
},
"project.settings.permissions.sort.rejected": {
"message": "Отклонённые"
},
"project.settings.permissions.sort.status": {
"message": "Статус"
},
"project.settings.title": {
"message": "Настройки"
@@ -3929,6 +4025,48 @@
"settings.account.security.email.title": {
"message": "Почта"
},
"settings.account.security.passkey.add": {
"message": "Добавить ключ доступа"
},
"settings.account.security.passkey.add-modal.name.description": {
"message": "Выберите что-то запоминающееся, чтобы потом опознать этот ключ доступа."
},
"settings.account.security.passkey.add-modal.name.label": {
"message": "Название"
},
"settings.account.security.passkey.add-modal.name.placeholder": {
"message": "Мой ключ доступа"
},
"settings.account.security.passkey.description": {
"message": "Управляйте вашими кодами доступа, или добавьте новый."
},
"settings.account.security.passkey.modal.added": {
"message": "Добавлен {ago}"
},
"settings.account.security.passkey.modal.last-used": {
"message": "Активность {ago}"
},
"settings.account.security.passkey.modal.loading": {
"message": "Загрузка ключей доступа…"
},
"settings.account.security.passkey.modal.never-used": {
"message": "Не использовался"
},
"settings.account.security.passkey.modal.no-passkeys": {
"message": "Ключи доступа отсутствуют."
},
"settings.account.security.passkey.remove.description": {
"message": "Ключ доступа «{name}» будет удалён навсегда. Им нельзя будет воспользоваться для входа."
},
"settings.account.security.passkey.remove.title": {
"message": "Вы действительно хотите удалить этот ключ доступа?"
},
"settings.account.security.passkey.rename-modal.header": {
"message": "Переименовать ключ доступа"
},
"settings.account.security.passkey.title": {
"message": "Управление ключами доступа"
},
"settings.account.security.password.action.add": {
"message": "Добавить пароль"
},
@@ -4535,6 +4673,48 @@
"ui.newsletter-button.tooltip": {
"message": "Подписаться на рассылку от Modrinth"
},
"version.all-versions": {
"message": "Все версии"
},
"version.confirm-delete.description": {
"message": "Эта версия будет удалена навсегда. Отменить это действие нельзя."
},
"version.confirm-delete.proceed": {
"message": "Удалить версию"
},
"version.confirm-delete.title": {
"message": "Вы действительно хотите удалить эту версию?"
},
"version.dependency.view-project": {
"message": "Посмотреть проект"
},
"version.dependency.view-version": {
"message": "Посмотреть версию"
},
"version.download.download-dependency": {
"message": "Скачать зависимость"
},
"version.download.no-primary-file": {
"message": "Ошибка: основной файл не найден"
},
"version.download.optional-resource-pack": {
"message": "Необязательный набор ресурсов"
},
"version.download.required-resource-pack": {
"message": "Необходимый набор ресурсов"
},
"version.edit.button": {
"message": "Изменить"
},
"version.edit.details": {
"message": "Изменить сведения"
},
"version.edit.files": {
"message": "Изменить файлы"
},
"version.edit.metadata": {
"message": "Изменить метаданные"
},
"version.environment.none.description": {
"message": "Среда для этой версии не указана."
},
@@ -4546,5 +4726,56 @@
},
"version.environment.unknown.title": {
"message": "Неизвестная среда"
},
"version.package-as-mod.button": {
"message": "Собрать в мод"
},
"version.package-as-mod.description": {
"message": "Это создаст новую версию с поддержкой выбранного загрузчика. Вас перенаправит на новую версию и сможете изменить её по своему усмотрению."
},
"version.package-as-mod.header": {
"message": "Сборка набора данных в мод"
},
"version.package-as-mod.mod-loaders": {
"message": "Загрузчики"
},
"version.package-as-mod.mod-loaders.description": {
"message": "Загрузчики, для которых вы хотите собрать набор данных."
},
"version.package-as-mod.mod-loaders.placeholder": {
"message": "Выберите загрузчики..."
},
"version.package-as-mod.submit-button": {
"message": "Собрать набор данных"
},
"version.section.content.dev-info": {
"message": "Для разработчиков"
},
"version.section.content.dev-info.gradle-snippet": {
"message": "build.gradle:"
},
"version.section.content.dev-info.maven-coordinates": {
"message": "Координаты Maven:"
},
"version.section.content.dev-info.maven-description": {
"message": "Проекты на Modrinth автоматически доступны через репозиторий Maven для использования с инструментами сборки JVM, такими как <gradle-link>Gradle</gradle-link>. Чтобы узнать больше о Modrinth Maven API, <article-link>нажмите сюда</article-link>."
},
"version.section.content.dev-info.maven-note": {
"message": "Примечание: По возможности следует использовать Maven-репозиторий самого автора, так как он содержит информацию о транзитивных зависимостях, которой нет у Modrinth Maven API. Кроме того, вы можете столкнуться с дублированием зависимостей, если будете одновременно использовать Maven-репозитории Modrinth и сторонние репозитории для своих зависимостей, поскольку идентификатор группы будет отличаться при их получении через Modrinth Maven API."
},
"version.section.content.dev-info.version-id": {
"message": "ID версии:"
},
"version.supplementary-resources.copy-hash-sha1": {
"message": "Копировать SHA-1"
},
"version.supplementary-resources.copy-hash-sha512": {
"message": "Копировать SHA-512"
},
"version.unknown-embedded-content.description": {
"message": "Эта версия скрыта и не отображается. Предоставьте доказательства наличия разрешения на распространение некоторых файлов."
},
"version.unknown-embedded-content.title": {
"message": "Скрыто из-за неизвестного встроенного контента"
}
}
+55 -13
View File
@@ -8,6 +8,27 @@
"admin.billing.error.not-found": {
"message": "Korisnik nije pronađen"
},
"analytics.action.add": {
"message": "Dodaj"
},
"analytics.action.cancel": {
"message": "Otkaži"
},
"analytics.action.refresh": {
"message": "Osveži"
},
"analytics.action.reset": {
"message": "Resetiraj"
},
"analytics.breakdown.country": {
"message": "Država"
},
"analytics.chart.axis.playtime-hours": {
"message": "{hours} sati"
},
"analytics.chart.controls.active-count": {
"message": "{count} aktivnih"
},
"app-marketing.download.description": {
"message": "Naša desktop aplikacija je dostupna na svim platformama, izaberite željenu verziju."
},
@@ -60,7 +81,7 @@
"message": "Deli"
},
"app-marketing.hero.download-button": {
"message": "Preuzmite aplikaciju Modrint"
"message": "Preuzmite aplikaciju Modrinth"
},
"auth.authorize.action.authorize": {
"message": "Odobri"
@@ -113,18 +134,9 @@
"auth.reset-password.title.long": {
"message": "Resetujte svoju lozinku"
},
"auth.sign-in.2fa.description": {
"message": "Unesite kod za dvofaktorsku autentifikaciju da biste nastavili."
},
"auth.sign-in.2fa.label": {
"message": "Unesite kod za dvofaktorsku autentifikaciju"
},
"auth.sign-in.2fa.placeholder": {
"message": "Unesite kod..."
},
"auth.sign-in.sign-in-with": {
"message": "Prijavi se sa"
},
"auth.sign-in.title": {
"message": "Prijavi se"
},
@@ -137,9 +149,6 @@
"auth.sign-up.title": {
"message": "Registracija"
},
"auth.sign-up.title.sign-up-with": {
"message": "Prijavite se sa"
},
"auth.verify-email.action.account-settings": {
"message": "Podešavanja naloga"
},
@@ -1135,5 +1144,38 @@
},
"settings.sessions.unknown-platform": {
"message": "Nepoznata platforma"
},
"version.package-as-mod.submit-button": {
"message": "Spakiraj data pack"
},
"version.section.content.dev-info": {
"message": "Informacije sa programere"
},
"version.section.content.dev-info.gradle-snippet": {
"message": "sastavi sa gradle:"
},
"version.section.content.dev-info.maven-coordinates": {
"message": "Maven koordinate:"
},
"version.section.content.dev-info.maven-description": {
"message": "Projekti na Modrinthu su automatski dostupni putem Maven spremišta za korišćenje sa JVM alatima za izgradnju, kao što je <gradle-link>Gradle</gradle-link>. Da biste saznali više o Modrinth Maven API-ju, <article-link>kliknite ovde</article-link>."
},
"version.section.content.dev-info.maven-note": {
"message": "Napomena: Kada je dostupan, trebalo bi da koristite Maven repozitorijum autora umesto njega, jer će on imati informacije o tranzitivnim zavisnostima koje Modrinth Maven API nema. Takođe možete završiti sa dupliranim zavisnostima ako koristite kombinaciju Modrinth i ne-Modrinth Maven repozitorijuma za vaše zavisnosti, jer će identifikator grupe biti drugačiji kada se služi preko Modrinth Maven API-ja."
},
"version.section.content.dev-info.version-id": {
"message": "ID verzije:"
},
"version.supplementary-resources.copy-hash-sha1": {
"message": "Kopiraj SHA-1"
},
"version.supplementary-resources.copy-hash-sha512": {
"message": "Kopiraj SHA-512"
},
"version.unknown-embedded-content.description": {
"message": "Ova verzija je trenutno zadržana i nije javno objavljena. Molimo vas da dostavite dokaz da imate dozvolu za redistribuciju određenih uključenih datoteka."
},
"version.unknown-embedded-content.title": {
"message": "Zadržan sadržaj zbog nepoznatog ugrađenog sadržaja"
}
}
+91 -46
View File
@@ -194,9 +194,15 @@
"analytics.filter.search.countries": {
"message": "Sök länder..."
},
"analytics.filter.search.dependent-projects": {
"message": "Sök efter projekt..."
},
"analytics.filter.search.download-sources": {
"message": "Sök nedladdningskällor..."
},
"analytics.filter.search.members": {
"message": "Sök efter medlemmar..."
},
"analytics.filter.search.project-versions": {
"message": "Sök projektversioner..."
},
@@ -272,6 +278,9 @@
"analytics.project-event.project-unlisted": {
"message": "Projekt är avlistat"
},
"analytics.project-event.version-released": {
"message": "{version} släpptes"
},
"analytics.project-status.approved": {
"message": "Godkänd"
},
@@ -398,6 +407,9 @@
"analytics.title": {
"message": "Statistik"
},
"analytics.value.no-dependent": {
"message": "Ingen"
},
"analytics.value.none": {
"message": "Ingen"
},
@@ -623,6 +635,18 @@
"auth.authorize.redirect-url": {
"message": "Du kommer bli flyttad till <redirect-url>{url}</redirect-url>"
},
"auth.create-account.page-title": {
"message": "Skapa konto"
},
"auth.create-account.title": {
"message": "Skapa ett konto"
},
"auth.create-account.username.label": {
"message": "Användarnamn"
},
"auth.create-account.username.placeholder": {
"message": "Ange användarnamn"
},
"auth.reset-password.method-choice.action": {
"message": "Skicka återställningsmejl"
},
@@ -657,23 +681,53 @@
"message": "Återställ ditt lösenord"
},
"auth.sign-in.2fa.description": {
"message": "Ange din tvåfaktorskod för att fortsätta."
"message": "Ange 6-siffriga koden från din autentiseringsapp, eller en av dina reservkoder."
},
"auth.sign-in.2fa.label": {
"message": "Ange tvåfaktorskod"
"message": "Tvåfaktorsautentisering"
},
"auth.sign-in.2fa.placeholder": {
"message": "Ange kod..."
},
"auth.sign-in.continue-with-email": {
"message": "Fortsätt med e-post"
},
"auth.sign-in.continue-with-passkey": {
"message": "Fortsätt med passkey"
},
"auth.sign-in.create-account": {
"message": "Registrera"
},
"auth.sign-in.forgot-password": {
"message": "Glömt lösenord"
},
"auth.sign-in.last-sign-in": {
"message": "Användes senast"
},
"auth.sign-in.no-account": {
"message": "Har du inget konto?"
},
"auth.sign-in.sign-in-with": {
"message": "Logga in med"
"message": "Logga in på Modrinth"
},
"auth.sign-in.title": {
"message": "Logga in"
},
"auth.sign-up.age-requirement.warning-title": {
"message": "Ålderskrav"
},
"auth.sign-up.continue-with-email": {
"message": "Fortsätt med e-post"
},
"auth.sign-up.legal-dislaimer": {
"message": "Genom att skapa ett konto godkänner du Modrinths <terms-link>villkor</terms-link> och <privacy-policy-link>sekretesspolicy</privacy-policy-link>."
},
"auth.sign-up.show-fewer-options": {
"message": "Visa färre inloggningsmetoder"
},
"auth.sign-up.show-other-options": {
"message": "Visa andra inloggningsmetoder"
},
"auth.sign-up.sign-in-option.title": {
"message": "Har du redan ett konto?"
},
@@ -681,11 +735,14 @@
"message": "Registrera dig"
},
"auth.sign-up.title.sign-up-with": {
"message": "Registrera dig med"
"message": "Skapa ett konto"
},
"auth.verify-email.action.account-settings": {
"message": "Kontoinställningar"
},
"auth.verify-email.action.discover-mods": {
"message": "Upptäck moddar"
},
"auth.verify-email.already-verified.description": {
"message": "Din e-post är redan verifierad!"
},
@@ -704,6 +761,15 @@
"auth.verify-email.failed-verification.title": {
"message": "Verifiering av e-post misslyckades"
},
"auth.verify-email.notification.email-sent.description": {
"message": "Ett e-postmeddelande med en verifieringslänk har skickats till {email}."
},
"auth.verify-email.notification.email-sent.title": {
"message": "E-postmeddelande skickat"
},
"auth.verify-email.notification.error-occurred.title": {
"message": "Ett fel inträffade"
},
"auth.verify-email.post-verification.description": {
"message": "Din e-postadress har verifierats!"
},
@@ -827,6 +893,18 @@
"conversation-thread.action.withhold": {
"message": "Tillhandahåll"
},
"conversation-thread.action.withhold-with-reply": {
"message": "Tillbakahåll med svar"
},
"conversation-thread.closed-thread.description": {
"message": "Den här tråden är stängd och nya meddelanden kan inte skickas."
},
"conversation-thread.error.closing-report": {
"message": "Fel vid stängning av rapport"
},
"conversation-thread.error.reopening-report": {
"message": "Fel vid öppning av rapport"
},
"conversation-thread.error.sending-message": {
"message": "Kunde inte skicka meddelande"
},
@@ -842,9 +920,15 @@
"conversation-thread.reply-modal.confirmation.label": {
"message": "Jag förstår att moderatorerna inte aktivt övervakar tråden."
},
"conversation-thread.reply-modal.description": {
"message": "Ditt projekt är redan godkänt. Moderatorteamet övervakar därför inte aktivt den här tråden. De kan dock fortfarande se ditt inlägg om det uppstår något problem med ditt projekt."
},
"conversation-thread.reply-modal.header": {
"message": "Svara tråden"
},
"conversation-thread.reply-modal.help-center-note": {
"message": "Ifall du behöver komma i kontakt med moderatorteamet, vänligen använd <help-center-link>Modrinth hjälpcenter</help-center-link> och klicka på den blåa bubblan nere till höger för att kontakta support."
},
"conversation-thread.resubmit-modal.confirmation.description": {
"message": "Bekräfta att jag tagit itu med meddelandena från moderatorerna"
},
@@ -1334,6 +1418,9 @@
"dashboard.discord-roles.role.big-creator": {
"message": "1 mn nedladdningar"
},
"dashboard.discord-roles.role.creator": {
"message": "Kreatör"
},
"dashboard.discord-roles.role.pride": {
"message": "Pride 2026"
},
@@ -1427,24 +1514,6 @@
"dashboard.projects.project.icon-alt": {
"message": "Ikon för {title}"
},
"dashboard.projects.sort.ascending": {
"message": "Stigande"
},
"dashboard.projects.sort.descending": {
"message": "Fallande"
},
"dashboard.projects.sort.option.name": {
"message": "Namn"
},
"dashboard.projects.sort.option.status": {
"message": "Status"
},
"dashboard.projects.sort.option.type": {
"message": "Typ"
},
"dashboard.projects.table.icon": {
"message": "Ikon"
},
"dashboard.projects.table.id": {
"message": "ID"
},
@@ -2735,45 +2804,21 @@
"project.details.licensed": {
"message": "Licensierad"
},
"project.download.game-version": {
"message": "Spelversion: {version}"
},
"project.download.game-version-error": {
"message": "Fel: inga spelversioner hittades"
},
"project.download.game-version-tooltip": {
"message": "{title} är bara tillgängligt för {version}"
},
"project.download.game-version-unsupported-tooltip": {
"message": "{title} stöttar inte {gameVersion} för {platform}"
},
"project.download.install-with-app": {
"message": "Installera med Modrinth App"
},
"project.download.no-app": {
"message": "Har du inte Modrinth appen?"
},
"project.download.no-versions-available": {
"message": "Inga versioner finns tillgängliga för {gameVersion} och {platform}."
},
"project.download.platform": {
"message": "Plattform: {platform}"
},
"project.download.platform-error": {
"message": "Fel: ingen plattform hittades"
},
"project.download.platform-tooltip": {
"message": "{title} är bara tillgängligt för {platform}"
},
"project.download.platform-unsupported-tooltip": {
"message": "{title} stöttar inte {platform} för {gameVersion}"
},
"project.download.search-game-versions": {
"message": "Sök spelversioner..."
},
"project.download.search-game-versions-label": {
"message": "Sök spelversioner..."
},
"project.download.select-game-version": {
"message": "Välj spelversion"
},

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