mirror of
https://github.com/modrinth/code.git
synced 2026-07-31 21:26:40 +00:00
Compare commits
41
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dcb2795934 | ||
|
|
0e59cc7dbf | ||
|
|
d3f9eaa152 | ||
|
|
51407de38c | ||
|
|
ba3601b36f | ||
|
|
e49979e5b2 | ||
|
|
ab907a21b6 | ||
|
|
3e096da965 | ||
|
|
54de5a52ee | ||
|
|
c43020badd | ||
|
|
de2eb1f5c1 | ||
|
|
b87ee2253f | ||
|
|
20bbe896ca | ||
|
|
387ab8e4fd | ||
|
|
21a174f8ef | ||
|
|
907db9e64a | ||
|
|
944f99a14e | ||
|
|
a79736dba9 | ||
|
|
6f0181d52f | ||
|
|
70c544b048 | ||
|
|
5a80df3cd4 | ||
|
|
1e85ec8649 | ||
|
|
1dd613e459 | ||
|
|
d632b7bdbc | ||
|
|
eb8141134a | ||
|
|
cc0d3bf42c | ||
|
|
5e155d69b6 | ||
|
|
707722ded6 | ||
|
|
dfc2ed3783 | ||
|
|
fbe70c6938 | ||
|
|
cd56b98975 | ||
|
|
b06b14e0fb | ||
|
|
a6d9bb7b3e | ||
|
|
e58af98f21 | ||
|
|
2e0d797bb0 | ||
|
|
508b96c27f | ||
|
|
0512e0b62b | ||
|
|
5c697f675c | ||
|
|
95f97a44ec | ||
|
|
054f1b42fd | ||
|
|
b4d681e713 |
@@ -27,7 +27,7 @@ jobs:
|
||||
BUMP_TYPE: minor
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -47,7 +47,7 @@ jobs:
|
||||
|
||||
- name: Setup Node
|
||||
if: steps.changes.outputs.changed == 'true'
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
registry-url: https://registry.npmjs.org
|
||||
@@ -63,7 +63,7 @@ jobs:
|
||||
|
||||
- name: Restore pnpm cache
|
||||
if: steps.changes.outputs.changed == 'true'
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
uses: actions/cache/restore@55cc8345863c7cc4c66a329aec7e433d2d1c52a9 # v6.1.0
|
||||
with:
|
||||
path: ${{ steps.pnpm-store.outputs.store-path }}
|
||||
key: pnpm-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
|
||||
@@ -14,7 +14,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Cancel Previous Runs
|
||||
uses: styfle/cancel-workflow-action@85880fa0301c86cca9da44039ee3bb12d3bedbfa # 0.12.1
|
||||
uses: styfle/cancel-workflow-action@d07a454dad7609a92316b57b23c9ccfd4f59af66 # 0.13.1
|
||||
with:
|
||||
workflow_id: all
|
||||
access_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
@@ -17,7 +17,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Post or update changelog comment
|
||||
uses: actions/github-script@d746ffe35508b1917358783b479e04febd2b8f71 # v9.0.0
|
||||
uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v9.0.0
|
||||
with:
|
||||
github-token: ${{ secrets.CROWDIN_GH_TOKEN }}
|
||||
script: |
|
||||
|
||||
@@ -12,14 +12,14 @@ jobs:
|
||||
typos:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: crate-ci/typos@6ac2ebd1b93eade61faf7e12688ad87a073fea59 # v1.46.0
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- uses: crate-ci/typos@bee27e3a4fd1ea2111cf90ab89cd076c870fce14 # v1.48.0
|
||||
|
||||
# see <https://github.com/influxdata/datafusion-udf-wasm/pull/275>
|
||||
tombi:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- uses: taiki-e/install-action@fd2f5e3d644b484055ebf4268f474c565f148f25 # v2.81.9
|
||||
with:
|
||||
tool: tombi
|
||||
|
||||
@@ -6,14 +6,15 @@ on:
|
||||
|
||||
env:
|
||||
CARGO_TERM_COLOR: always
|
||||
CARGO_INCREMENTAL: 0
|
||||
SQLX_OFFLINE: true
|
||||
|
||||
jobs:
|
||||
shear:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
- uses: dtolnay/rust-toolchain@29eef336d9b2848a0b548edc03f92a220660cdb8 # stable
|
||||
- uses: cargo-bins/cargo-binstall@dc19f1e48450eefe5a29b8da6c6b00a87d730b37 # v1.18.1
|
||||
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
- uses: dtolnay/rust-toolchain@4cda84d5c5c54efe2404f9d843567869ab1699d4 # stable
|
||||
- uses: cargo-bins/cargo-binstall@ead08b90bd7b2e6d81963fb9cf0b7239f66d5db4 # v1.21.0
|
||||
- run: cargo binstall --no-confirm cargo-shear
|
||||
- run: cargo shear
|
||||
|
||||
@@ -35,7 +35,7 @@ jobs:
|
||||
if: ${{ always() }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Check if workflow runs on an internal branch
|
||||
id: check-internal
|
||||
@@ -72,19 +72,15 @@ jobs:
|
||||
fi
|
||||
|
||||
docker:
|
||||
runs-on: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-latest' }}
|
||||
env:
|
||||
SCCACHE_DIR: ${{ needs.skip-if-clean.outputs.internal == 'true' && '/mnt/sccache' || '' }}
|
||||
SCCACHE_CACHE_SIZE: ${{ needs.skip-if-clean.outputs.internal == 'true' && '10G' || '' }}
|
||||
RUSTC_WRAPPER: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'sccache' || '' }}
|
||||
runs-on: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'namespace-profile-medium-amd64' || 'ubuntu-latest' }}
|
||||
needs: [skip-if-clean]
|
||||
if: ${{ needs.skip-if-clean.outputs.skip != 'true' }}
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Setup Rust toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
|
||||
uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17.0
|
||||
with:
|
||||
rustflags: ''
|
||||
cache: false
|
||||
@@ -92,30 +88,6 @@ jobs:
|
||||
- name: Setup mold
|
||||
uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1 / Mold 2.41.0
|
||||
|
||||
- name: Cache Cargo registry and index
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
~/.cargo/bin
|
||||
key: ${{ runner.os }}-${{ runner.arch }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- name: Ensure sccache directory exists
|
||||
if: needs.skip-if-clean.outputs.internal == 'true'
|
||||
run: sudo mkdir -p /mnt/sccache && sudo chown $(id -u):$(id -g) /mnt/sccache
|
||||
|
||||
- name: Mount sccache disk cache
|
||||
if: needs.skip-if-clean.outputs.internal == 'true'
|
||||
uses: useblacksmith/stickydisk@13af8883542ca949a717e70fef89d15edbb29d88 # v1.2.0
|
||||
with:
|
||||
key: ${{ github.repository }}-daedalus-sccache
|
||||
path: /mnt/sccache
|
||||
|
||||
- name: Setup sccache
|
||||
if: needs.skip-if-clean.outputs.internal == 'true'
|
||||
uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
|
||||
|
||||
- name: Build daedalus_client
|
||||
run: cargo build --release --package daedalus_client
|
||||
|
||||
@@ -125,11 +97,11 @@ jobs:
|
||||
cp target/release/daedalus_client apps/daedalus_client/docker-stage/daedalus_client
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
|
||||
|
||||
- name: Generate Docker image metadata
|
||||
id: docker-meta
|
||||
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
|
||||
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
|
||||
env:
|
||||
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
|
||||
with:
|
||||
@@ -144,14 +116,14 @@ jobs:
|
||||
org.opencontainers.image.licenses=MIT
|
||||
|
||||
- name: Login to GitHub Packages
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
||||
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
||||
with:
|
||||
context: ./apps/daedalus_client/docker-stage
|
||||
file: ./apps/daedalus_client/Dockerfile
|
||||
|
||||
@@ -12,10 +12,10 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Log in to GitHub Container Registry
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
|
||||
@@ -39,14 +39,14 @@ concurrency:
|
||||
|
||||
jobs:
|
||||
deploy:
|
||||
runs-on: blacksmith-2vcpu-ubuntu-2404
|
||||
runs-on: namespace-profile-modrinth-frontend
|
||||
permissions:
|
||||
contents: read
|
||||
deployments: write
|
||||
pull-requests: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
@@ -90,24 +90,23 @@ jobs:
|
||||
fi
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Get pnpm store path
|
||||
id: pnpm-store
|
||||
run: echo "store-path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Restore pnpm cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
- name: Set up caches
|
||||
uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1
|
||||
with:
|
||||
path: ${{ steps.pnpm-store.outputs.store-path }}
|
||||
key: pnpm-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
pnpm-cache-
|
||||
cache: |
|
||||
rust
|
||||
pnpm
|
||||
apt
|
||||
|
||||
- name: Set up Turborepo caching
|
||||
uses: namespace-actions/setup-turbocache@f96bd6befa13ae74b2858a5be49573640d4636f5 # v0.0.2
|
||||
|
||||
- name: Inject build variables
|
||||
working-directory: ./apps/frontend
|
||||
@@ -136,7 +135,7 @@ jobs:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
|
||||
- name: Create Sentry release and upload sourcemaps
|
||||
uses: getsentry/action-release@5657c9e888b4e2cc85f4d29143ea4131fde4a73a # v3.6.0
|
||||
uses: getsentry/action-release@ff07929a6537bac57790c3451cf4d364aca38528 # v3.7.0
|
||||
env:
|
||||
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
|
||||
SENTRY_ORG: modrinth
|
||||
@@ -146,50 +145,53 @@ jobs:
|
||||
sourcemaps: ./apps/frontend/.output/server
|
||||
url_prefix: '~/'
|
||||
|
||||
- name: Deploy Cloudflare Worker
|
||||
id: wrangler
|
||||
uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3.15.0
|
||||
- name: Install Wrangler CLI
|
||||
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
environment: ${{ steps.meta.outputs.env != 'production' && steps.meta.outputs.env || '' }}
|
||||
workingDirectory: ./apps/frontend
|
||||
packageManager: pnpm
|
||||
wranglerVersion: '4.54.0'
|
||||
command: ${{ steps.meta.outputs.cmd }}
|
||||
wranglerVersion: '4.112.0'
|
||||
command: --version
|
||||
|
||||
- name: Deploy staging Cloudflare Worker preview
|
||||
if: ${{ inputs.preview }}
|
||||
uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3.15.0
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
workingDirectory: ./apps/frontend
|
||||
packageManager: pnpm
|
||||
wranglerVersion: '4.54.0'
|
||||
command: ${{ steps.meta.outputs.staging_cmd }}
|
||||
- parallel:
|
||||
- name: Deploy Cloudflare Worker
|
||||
id: wrangler
|
||||
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
environment: ${{ steps.meta.outputs.env != 'production' && steps.meta.outputs.env || '' }}
|
||||
workingDirectory: ./apps/frontend
|
||||
command: ${{ steps.meta.outputs.cmd }}
|
||||
|
||||
- name: Deploy persistent Cloudflare Worker preview
|
||||
if: ${{ inputs.preview && inputs.branch_alias != '' }}
|
||||
uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3.15.0
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
workingDirectory: ./apps/frontend
|
||||
packageManager: pnpm
|
||||
wranglerVersion: '4.54.0'
|
||||
command: versions upload --preview-alias ${{ inputs.branch_alias }} --var PREVIEW:true --var CF_PAGES_URL:${{ steps.meta.outputs.branch_alias_url }}
|
||||
- name: Deploy staging Cloudflare Worker preview
|
||||
if: ${{ inputs.preview }}
|
||||
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
workingDirectory: ./apps/frontend
|
||||
command: ${{ steps.meta.outputs.staging_cmd }}
|
||||
|
||||
- name: Deploy persistent staging Cloudflare Worker preview
|
||||
if: ${{ inputs.preview && inputs.branch_alias != '' }}
|
||||
uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3.15.0
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
workingDirectory: ./apps/frontend
|
||||
packageManager: pnpm
|
||||
wranglerVersion: '4.54.0'
|
||||
command: ${{ steps.meta.outputs.staging_branch_alias_cmd }}
|
||||
- name: Deploy persistent Cloudflare Worker preview
|
||||
if: ${{ inputs.preview && inputs.branch_alias != '' }}
|
||||
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
workingDirectory: ./apps/frontend
|
||||
command: versions upload --preview-alias ${{ inputs.branch_alias }} --var PREVIEW:true --var CF_PAGES_URL:${{ steps.meta.outputs.branch_alias_url }}
|
||||
|
||||
- name: Deploy persistent staging Cloudflare Worker preview
|
||||
if: ${{ inputs.preview && inputs.branch_alias != '' }}
|
||||
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
workingDirectory: ./apps/frontend
|
||||
command: ${{ steps.meta.outputs.staging_branch_alias_cmd }}
|
||||
|
||||
- name: Purge cache
|
||||
if: github.ref == 'refs/heads/prod'
|
||||
@@ -206,16 +208,17 @@ jobs:
|
||||
echo "${{ steps.meta.outputs.url }}" > deployment-url-production.txt
|
||||
echo "${{ steps.meta.outputs.staging_url }}" > deployment-url-staging.txt
|
||||
|
||||
- name: Upload production deployment URL
|
||||
if: ${{ inputs.preview }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: deployment-url-production
|
||||
path: deployment-url-production.txt
|
||||
- parallel:
|
||||
- name: Upload production deployment URL
|
||||
if: ${{ inputs.preview }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: deployment-url-production
|
||||
path: deployment-url-production.txt
|
||||
|
||||
- name: Upload staging deployment URL
|
||||
if: ${{ inputs.preview }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: deployment-url-staging
|
||||
path: deployment-url-staging.txt
|
||||
- name: Upload staging deployment URL
|
||||
if: ${{ inputs.preview }}
|
||||
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
|
||||
with:
|
||||
name: deployment-url-staging
|
||||
path: deployment-url-staging.txt
|
||||
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
deploy-storybook:
|
||||
if: github.repository_owner == 'modrinth' && github.event.pull_request.head.repo.full_name == github.repository
|
||||
needs: metadata
|
||||
runs-on: blacksmith-2vcpu-ubuntu-2404
|
||||
runs-on: namespace-profile-modrinth-frontend
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}-storybook
|
||||
cancel-in-progress: true
|
||||
@@ -48,27 +48,21 @@ jobs:
|
||||
deployments: write
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Get pnpm store path
|
||||
id: pnpm-store
|
||||
run: echo "store-path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Restore pnpm cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
- name: Set up caches
|
||||
uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1
|
||||
with:
|
||||
path: ${{ steps.pnpm-store.outputs.store-path }}
|
||||
key: pnpm-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
pnpm-cache-
|
||||
cache: |
|
||||
pnpm
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: ./packages/ui
|
||||
@@ -86,27 +80,34 @@ jobs:
|
||||
HEAD_SHA: ${{ github.event.pull_request.head.sha }}
|
||||
run: echo "sha_short=${HEAD_SHA::8}" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Deploy Storybook preview
|
||||
uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3.15.0
|
||||
- name: Install Wrangler CLI
|
||||
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
workingDirectory: ./packages/ui
|
||||
packageManager: pnpm
|
||||
wranglerVersion: '4.54.0'
|
||||
command: versions upload --preview-alias git-${{ steps.meta.outputs.sha_short }}
|
||||
wranglerVersion: '4.112.0'
|
||||
command: --version
|
||||
|
||||
- name: Deploy persistent Storybook preview
|
||||
uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3.15.0
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=6144
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
workingDirectory: ./packages/ui
|
||||
packageManager: pnpm
|
||||
wranglerVersion: '4.54.0'
|
||||
command: versions upload --preview-alias ${{ needs.metadata.outputs.branch-alias }}
|
||||
- parallel:
|
||||
- name: Deploy Storybook preview
|
||||
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
workingDirectory: ./packages/ui
|
||||
command: versions upload --preview-alias git-${{ steps.meta.outputs.sha_short }}
|
||||
|
||||
- name: Deploy persistent Storybook preview
|
||||
uses: cloudflare/wrangler-action@ebbaa1584979971c8614a24965b4405ff95890e0 # v4.0.0
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=6144
|
||||
with:
|
||||
apiToken: ${{ secrets.CF_API_TOKEN }}
|
||||
accountId: ${{ secrets.CF_ACCOUNT_ID }}
|
||||
workingDirectory: ./packages/ui
|
||||
command: versions upload --preview-alias ${{ needs.metadata.outputs.branch-alias }}
|
||||
|
||||
comment:
|
||||
if: |
|
||||
|
||||
@@ -51,13 +51,13 @@ jobs:
|
||||
CROWDIN_GH_TOKEN_DEFINED: ${{ secrets.CROWDIN_GH_TOKEN != '' }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
token: ${{ secrets.CROWDIN_GH_TOKEN }}
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
|
||||
@@ -90,7 +90,7 @@ jobs:
|
||||
echo "safe_branch_name=$SAFE_BRANCH_NAME" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Download translations from Crowdin
|
||||
uses: crowdin/github-action@8868a33591d21088edfc398968173a3b98d51706 # v2.16.2
|
||||
uses: crowdin/github-action@c7af9bc98b01694653031fef2a0dc6c7888ce9bc # v2.17.0
|
||||
with:
|
||||
upload_sources: false
|
||||
upload_translations: false
|
||||
|
||||
@@ -56,13 +56,13 @@ jobs:
|
||||
CROWDIN_PERSONAL_TOKEN_DEFINED: ${{ secrets.CROWDIN_PERSONAL_TOKEN != '' }}
|
||||
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
ref: ${{ github.ref }}
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
|
||||
@@ -83,7 +83,7 @@ jobs:
|
||||
echo "safe_branch_name=$SAFE_BRANCH_NAME" >> "$GITHUB_OUTPUT"
|
||||
|
||||
- name: Upload translations to Crowdin
|
||||
uses: crowdin/github-action@8868a33591d21088edfc398968173a3b98d51706 # v2.16.2
|
||||
uses: crowdin/github-action@c7af9bc98b01694653031fef2a0dc6c7888ce9bc # v2.17.0
|
||||
with:
|
||||
upload_sources: true
|
||||
upload_translations: false
|
||||
|
||||
@@ -33,7 +33,7 @@ jobs:
|
||||
if: ${{ always() }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Check if workflow runs on an internal branch
|
||||
id: check-internal
|
||||
@@ -70,22 +70,21 @@ jobs:
|
||||
fi
|
||||
|
||||
docker:
|
||||
runs-on: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-latest' }}
|
||||
runs-on: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'namespace-profile-modrinth-labrinth' || 'ubuntu-latest' }}
|
||||
needs: [skip-if-clean]
|
||||
if: ${{ needs.skip-if-clean.outputs.skip != 'true' }}
|
||||
env:
|
||||
SQLX_OFFLINE: 'true'
|
||||
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_CACHE_SIZE: ${{ needs.skip-if-clean.outputs.internal == 'true' && '20G' || '' }}
|
||||
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
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Setup Rust toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
|
||||
uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17.0
|
||||
with:
|
||||
rustflags: ''
|
||||
cache: false
|
||||
@@ -93,36 +92,23 @@ jobs:
|
||||
- name: Setup mold
|
||||
uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1 / Mold 2.41.0
|
||||
|
||||
- name: Setup sccache
|
||||
uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
|
||||
|
||||
- name: Set up caches
|
||||
if: needs.skip-if-clean.outputs.internal == 'true'
|
||||
uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1
|
||||
with:
|
||||
cache: |
|
||||
rust
|
||||
apt
|
||||
|
||||
- name: Configure sccache
|
||||
if: needs.skip-if-clean.outputs.internal == 'true'
|
||||
run: nsc cache sccache setup --cache_name default >> "$GITHUB_ENV"
|
||||
|
||||
- name: Install build dependencies
|
||||
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
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
~/.cargo/bin
|
||||
key: ${{ runner.os }}-${{ runner.arch }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- name: Ensure sccache directory exists
|
||||
if: needs.skip-if-clean.outputs.internal == 'true'
|
||||
run: sudo mkdir -p /mnt/sccache && sudo chown $(id -u):$(id -g) /mnt/sccache
|
||||
|
||||
- name: Mount sccache disk cache
|
||||
if: needs.skip-if-clean.outputs.internal == 'true'
|
||||
uses: useblacksmith/stickydisk@13af8883542ca949a717e70fef89d15edbb29d88 # v1.2.0
|
||||
with:
|
||||
key: ${{ github.repository }}-labrinth-sccache
|
||||
path: /mnt/sccache
|
||||
|
||||
- name: Setup sccache
|
||||
if: needs.skip-if-clean.outputs.internal == 'true'
|
||||
uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
|
||||
|
||||
- name: Build labrinth
|
||||
run: cargo build --profile release-labrinth --package labrinth
|
||||
@@ -135,11 +121,11 @@ jobs:
|
||||
cp -r apps/labrinth/assets apps/labrinth/docker-stage/assets
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
|
||||
uses: docker/setup-buildx-action@bb05f3f5519dd87d3ba754cc423b652a5edd6d2c # v4.2.0
|
||||
|
||||
- name: Generate Docker image metadata
|
||||
id: docker-meta
|
||||
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
|
||||
uses: docker/metadata-action@dc802804100637a589fabce1cb79ff13a1411302 # v6.2.0
|
||||
env:
|
||||
# GitHub Packages requires annotations metadata in at least the index descriptor to show them
|
||||
# up properly in its UI it seems, but it's not clear about it, because the docs refer to the
|
||||
@@ -158,14 +144,14 @@ jobs:
|
||||
org.opencontainers.image.licenses=AGPL-3.0-only
|
||||
|
||||
- name: Login to GitHub Packages
|
||||
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
|
||||
uses: docker/login-action@abd2ef45e78c5afb21d64d4ca52ee8550d9572c7 # v4.5.1
|
||||
with:
|
||||
registry: ghcr.io
|
||||
username: ${{ github.actor }}
|
||||
password: ${{ secrets.GITHUB_TOKEN }}
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
|
||||
uses: docker/build-push-action@53b7df96c91f9c12dcc8a07bcb9ccacbed38856a # v7.3.0
|
||||
with:
|
||||
context: ./apps/labrinth/docker-stage
|
||||
file: ./apps/labrinth/Dockerfile
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
name: Prepare pnpm cache
|
||||
|
||||
on:
|
||||
push:
|
||||
paths:
|
||||
- .github/workflows/prepare-pnpm-cache.yml
|
||||
- package.json
|
||||
- pnpm-lock.yaml
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.workflow }}-${{ github.ref }}
|
||||
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/prod' }}
|
||||
|
||||
jobs:
|
||||
prepare:
|
||||
if: github.repository_owner == 'modrinth'
|
||||
runs-on: blacksmith-2vcpu-ubuntu-2404
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Get pnpm store path
|
||||
id: pnpm-store
|
||||
run: echo "store-path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Cache pnpm
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
with:
|
||||
path: ${{ steps.pnpm-store.outputs.store-path }}
|
||||
key: pnpm-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm recursive install --frozen-lockfile
|
||||
@@ -44,42 +44,34 @@ jobs:
|
||||
name: Build
|
||||
env:
|
||||
VITE_STRIPE_PUBLISHABLE_KEY: pk_live_51JbFxJJygY5LJFfKLVVldb10HlLt24p421OWRsTOWc5sXYFOnFUXWieSc6HD3PHo25ktx8db1WcHr36XGFvZFVUz00V9ixrCs5
|
||||
# SCCACHE_DIR: '/mnt/sccache'
|
||||
# SCCACHE_CACHE_SIZE: '10G'
|
||||
# SCCACHE_MULTILEVEL_CHAIN: 'disk,s3'
|
||||
SCCACHE_S3_KEY_PREFIX: '${{ 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: 'sccache'
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
platform: [
|
||||
blacksmith-6vcpu-macos-26,
|
||||
blacksmith-8vcpu-windows-2025, # At time of writing, Windows 4 vCPU VMs don't seem to actually exist
|
||||
blacksmith-4vcpu-ubuntu-2404,
|
||||
platform:
|
||||
[
|
||||
namespace-profile-medium-amd64-macos,
|
||||
namespace-profile-medium-amd64-windows,
|
||||
namespace-profile-medium-amd64,
|
||||
]
|
||||
include:
|
||||
- platform: blacksmith-6vcpu-macos-26
|
||||
- platform: namespace-profile-medium-amd64-macos
|
||||
artifact-target-name: universal-apple-darwin
|
||||
- platform: blacksmith-8vcpu-windows-2025
|
||||
- platform: namespace-profile-medium-amd64-windows
|
||||
artifact-target-name: x86_64-pc-windows-msvc
|
||||
- platform: blacksmith-4vcpu-ubuntu-2404
|
||||
- platform: namespace-profile-medium-amd64
|
||||
artifact-target-name: x86_64-unknown-linux-gnu
|
||||
|
||||
runs-on: ${{ matrix.platform }}
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
fetch-depth: 0
|
||||
|
||||
- name: Setup Rust toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
|
||||
uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17.0
|
||||
with:
|
||||
rustflags: ''
|
||||
target: ${{ contains(matrix.platform, 'macos') && 'x86_64-apple-darwin' || '' }}
|
||||
@@ -91,14 +83,25 @@ jobs:
|
||||
- name: Setup sccache
|
||||
uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
- name: Set up caches
|
||||
if: contains(matrix.platform, 'ubuntu') || contains(matrix.platform, 'macos')
|
||||
uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
cache: 'pnpm'
|
||||
cache: |
|
||||
rust
|
||||
pnpm
|
||||
|
||||
- name: Configure sccache
|
||||
if: contains(matrix.platform, 'ubuntu') || contains(matrix.platform, 'macos')
|
||||
run: nsc cache sccache setup --cache_name default >> "$GITHUB_ENV"
|
||||
|
||||
- name: Generate tauri-dev.conf.json
|
||||
shell: bash
|
||||
@@ -117,10 +120,15 @@ jobs:
|
||||
|
||||
- name: Install Linux build dependencies
|
||||
if: contains(matrix.platform, 'ubuntu')
|
||||
uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # v1.6.0
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev
|
||||
|
||||
- name: Setup Java
|
||||
uses: actions/setup-java@03ad4de0992f5dab5e18fcb136590ce7c4a0ac95 # v5.6.0
|
||||
with:
|
||||
packages: libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev
|
||||
version: v1 # cache key
|
||||
distribution: temurin
|
||||
java-version: 17
|
||||
|
||||
- name: Setup Dasel
|
||||
uses: jaxxstorm/action-install-gh-release@25e24d2d23ae098373794ef1d6faecb48ee52da8 # v3.0.0
|
||||
@@ -147,9 +155,6 @@ jobs:
|
||||
|
||||
cp "packages/app-lib/.env.${BUILD_ENVIRONMENT}" packages/app-lib/.env
|
||||
|
||||
- name: Setup Turbo cache
|
||||
uses: rharkor/caching-for-turbo@56219402aacc0d06b650d898c222996dbc1191ec # v2.3.14
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
github.event.workflow_run.conclusion == 'success' &&
|
||||
github.event.workflow_run.event == 'push' &&
|
||||
startsWith(github.event.workflow_run.head_branch, 'v')
|
||||
runs-on: blacksmith-4vcpu-ubuntu-2404
|
||||
runs-on: namespace-profile-medium-amd64
|
||||
env:
|
||||
VERSION_TAG: ${{ github.event.workflow_run.head_branch }}
|
||||
LINUX_X64_BUNDLE_ARTIFACT_NAME: App bundle (x86_64-unknown-linux-gnu)
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Verify ref is a tag
|
||||
env:
|
||||
|
||||
@@ -22,7 +22,7 @@ jobs:
|
||||
if: ${{ always() }}
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
|
||||
- name: Check if workflow runs on an internal branch
|
||||
id: check-internal
|
||||
@@ -62,7 +62,7 @@ jobs:
|
||||
|
||||
build:
|
||||
name: Lint and Test
|
||||
runs-on: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-latest' }}
|
||||
runs-on: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'namespace-profile-large-amd64' || 'ubuntu-latest' }}
|
||||
needs: [skip-if-clean]
|
||||
if: ${{ needs.skip-if-clean.outputs.skip != 'true' }}
|
||||
|
||||
@@ -76,47 +76,47 @@ jobs:
|
||||
# since we don't want warnings to become errors
|
||||
# while developing)
|
||||
RUSTFLAGS: -Dwarnings
|
||||
# sccache config (only populated for internal branches; secrets aren't
|
||||
# available to forked PRs, and blacksmith stickydisk requires a
|
||||
# blacksmith runner)
|
||||
SCCACHE_DIR: ${{ needs.skip-if-clean.outputs.internal == 'true' && '/mnt/sccache' || '' }}
|
||||
SCCACHE_CACHE_SIZE: ${{ needs.skip-if-clean.outputs.internal == 'true' && '10G' || '' }}
|
||||
RUSTC_WRAPPER: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'sccache' || '' }}
|
||||
# Redis config for tests
|
||||
REDIS_TOPOLOGY: cluster
|
||||
REDIS_CONNECTION_TYPE: multiplexed
|
||||
REDIS_URL: redis://127.0.0.1:7000,redis://127.0.0.1:7001,redis://127.0.0.1:7002,redis://127.0.0.1:7003,redis://127.0.0.1:7004,redis://127.0.0.1:7005
|
||||
# Avoid stack overflows in tests
|
||||
RUST_MIN_STACK: 33554432
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
|
||||
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
||||
with:
|
||||
fetch-depth: 2
|
||||
|
||||
- name: Install build dependencies
|
||||
uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # v1.6.0
|
||||
with:
|
||||
packages: cmake libcurl4-openssl-dev libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev
|
||||
version: v2 # cache key
|
||||
|
||||
- name: Setup Node
|
||||
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
|
||||
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
||||
with:
|
||||
node-version-file: .nvmrc
|
||||
|
||||
- name: Enable Corepack
|
||||
run: corepack enable
|
||||
|
||||
- name: Get pnpm store path
|
||||
id: pnpm-store
|
||||
run: echo "store-path=$(pnpm store path --silent)" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Restore pnpm cache
|
||||
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
|
||||
- name: Set up caches
|
||||
if: needs.skip-if-clean.outputs.internal == 'true'
|
||||
uses: namespacelabs/nscloud-cache-action@c5f8dab7560444c4bf8dbc64f1b203431873c547 # v1.6.1
|
||||
with:
|
||||
path: ${{ steps.pnpm-store.outputs.store-path }}
|
||||
key: pnpm-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
pnpm-cache-
|
||||
cache: |
|
||||
rust
|
||||
pnpm
|
||||
apt
|
||||
|
||||
- name: Set up Turborepo caching
|
||||
if: needs.skip-if-clean.outputs.internal == 'true'
|
||||
uses: namespace-actions/setup-turbocache@f96bd6befa13ae74b2858a5be49573640d4636f5 # v0.0.2
|
||||
|
||||
- name: Install apt dependencies
|
||||
run: |
|
||||
sudo apt-get update
|
||||
sudo apt-get install -y cmake libcurl4-openssl-dev libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev
|
||||
|
||||
- name: Setup Rust toolchain
|
||||
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
|
||||
uses: actions-rust-lang/setup-rust-toolchain@166cdcfd11aee3cb47222f9ddb555ce30ddb9659 # v1.17.0
|
||||
with:
|
||||
rustflags: ''
|
||||
components: clippy, rustfmt
|
||||
@@ -125,28 +125,8 @@ jobs:
|
||||
- name: Setup mold
|
||||
uses: rui314/setup-mold@9c9c13bf4c3f1adef0cc596abc155580bcb04444 # v1 / Mold 2.41.0
|
||||
|
||||
- name: Cache Cargo registry and index
|
||||
uses: actions/cache@27d5ce7f107fe9357f9df03efb73ab90386fccae #v5.0.5
|
||||
with:
|
||||
path: |
|
||||
~/.cargo/registry
|
||||
~/.cargo/git
|
||||
~/.cargo/bin
|
||||
key: ${{ runner.os }}-${{ runner.arch }}-cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||
|
||||
- name: Mount sccache disk cache
|
||||
if: needs.skip-if-clean.outputs.internal == 'true'
|
||||
uses: useblacksmith/stickydisk@13af8883542ca949a717e70fef89d15edbb29d88 # v1.2.0
|
||||
with:
|
||||
key: ${{ github.repository }}-turbo-sccache
|
||||
path: /mnt/sccache
|
||||
|
||||
- name: Setup sccache
|
||||
if: needs.skip-if-clean.outputs.internal == 'true'
|
||||
uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
|
||||
|
||||
- name: Setup binstall
|
||||
uses: cargo-bins/cargo-binstall@dc19f1e48450eefe5a29b8da6c6b00a87d730b37 # v1.18.1
|
||||
uses: cargo-bins/cargo-binstall@ead08b90bd7b2e6d81963fb9cf0b7239f66d5db4 # v1.21.0
|
||||
|
||||
- name: Setup nextest
|
||||
run: cargo binstall --no-confirm --secure --locked cargo-nextest@0.9.133
|
||||
@@ -154,16 +134,13 @@ jobs:
|
||||
# cargo-binstall does not have pre-built binaries for sqlx-cli, so we fall
|
||||
# back to a cached cargo install
|
||||
- name: Setup cargo-sqlx
|
||||
uses: taiki-e/cache-cargo-install-action@f9eed3e4680f27610dc6d8c67be1b88593f7dade # v3.0.6
|
||||
uses: taiki-e/cache-cargo-install-action@417450f3c33ee20393705369577571770643d4c7 # v3.0.7
|
||||
with:
|
||||
tool: sqlx-cli@0.8.6
|
||||
locked: false
|
||||
no-default-features: true
|
||||
features: rustls,postgres
|
||||
|
||||
- name: Setup Turbo cache
|
||||
uses: rharkor/caching-for-turbo@56219402aacc0d06b650d898c222996dbc1191ec # v2.3.14
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
@@ -185,7 +162,7 @@ jobs:
|
||||
|
||||
- name: Start services
|
||||
if: steps.check-labrinth.outputs.needs_services == 'true'
|
||||
run: docker compose up --wait
|
||||
run: docker compose --profile clustered-redis up --wait
|
||||
|
||||
- name: Setup labrinth environment and database
|
||||
if: steps.check-labrinth.outputs.needs_services == 'true'
|
||||
|
||||
Generated
+71
-43
@@ -244,7 +244,7 @@ dependencies = [
|
||||
"serde_json",
|
||||
"serde_urlencoded",
|
||||
"smallvec",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.6.5",
|
||||
"time",
|
||||
"tracing",
|
||||
"url",
|
||||
@@ -458,6 +458,12 @@ version = "1.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
|
||||
|
||||
[[package]]
|
||||
name = "arcstr"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "03918c3dbd7701a85c6b9887732e2921175f26c350b4563841d0958c21d57e6d"
|
||||
|
||||
[[package]]
|
||||
name = "arg_enum_proc_macro"
|
||||
version = "0.3.4"
|
||||
@@ -2478,6 +2484,12 @@ dependencies = [
|
||||
"spin 0.10.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "crc16"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "338089f42c427b86394a5ee60ff321da23a5c89c9d89514c829687b26359fcff"
|
||||
|
||||
[[package]]
|
||||
name = "crc32fast"
|
||||
version = "1.5.0"
|
||||
@@ -2801,7 +2813,7 @@ checksum = "be1e0bca6c3637f992fc1cc7cbc52a78c1ef6db076dbf1059c4323d6a2048376"
|
||||
[[package]]
|
||||
name = "deadpool"
|
||||
version = "0.12.3"
|
||||
source = "git+https://github.com/modrinth/deadpool?rev=db5fb00b036ecc8fe5f18853c559b745ffe47bde#db5fb00b036ecc8fe5f18853c559b745ffe47bde"
|
||||
source = "git+https://github.com/modrinth/deadpool?rev=c7209b086829572f368f1194aba54bdea8dc540b#c7209b086829572f368f1194aba54bdea8dc540b"
|
||||
dependencies = [
|
||||
"deadpool-runtime",
|
||||
"num_cpus",
|
||||
@@ -2811,8 +2823,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "deadpool-redis"
|
||||
version = "0.22.1"
|
||||
source = "git+https://github.com/modrinth/deadpool?rev=db5fb00b036ecc8fe5f18853c559b745ffe47bde#db5fb00b036ecc8fe5f18853c559b745ffe47bde"
|
||||
version = "0.23.0"
|
||||
source = "git+https://github.com/modrinth/deadpool?rev=c7209b086829572f368f1194aba54bdea8dc540b#c7209b086829572f368f1194aba54bdea8dc540b"
|
||||
dependencies = [
|
||||
"deadpool",
|
||||
"redis",
|
||||
@@ -2822,7 +2834,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "deadpool-runtime"
|
||||
version = "0.1.5"
|
||||
source = "git+https://github.com/modrinth/deadpool?rev=db5fb00b036ecc8fe5f18853c559b745ffe47bde#db5fb00b036ecc8fe5f18853c559b745ffe47bde"
|
||||
source = "git+https://github.com/modrinth/deadpool?rev=c7209b086829572f368f1194aba54bdea8dc540b#c7209b086829572f368f1194aba54bdea8dc540b"
|
||||
dependencies = [
|
||||
"tokio",
|
||||
]
|
||||
@@ -4794,7 +4806,7 @@ dependencies = [
|
||||
"libc",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.5.10",
|
||||
"system-configuration",
|
||||
"tokio",
|
||||
"tower-service",
|
||||
@@ -5135,17 +5147,6 @@ dependencies = [
|
||||
"syn 2.0.106",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "io-uring"
|
||||
version = "0.7.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4d09b98f7eace8982db770e4408e7470b028ce513ac28fecdc6bf4c30fe92b62"
|
||||
dependencies = [
|
||||
"bitflags 2.9.4",
|
||||
"cfg-if",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ipconfig"
|
||||
version = "0.3.2"
|
||||
@@ -5470,7 +5471,6 @@ dependencies = [
|
||||
"color-thief",
|
||||
"const_format",
|
||||
"dashmap",
|
||||
"deadpool-redis",
|
||||
"derive_more 2.1.1",
|
||||
"dotenv-build",
|
||||
"dotenvy",
|
||||
@@ -5490,7 +5490,6 @@ dependencies = [
|
||||
"json-patch 4.1.0",
|
||||
"labrinth",
|
||||
"lettre",
|
||||
"lz4_flex",
|
||||
"meilisearch-sdk",
|
||||
"modrinth-content-management",
|
||||
"modrinth-util",
|
||||
@@ -5540,6 +5539,7 @@ dependencies = [
|
||||
"webauthn-rs-proto",
|
||||
"webp",
|
||||
"woothee",
|
||||
"xredis",
|
||||
"yaserde",
|
||||
"zip 6.0.0",
|
||||
"zxcvbn",
|
||||
@@ -5605,7 +5605,7 @@ dependencies = [
|
||||
"quoted_printable",
|
||||
"rustls 0.23.32",
|
||||
"rustls-native-certs 0.8.1",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.6.5",
|
||||
"tokio",
|
||||
"tokio-rustls 0.26.4",
|
||||
"url",
|
||||
@@ -5643,9 +5643,9 @@ checksum = "2c4a545a15244c7d945065b5d392b2d2d7f21526fba56ce51467b06ed445e8f7"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.177"
|
||||
version = "0.2.186"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
|
||||
checksum = "68ab91017fe16c622486840e4c83c9a37afeff978bd239b5293d61ece587de66"
|
||||
|
||||
[[package]]
|
||||
name = "libfuzzer-sys"
|
||||
@@ -6059,14 +6059,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.0.4"
|
||||
version = "1.2.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78bed444cc8a2160f01cbcf811ef18cac863ad68ae8ca62092e8db51d51c761c"
|
||||
checksum = "30d65c71f1ce40ab09135ce117d742b9f8a19ff91a41a8b57ed50bc2de59c427"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"log",
|
||||
"wasi 0.11.1+wasi-snapshot-preview1",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -8014,7 +8014,7 @@ dependencies = [
|
||||
"quinn-udp",
|
||||
"rustc-hash",
|
||||
"rustls 0.23.32",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.5.10",
|
||||
"thiserror 2.0.17",
|
||||
"tokio",
|
||||
"tracing",
|
||||
@@ -8051,7 +8051,7 @@ dependencies = [
|
||||
"cfg_aliases",
|
||||
"libc",
|
||||
"once_cell",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.5.10",
|
||||
"tracing",
|
||||
"windows-sys 0.60.2",
|
||||
]
|
||||
@@ -8345,26 +8345,32 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redis"
|
||||
version = "0.32.7"
|
||||
version = "1.4.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "014cc767fefab6a3e798ca45112bccad9c6e0e218fbd49720042716c73cfef44"
|
||||
checksum = "b0b9503711b03773e43b31668c7b5bd279ee7cd9b7d18cff7c23a42cc1d08e5a"
|
||||
dependencies = [
|
||||
"ahash 0.8.12",
|
||||
"arcstr",
|
||||
"async-lock",
|
||||
"bytes",
|
||||
"cfg-if",
|
||||
"combine",
|
||||
"crc16",
|
||||
"futures-util",
|
||||
"itoa",
|
||||
"log",
|
||||
"num-bigint",
|
||||
"percent-encoding",
|
||||
"pin-project-lite",
|
||||
"r2d2",
|
||||
"rand 0.10.1",
|
||||
"ryu",
|
||||
"sha1_smol",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.6.5",
|
||||
"tokio",
|
||||
"tokio-util",
|
||||
"url",
|
||||
"xxhash-rust",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -9817,12 +9823,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "socket2"
|
||||
version = "0.6.1"
|
||||
version = "0.6.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "17129e116933cf371d018bb80ae557e889637989d8638274fb25622827b03881"
|
||||
checksum = "c3d1e2c7f27f8d4cb10542a02c49005dbd6e93095799d6f3be745fae9f8fedd4"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"windows-sys 0.60.2",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -11272,30 +11278,27 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.47.1"
|
||||
version = "1.53.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "89e49afdadebb872d3145a5638b59eb0691ea23e46ca484037cfab3b76b95038"
|
||||
checksum = "d988bcd52dbe076d3d46903332f58c912b87a2c49b1428419a5845154762ffee"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"io-uring",
|
||||
"libc",
|
||||
"mio",
|
||||
"parking_lot",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"slab",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.6.5",
|
||||
"tokio-macros",
|
||||
"tracing",
|
||||
"windows-sys 0.59.0",
|
||||
"windows-sys 0.61.2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.5.0"
|
||||
version = "2.7.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8"
|
||||
checksum = "6328af13490e73a9b4694030fafd93f8c8c6a9dede33e821c3fc63eddf8042ba"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -11499,7 +11502,7 @@ dependencies = [
|
||||
"hyper-util",
|
||||
"percent-encoding",
|
||||
"pin-project",
|
||||
"socket2 0.6.1",
|
||||
"socket2 0.6.5",
|
||||
"sync_wrapper",
|
||||
"tokio",
|
||||
"tokio-stream",
|
||||
@@ -13429,6 +13432,31 @@ version = "0.13.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4"
|
||||
|
||||
[[package]]
|
||||
name = "xredis"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"ariadne",
|
||||
"chrono",
|
||||
"dashmap",
|
||||
"deadpool-redis",
|
||||
"futures",
|
||||
"lz4_flex",
|
||||
"prometheus",
|
||||
"redis",
|
||||
"serde",
|
||||
"serde_json",
|
||||
"thiserror 2.0.17",
|
||||
"tokio",
|
||||
"tracing",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "xxhash-rust"
|
||||
version = "0.8.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "985eec839aaf2a1270af8f4ebcf63cf9401cfd90f0902f97c28d9f104ffbde72"
|
||||
|
||||
[[package]]
|
||||
name = "yaserde"
|
||||
version = "0.12.0"
|
||||
|
||||
+4
-2
@@ -15,6 +15,7 @@ members = [
|
||||
"packages/modrinth-util",
|
||||
"packages/neverbounce",
|
||||
"packages/path-util",
|
||||
"packages/xredis",
|
||||
]
|
||||
|
||||
[workspace.package]
|
||||
@@ -72,7 +73,7 @@ daedalus = { path = "packages/daedalus" }
|
||||
darling = { version = "0.23" }
|
||||
dashmap = "6.1.0"
|
||||
data-url = "0.3.2"
|
||||
deadpool-redis = { git = "https://github.com/modrinth/deadpool", rev = "db5fb00b036ecc8fe5f18853c559b745ffe47bde", version = "0.22.1" }
|
||||
deadpool-redis = { git = "https://github.com/modrinth/deadpool", rev = "c7209b086829572f368f1194aba54bdea8dc540b", version = "0.23.0" }
|
||||
derive_more = "2.1.1"
|
||||
directories = "6.0.0"
|
||||
dirs = "6.0.0"
|
||||
@@ -154,7 +155,7 @@ quote = { version = "1.0" }
|
||||
rand = "=0.8.5" # Locked on 0.8 until argon2 and p256 update to 0.9
|
||||
rand_chacha = "=0.3.1" # Locked on 0.3 until we can update rand to 0.9
|
||||
rdkafka = { version = "0.36.2", features = ["cmake-build"] }
|
||||
redis = "0.32.7"
|
||||
redis = "1.4.1"
|
||||
regex = "1.12.2"
|
||||
reqwest = { version = "0.12.24", default-features = false }
|
||||
rgb = "0.8.52"
|
||||
@@ -241,6 +242,7 @@ windows = "=0.61.3" # Locked on 0.61 until we can update windows-core to 0.62
|
||||
windows-core = "=0.61.2" # Locked on 0.61 until webview2-com updates to 0.62
|
||||
winreg = "0.55.0"
|
||||
woothee = "0.13.0"
|
||||
xredis = { path = "packages/xredis" }
|
||||
yaserde = "0.12.0"
|
||||
zbus = "5.11.0"
|
||||
zip = { version = "6.0.0", default-features = false, features = [
|
||||
|
||||
+119
-38
@@ -78,24 +78,25 @@ import UnknownPackWarningModal from '@/components/ui/install_flow/UnknownPackWar
|
||||
import MinecraftAuthErrorModal from '@/components/ui/minecraft-auth-error-modal/MinecraftAuthErrorModal.vue'
|
||||
import MinecraftRequiredModal from '@/components/ui/minecraft-required-modal/MinecraftRequiredModal.vue'
|
||||
import AppSettingsModal from '@/components/ui/modal/AppSettingsModal.vue'
|
||||
import AuthGrantFlowWaitModal from '@/components/ui/modal/AuthGrantFlowWaitModal.vue'
|
||||
import InstallToPlayModal from '@/components/ui/modal/InstallToPlayModal.vue'
|
||||
import ModpackAlreadyInstalledModal from '@/components/ui/modal/ModpackAlreadyInstalledModal.vue'
|
||||
import ModrinthAccountRequiredModal from '@/components/ui/modal/ModrinthAccountRequiredModal.vue'
|
||||
import UpdateToPlayModal from '@/components/ui/modal/UpdateToPlayModal.vue'
|
||||
import NavButton from '@/components/ui/NavButton.vue'
|
||||
import PrideFundraiserBanner from '@/components/ui/PrideFundraiserBanner.vue'
|
||||
import PromotionWrapper from '@/components/ui/PromotionWrapper.vue'
|
||||
import QuickInstanceSwitcher from '@/components/ui/QuickInstanceSwitcher.vue'
|
||||
import SharedInstanceInviteHandler from '@/components/ui/shared-instances/shared-instance-invite-handler/index.vue'
|
||||
import SplashScreen from '@/components/ui/SplashScreen.vue'
|
||||
import WindowControls from '@/components/ui/WindowControls.vue'
|
||||
import { useCheckDisableMouseover } from '@/composables/macCssFix.js'
|
||||
import { config } from '@/config'
|
||||
import {
|
||||
ads_consent_listener,
|
||||
get_ads_consent_required,
|
||||
hide_ads_window,
|
||||
init_ads_window,
|
||||
perform_ads_consent_action,
|
||||
should_show_ads_consent_popup,
|
||||
show_ads_window,
|
||||
} from '@/helpers/ads.js'
|
||||
import { debugAnalytics, initAnalytics, trackEvent } from '@/helpers/analytics'
|
||||
@@ -103,8 +104,13 @@ import { check_reachable } from '@/helpers/auth.js'
|
||||
import { get_user, get_version } from '@/helpers/cache.js'
|
||||
import { command_listener, notification_listener, warning_listener } from '@/helpers/events.js'
|
||||
import { install_create_modpack_instance, install_get_modpack_preview } from '@/helpers/install'
|
||||
import { list, run } from '@/helpers/instance'
|
||||
import { cancelLogin, get as getCreds, login, logout } from '@/helpers/mr_auth.ts'
|
||||
import {
|
||||
can_current_user_use_shared_instances,
|
||||
get as getInstance,
|
||||
list,
|
||||
run,
|
||||
} from '@/helpers/instance'
|
||||
import { get as getCreds, login, logout } from '@/helpers/mr_auth.ts'
|
||||
import { mergeUrlQuery, parseModrinthLink } from '@/helpers/project-links.ts'
|
||||
import { get as getSettings, set as setSettings } from '@/helpers/settings.ts'
|
||||
import { get_opening_command, initialize_state } from '@/helpers/state'
|
||||
@@ -155,6 +161,7 @@ const APP_SIDEBAR_WIDTH = 300
|
||||
const INTERCOM_BUBBLE_DEFAULT_PADDING = 20
|
||||
const PRIDE_FUNDRAISER_END_DATE = new Date('2026-07-01T00:00:00Z').getTime()
|
||||
const credentials = ref()
|
||||
let credentialsRefreshId = 0
|
||||
const sidebarToggled = ref(true)
|
||||
const unsubscribeSidebarToggle = themeStore.$subscribe(() => {
|
||||
sidebarToggled.value = !themeStore.toggleSidebar
|
||||
@@ -200,6 +207,7 @@ const tauriApiClient = new TauriModrinthClient({
|
||||
userAgent: async () => `modrinth/theseus/${await appVersion} (support@modrinth.com)`,
|
||||
labrinthBaseUrl: config.labrinthBaseUrl,
|
||||
archonBaseUrl: config.archonBaseUrl,
|
||||
sharedInstancesBaseUrl: config.sharedInstancesBaseUrl,
|
||||
features: [
|
||||
new NodeAuthFeature({
|
||||
getAuth: () => nodeAuthState.getAuth?.() ?? null,
|
||||
@@ -223,6 +231,16 @@ const { data: authenticatedModrinthUser } = useQuery({
|
||||
enabled: () => !!credentials.value?.session,
|
||||
retry: false,
|
||||
})
|
||||
useQuery({
|
||||
queryKey: computed(() => ['shared-instance-eligibility', credentials.value?.user?.id]),
|
||||
queryFn: can_current_user_use_shared_instances,
|
||||
enabled: () => !!credentials.value?.session && !!credentials.value?.user?.id,
|
||||
retry: false,
|
||||
staleTime: Infinity,
|
||||
refetchOnMount: false,
|
||||
refetchOnWindowFocus: false,
|
||||
refetchOnReconnect: false,
|
||||
})
|
||||
const hasPlus = computed(
|
||||
() =>
|
||||
!!credentials.value?.user &&
|
||||
@@ -272,6 +290,9 @@ const {
|
||||
const news = ref([])
|
||||
const availableSurvey = ref(false)
|
||||
const displayedServerInviteNotifications = new Set()
|
||||
const serverInvitePopupNotificationIds = new Set()
|
||||
let liveNotificationGeneration = 0
|
||||
let liveNotificationsEnabled = true
|
||||
|
||||
const offline = ref(!navigator.onLine)
|
||||
window.addEventListener('offline', () => {
|
||||
@@ -318,7 +339,7 @@ onMounted(async () => {
|
||||
await useCheckDisableMouseover()
|
||||
try {
|
||||
unlistenAdsConsent = await ads_consent_listener(handleAdsConsentRequired)
|
||||
handleAdsConsentRequired(await get_ads_consent_required())
|
||||
handleAdsConsentRequired(await should_show_ads_consent_popup())
|
||||
} catch (error) {
|
||||
handleError(error)
|
||||
}
|
||||
@@ -735,9 +756,10 @@ const contentInstallModpackAlreadyInstalledModal = ref()
|
||||
const addServerToInstanceModal = ref()
|
||||
const incompatibilityWarningModal = ref()
|
||||
const installToPlayModal = ref()
|
||||
const sharedInstanceInviteHandler = ref()
|
||||
const updateToPlayModal = ref()
|
||||
|
||||
const modrinthLoginFlowWaitModal = ref()
|
||||
const modrinthLoginModal = ref()
|
||||
|
||||
watch(incompatibilityWarningModal, (modal) => {
|
||||
if (modal) {
|
||||
@@ -745,8 +767,12 @@ watch(incompatibilityWarningModal, (modal) => {
|
||||
}
|
||||
})
|
||||
|
||||
setupAuthProvider(credentials, async (_redirectPath) => {
|
||||
await signIn()
|
||||
setupAuthProvider(credentials, async (_redirectPath, flow, options) => {
|
||||
if (options?.showModal === false) {
|
||||
await signIn(flow)
|
||||
} else {
|
||||
await requestSignIn(flow)
|
||||
}
|
||||
})
|
||||
|
||||
async function validateSession(sessionToken) {
|
||||
@@ -763,23 +789,35 @@ async function validateSession(sessionToken) {
|
||||
}
|
||||
|
||||
async function fetchCredentials() {
|
||||
const hadSession = !!credentials.value?.session
|
||||
const refreshId = ++credentialsRefreshId
|
||||
credentials.value = undefined
|
||||
|
||||
const creds = await getCreds().catch(handleError)
|
||||
if (refreshId !== credentialsRefreshId) return
|
||||
if (!creds && hadSession) clearLiveNotifications()
|
||||
|
||||
if (creds && creds.user_id) {
|
||||
if (creds.session && !(await validateSession(creds.session))) {
|
||||
if (refreshId !== credentialsRefreshId) return
|
||||
|
||||
clearLiveNotifications()
|
||||
await logout().catch(handleError)
|
||||
if (refreshId !== credentialsRefreshId) return
|
||||
|
||||
credentials.value = null
|
||||
return
|
||||
}
|
||||
creds.user = await get_user(creds.user_id, 'bypass').catch(handleError)
|
||||
if (refreshId !== credentialsRefreshId) return
|
||||
}
|
||||
credentials.value = creds ?? null
|
||||
liveNotificationsEnabled = !!creds?.session
|
||||
}
|
||||
|
||||
async function signIn() {
|
||||
modrinthLoginFlowWaitModal.value.show()
|
||||
|
||||
async function signIn(flow = 'sign-in') {
|
||||
try {
|
||||
await login()
|
||||
await login(flow)
|
||||
await fetchCredentials()
|
||||
} catch (error) {
|
||||
if (
|
||||
@@ -791,12 +829,27 @@ async function signIn() {
|
||||
} else {
|
||||
handleError(error)
|
||||
}
|
||||
} finally {
|
||||
modrinthLoginFlowWaitModal.value.hide()
|
||||
}
|
||||
}
|
||||
|
||||
async function requestSignIn(flow = 'sign-in') {
|
||||
await modrinthLoginModal.value?.showSigningIn(flow)
|
||||
}
|
||||
|
||||
async function requestModrinthAuth(flow = 'sign-in') {
|
||||
await signIn(flow)
|
||||
return !!credentials.value?.session
|
||||
}
|
||||
|
||||
async function logOut() {
|
||||
await performLogOut()
|
||||
}
|
||||
|
||||
async function performLogOut() {
|
||||
credentialsRefreshId++
|
||||
credentials.value = undefined
|
||||
clearLiveNotifications()
|
||||
|
||||
await logout().catch(handleError)
|
||||
await fetchCredentials()
|
||||
}
|
||||
@@ -917,30 +970,48 @@ function openServerInviteInviterProfile(inviterName) {
|
||||
}
|
||||
|
||||
async function handleLiveNotification(notification) {
|
||||
if (notification?.body?.type !== 'server_invite' || notification.read) return
|
||||
if (displayedServerInviteNotifications.has(notification.id)) return
|
||||
if (!liveNotificationsEnabled || !notification?.body || notification.read) return
|
||||
if (await sharedInstanceInviteHandler.value?.handleNotification(notification)) return
|
||||
|
||||
displayedServerInviteNotifications.add(notification.id)
|
||||
if (notification.body.type === 'server_invite') {
|
||||
if (displayedServerInviteNotifications.has(notification.id)) return
|
||||
|
||||
const serverName =
|
||||
typeof notification.body.server_name === 'string' ? notification.body.server_name : 'a server'
|
||||
const inviterId = notification.body.invited_by
|
||||
const invitedBy =
|
||||
typeof inviterId === 'string' ? await get_user(inviterId, 'bypass').catch(() => null) : null
|
||||
const generation = liveNotificationGeneration
|
||||
displayedServerInviteNotifications.add(notification.id)
|
||||
|
||||
addPopupNotification({
|
||||
title: serverName,
|
||||
autoCloseMs: null,
|
||||
toast: {
|
||||
type: 'server-invite',
|
||||
actorName: invitedBy?.username ?? null,
|
||||
actorAvatarUrl: invitedBy?.avatar_url ?? null,
|
||||
entityName: serverName,
|
||||
onAccept: () => acceptServerInviteNotification(notification),
|
||||
onDecline: () => declineServerInviteNotification(notification),
|
||||
onOpenActor: () => openServerInviteInviterProfile(invitedBy?.username ?? null),
|
||||
},
|
||||
})
|
||||
const serverName =
|
||||
typeof notification.body.server_name === 'string' ? notification.body.server_name : 'a server'
|
||||
const inviterId = notification.body.invited_by
|
||||
const invitedBy =
|
||||
typeof inviterId === 'string' ? await get_user(inviterId, 'bypass').catch(() => null) : null
|
||||
if (generation !== liveNotificationGeneration) return
|
||||
|
||||
const popupNotification = addPopupNotification({
|
||||
title: serverName,
|
||||
autoCloseMs: null,
|
||||
toast: {
|
||||
type: 'server-invite',
|
||||
actorName: invitedBy?.username ?? null,
|
||||
actorAvatarUrl: invitedBy?.avatar_url ?? null,
|
||||
entityName: serverName,
|
||||
onAccept: () => acceptServerInviteNotification(notification),
|
||||
onDecline: () => declineServerInviteNotification(notification),
|
||||
onOpenActor: () => openServerInviteInviterProfile(invitedBy?.username ?? null),
|
||||
},
|
||||
})
|
||||
serverInvitePopupNotificationIds.add(popupNotification.id)
|
||||
}
|
||||
}
|
||||
|
||||
function clearLiveNotifications() {
|
||||
liveNotificationGeneration++
|
||||
liveNotificationsEnabled = false
|
||||
for (const id of serverInvitePopupNotificationIds) {
|
||||
popupNotificationManager.removeNotification(id)
|
||||
}
|
||||
displayedServerInviteNotifications.clear()
|
||||
serverInvitePopupNotificationIds.clear()
|
||||
sharedInstanceInviteHandler.value?.clearNotifications()
|
||||
}
|
||||
|
||||
async function handleCommand(e) {
|
||||
@@ -967,6 +1038,9 @@ async function handleCommand(e) {
|
||||
})
|
||||
}
|
||||
} else if (e.event === 'LaunchInstance') {
|
||||
const instance = await getInstance(e.id).catch(handleError)
|
||||
if (!instance || instance.quarantined) return
|
||||
|
||||
if (e.server) {
|
||||
await start_join_server(e.id, e.server).catch(handleError)
|
||||
} else if (e.singleplayer_world) {
|
||||
@@ -974,6 +1048,8 @@ async function handleCommand(e) {
|
||||
} else {
|
||||
await run(e.id).catch(handleError)
|
||||
}
|
||||
} else if (e.event === 'InstallSharedInstanceInvite') {
|
||||
await sharedInstanceInviteHandler.value?.installFromInviteId(e.invite_id)
|
||||
} else if (e.event === 'InstallServer') {
|
||||
await router.push(`/project/${e.id}`)
|
||||
await playServerProject(e.id).catch(handleError)
|
||||
@@ -1498,7 +1574,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
<AppSettingsModal ref="settingsModal" />
|
||||
</Suspense>
|
||||
<Suspense>
|
||||
<AuthGrantFlowWaitModal ref="modrinthLoginFlowWaitModal" @flow-cancel="cancelLogin" />
|
||||
<ModrinthAccountRequiredModal ref="modrinthLoginModal" :request-auth="requestModrinthAuth" />
|
||||
</Suspense>
|
||||
<CreationFlowModal
|
||||
ref="installationModal"
|
||||
@@ -1602,7 +1678,11 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
</template>
|
||||
<template #sign-out> <LogOutIcon /> Sign out </template>
|
||||
</OverflowMenu>
|
||||
<NavButton v-else v-tooltip.right="'Sign in to a Modrinth account'" :to="() => signIn()">
|
||||
<NavButton
|
||||
v-else
|
||||
v-tooltip.right="'Sign in to a Modrinth account'"
|
||||
:to="() => requestSignIn()"
|
||||
>
|
||||
<LogInIcon class="text-brand" />
|
||||
</NavButton>
|
||||
</div>
|
||||
@@ -1749,7 +1829,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
</div>
|
||||
<div class="p-4 border-0 border-b-[1px] border-[--brand-gradient-border] border-solid">
|
||||
<suspense>
|
||||
<FriendsList :credentials="credentials" :sign-in="() => signIn()" />
|
||||
<FriendsList :credentials="credentials" :sign-in="() => requestSignIn()" />
|
||||
</suspense>
|
||||
</div>
|
||||
<PrideFundraiserBanner
|
||||
@@ -1834,6 +1914,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
|
||||
@create-anyway="handleContentInstallModpackDuplicateCreateAnyway"
|
||||
@go-to-instance="handleContentInstallModpackDuplicateGoToInstance"
|
||||
/>
|
||||
<SharedInstanceInviteHandler ref="sharedInstanceInviteHandler" />
|
||||
<InstallToPlayModal ref="installToPlayModal" :show-external-warnings="false" />
|
||||
<UpdateToPlayModal ref="updateToPlayModal" :show-external-warnings="false" />
|
||||
</template>
|
||||
|
||||
@@ -65,8 +65,7 @@ async function duplicateInstance(p) {
|
||||
const handleRightClick = (event, instanceId) => {
|
||||
const item = instanceComponents.value.find((x) => x.instance.id === instanceId)
|
||||
const baseOptions = [
|
||||
{ name: 'add_content' },
|
||||
{ type: 'divider' },
|
||||
...(item.instance.quarantined ? [] : [{ name: 'add_content' }, { type: 'divider' }]),
|
||||
{ name: 'edit' },
|
||||
{ name: 'duplicate' },
|
||||
{ name: 'open' },
|
||||
@@ -90,10 +89,14 @@ const handleRightClick = (event, instanceId) => {
|
||||
...baseOptions,
|
||||
]
|
||||
: [
|
||||
{
|
||||
name: 'play',
|
||||
color: 'primary',
|
||||
},
|
||||
...(item.instance.quarantined
|
||||
? []
|
||||
: [
|
||||
{
|
||||
name: 'play',
|
||||
color: 'primary',
|
||||
},
|
||||
]),
|
||||
...baseOptions,
|
||||
],
|
||||
)
|
||||
|
||||
@@ -73,8 +73,7 @@ async function duplicateInstance(p) {
|
||||
|
||||
const handleInstanceRightClick = async (event, passedInstance) => {
|
||||
const baseOptions = [
|
||||
{ name: 'add_content' },
|
||||
{ type: 'divider' },
|
||||
...(passedInstance.quarantined ? [] : [{ name: 'add_content' }, { type: 'divider' }]),
|
||||
{ name: 'edit' },
|
||||
{ name: 'duplicate' },
|
||||
{ name: 'open_folder' },
|
||||
@@ -98,10 +97,14 @@ const handleInstanceRightClick = async (event, passedInstance) => {
|
||||
...baseOptions,
|
||||
]
|
||||
: [
|
||||
{
|
||||
name: 'play',
|
||||
color: 'primary',
|
||||
},
|
||||
...(passedInstance.quarantined
|
||||
? []
|
||||
: [
|
||||
{
|
||||
name: 'play',
|
||||
color: 'primary',
|
||||
},
|
||||
]),
|
||||
...baseOptions,
|
||||
]
|
||||
|
||||
|
||||
@@ -66,6 +66,7 @@ const checkProcess = async () => {
|
||||
|
||||
const play = async (e, context) => {
|
||||
e?.stopPropagation()
|
||||
if (props.instance.quarantined) return
|
||||
loading.value = true
|
||||
await run(props.instance.id)
|
||||
.catch((err) => handleSevereError(err, { instanceId: props.instance.id }))
|
||||
@@ -94,6 +95,7 @@ const stop = async (e, context) => {
|
||||
|
||||
const repair = async (e) => {
|
||||
e?.stopPropagation()
|
||||
if (props.instance.quarantined) return
|
||||
|
||||
if (
|
||||
props.instance.install_stage !== 'pack_installed' &&
|
||||
@@ -116,6 +118,7 @@ const openFolder = async () => {
|
||||
}
|
||||
|
||||
const addContent = async () => {
|
||||
if (props.instance.quarantined) return
|
||||
await router.push({
|
||||
path: `/browse/${props.instance.loader === 'vanilla' ? 'datapack' : 'mod'}`,
|
||||
query: { i: props.instance.id },
|
||||
@@ -142,7 +145,9 @@ const unlisten = await process_listener((e) => {
|
||||
}
|
||||
})
|
||||
|
||||
onMounted(() => checkProcess())
|
||||
onMounted(() => {
|
||||
checkProcess()
|
||||
})
|
||||
onUnmounted(() => unlisten())
|
||||
</script>
|
||||
|
||||
@@ -173,7 +178,11 @@ onUnmounted(() => unlisten())
|
||||
<SpinnerIcon class="animate-spin" />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled v-else :color="first ? 'brand' : 'standard'" circular>
|
||||
<ButtonStyled
|
||||
v-else-if="!instance.quarantined"
|
||||
:color="first ? 'brand' : 'standard'"
|
||||
circular
|
||||
>
|
||||
<button
|
||||
v-tooltip="'Play'"
|
||||
@click="(e) => play(e, 'InstanceCard')"
|
||||
@@ -227,7 +236,12 @@ onUnmounted(() => unlisten())
|
||||
class="animate-spin w-8 h-8"
|
||||
tabindex="-1"
|
||||
/>
|
||||
<ButtonStyled v-else-if="!installed" size="large" color="brand" circular>
|
||||
<ButtonStyled
|
||||
v-else-if="!installed && !instance.quarantined"
|
||||
size="large"
|
||||
color="brand"
|
||||
circular
|
||||
>
|
||||
<button
|
||||
v-tooltip="'Repair'"
|
||||
class="transition-all scale-75 group-hover:scale-100 group-focus-within:scale-100 origin-bottom opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 card-shadow"
|
||||
@@ -236,7 +250,7 @@ onUnmounted(() => unlisten())
|
||||
<DownloadIcon />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled v-else size="large" color="brand" circular>
|
||||
<ButtonStyled v-else-if="!instance.quarantined" size="large" color="brand" circular>
|
||||
<button
|
||||
v-tooltip="'Play'"
|
||||
class="transition-all scale-75 group-hover:scale-100 group-focus-within:scale-100 origin-bottom opacity-0 group-hover:opacity-100 group-focus-within:opacity-100 card-shadow"
|
||||
|
||||
@@ -10,18 +10,12 @@ import {
|
||||
useRelativeTime,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, onUnmounted, ref, watch } from 'vue'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import FriendsSection from '@/components/ui/friends/FriendsSection.vue'
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
import { friend_listener } from '@/helpers/events'
|
||||
import {
|
||||
add_friend,
|
||||
friends,
|
||||
type FriendWithUserData,
|
||||
remove_friend,
|
||||
transformFriends,
|
||||
} from '@/helpers/friends.ts'
|
||||
import { useFriends } from '@/composables/use-friends'
|
||||
import type { FriendWithUserData } from '@/helpers/friends.ts'
|
||||
import type { ModrinthCredentials } from '@/helpers/mr_auth'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
@@ -35,36 +29,23 @@ const props = defineProps<{
|
||||
}>()
|
||||
|
||||
const userCredentials = computed(() => props.credentials)
|
||||
const {
|
||||
friends: userFriends,
|
||||
loading,
|
||||
requestFriend,
|
||||
acceptFriend,
|
||||
removeFriend: removeFriendRecord,
|
||||
} = useFriends({
|
||||
currentUserId: () => userCredentials.value?.user_id,
|
||||
getCredentials: () => userCredentials.value,
|
||||
onError: handleError,
|
||||
})
|
||||
|
||||
const search = ref('')
|
||||
const friendInvitesModal = ref()
|
||||
|
||||
const username = ref('')
|
||||
const addFriendModal = ref()
|
||||
async function addFriendFromModal() {
|
||||
addFriendModal.value.hide()
|
||||
await add_friend(username.value).catch(handleError)
|
||||
username.value = ''
|
||||
await loadFriends()
|
||||
}
|
||||
|
||||
async function addFriend(friend: FriendWithUserData) {
|
||||
const id = friend.id === userCredentials.value?.user_id ? friend.friend_id : friend.id
|
||||
if (id) {
|
||||
await add_friend(id).catch(handleError)
|
||||
await loadFriends()
|
||||
}
|
||||
}
|
||||
|
||||
async function removeFriend(friend: FriendWithUserData) {
|
||||
const id = friend.id === userCredentials.value?.user_id ? friend.friend_id : friend.id
|
||||
if (id) {
|
||||
await remove_friend(id).catch(handleError)
|
||||
await loadFriends()
|
||||
}
|
||||
}
|
||||
|
||||
const userFriends = ref<FriendWithUserData[]>([])
|
||||
const sortedFriends = computed<FriendWithUserData[]>(() =>
|
||||
userFriends.value.slice().sort((a, b) => {
|
||||
if (a.last_updated === null && b.last_updated === null) {
|
||||
@@ -108,42 +89,22 @@ const incomingRequests = computed(() =>
|
||||
.sort((a, b) => b.created.diff(a.created)),
|
||||
)
|
||||
|
||||
const loading = ref(true)
|
||||
async function loadFriends(timeout = false) {
|
||||
loading.value = timeout
|
||||
function addFriendFromModal() {
|
||||
const target = username.value.trim()
|
||||
if (!target) return
|
||||
|
||||
try {
|
||||
const friendsList = await friends()
|
||||
userFriends.value = await transformFriends(friendsList, userCredentials.value)
|
||||
loading.value = false
|
||||
} catch (e) {
|
||||
console.error('Error loading friends', e)
|
||||
if (timeout) {
|
||||
setTimeout(() => loadFriends(), 15 * 1000)
|
||||
}
|
||||
}
|
||||
addFriendModal.value.hide()
|
||||
requestFriend({ id: target, username: target })
|
||||
username.value = ''
|
||||
}
|
||||
|
||||
watch(
|
||||
userCredentials,
|
||||
() => {
|
||||
if (userCredentials.value === undefined) {
|
||||
userFriends.value = []
|
||||
loading.value = false
|
||||
} else if (userCredentials.value === null) {
|
||||
userFriends.value = []
|
||||
loading.value = false
|
||||
} else {
|
||||
loadFriends(true)
|
||||
}
|
||||
},
|
||||
{ immediate: true },
|
||||
)
|
||||
function addFriend(friend: FriendWithUserData) {
|
||||
acceptFriend(friend)
|
||||
}
|
||||
|
||||
const unlisten = await friend_listener(() => loadFriends())
|
||||
onUnmounted(() => {
|
||||
unlisten()
|
||||
})
|
||||
function removeFriend(friend: FriendWithUserData) {
|
||||
removeFriendRecord(friend)
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
addFriend: {
|
||||
|
||||
@@ -4,23 +4,57 @@
|
||||
<Avatar :src="iconSrc" :alt="instance.name" size="64px" :tint-by="instance.id" />
|
||||
</template>
|
||||
|
||||
<template v-if="instance.shared_instance || instance.quarantined" #badges>
|
||||
<PageHeaderBadgeItem
|
||||
v-if="instance.quarantined"
|
||||
:icon="LockIcon"
|
||||
aria-label="Locked instance information"
|
||||
class="!border-orange !bg-highlight-orange !text-orange"
|
||||
>
|
||||
Locked
|
||||
</PageHeaderBadgeItem>
|
||||
<PageHeaderBadgeItem
|
||||
v-else
|
||||
:icon="UnknownIcon"
|
||||
:tooltip="sharedInstanceTooltip"
|
||||
aria-label="Shared instance information"
|
||||
class="!border-blue !bg-highlight-blue !text-blue"
|
||||
>
|
||||
Shared
|
||||
</PageHeaderBadgeItem>
|
||||
</template>
|
||||
|
||||
<template #metadata>
|
||||
<InstanceHeaderServerMetadata
|
||||
v-if="isServerInstance"
|
||||
:loading-server-ping="loadingServerPing"
|
||||
:players-online="playersOnline"
|
||||
:status-online="statusOnline"
|
||||
:recent-plays="recentPlays"
|
||||
:ping="ping"
|
||||
:minecraft-server="minecraftServer"
|
||||
:linked-project-v3="linkedProjectV3"
|
||||
:instance-id="instance.id"
|
||||
/>
|
||||
<div v-if="isServerInstance" class="flex flex-wrap items-center gap-2">
|
||||
<InstanceHeaderServerMetadata
|
||||
:loading-server-ping="loadingServerPing"
|
||||
:players-online="playersOnline"
|
||||
:status-online="statusOnline"
|
||||
:recent-plays="recentPlays"
|
||||
:ping="ping"
|
||||
:minecraft-server="minecraftServer"
|
||||
:linked-project-v3="linkedProjectV3"
|
||||
:instance-id="instance.id"
|
||||
/>
|
||||
<PageHeaderMetadataItem v-if="sharedInstanceManager" :action="sharedInstanceManagerAction">
|
||||
{{ sharedInstanceManagerLabel }}
|
||||
<Avatar
|
||||
:src="sharedInstanceManager.avatarUrl"
|
||||
:alt="sharedInstanceManager.name"
|
||||
:tint-by="sharedInstanceManager.tintBy"
|
||||
size="24px"
|
||||
:circle="sharedInstanceManager.type === 'user'"
|
||||
no-shadow
|
||||
/>
|
||||
<span class="min-w-0 truncate">{{ sharedInstanceManager.name }}</span>
|
||||
</PageHeaderMetadataItem>
|
||||
</div>
|
||||
<PageHeaderMetadata v-else>
|
||||
<PageHeaderMetadataItem :icon="Gamepad2Icon" tooltip="Minecraft version">
|
||||
Minecraft {{ instance.game_version }}
|
||||
</PageHeaderMetadataItem>
|
||||
<PageHeaderMetadataItem
|
||||
v-if="sharedInstanceManager?.type !== 'user'"
|
||||
:icon="ServerLoaderIcon"
|
||||
:icon-props="{ loader: loaderDisplayName }"
|
||||
tooltip="Mod loader"
|
||||
@@ -34,6 +68,18 @@
|
||||
>
|
||||
{{ playtimeLabel }}
|
||||
</PageHeaderMetadataItem>
|
||||
<PageHeaderMetadataItem v-if="sharedInstanceManager" :action="sharedInstanceManagerAction">
|
||||
{{ sharedInstanceManagerLabel }}
|
||||
<Avatar
|
||||
:src="sharedInstanceManager.avatarUrl"
|
||||
:alt="sharedInstanceManager.name"
|
||||
:tint-by="sharedInstanceManager.tintBy"
|
||||
size="24px"
|
||||
:circle="sharedInstanceManager.type === 'user'"
|
||||
no-shadow
|
||||
/>
|
||||
<span class="min-w-0 truncate">{{ sharedInstanceManager.name }}</span>
|
||||
</PageHeaderMetadataItem>
|
||||
</PageHeaderMetadata>
|
||||
</template>
|
||||
|
||||
@@ -44,12 +90,6 @@
|
||||
{{ formatMessage(commonMessages.installingLabel) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled v-else-if="instance.install_stage !== 'installed'" color="brand" size="large">
|
||||
<button type="button" @click="emit('repair')">
|
||||
<DownloadIcon />
|
||||
{{ formatMessage(messages.repair) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled v-else-if="playing" color="red" size="large">
|
||||
<button type="button" :disabled="stopping" @click="emit('stop')">
|
||||
<StopCircleIcon />
|
||||
@@ -58,6 +98,18 @@
|
||||
}}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled v-else-if="instance.quarantined" color="brand" size="large">
|
||||
<button v-tooltip="formatMessage(messages.lockedPlayTooltip)" type="button" disabled>
|
||||
<PlayIcon />
|
||||
{{ formatMessage(commonMessages.playButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled v-else-if="instance.install_stage !== 'installed'" color="brand" size="large">
|
||||
<button type="button" @click="emit('repair')">
|
||||
<DownloadIcon />
|
||||
{{ formatMessage(messages.repair) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<JoinedButtons
|
||||
v-else-if="!loading && isServerInstance"
|
||||
:actions="serverPlayActions"
|
||||
@@ -104,13 +156,16 @@ import {
|
||||
DownloadIcon,
|
||||
ExternalIcon,
|
||||
FolderOpenIcon,
|
||||
LockIcon,
|
||||
MoreVerticalIcon,
|
||||
PackageIcon,
|
||||
PlayIcon,
|
||||
ReportIcon,
|
||||
SettingsIcon,
|
||||
StopCircleIcon,
|
||||
TagCategoryGamepad2Icon as Gamepad2Icon,
|
||||
TimerIcon,
|
||||
UnknownIcon,
|
||||
} from '@modrinth/assets'
|
||||
import {
|
||||
Avatar,
|
||||
@@ -123,6 +178,7 @@ import {
|
||||
LoaderIcon as ServerLoaderIcon,
|
||||
PageHeader,
|
||||
PageHeaderActions,
|
||||
PageHeaderBadgeItem,
|
||||
PageHeaderMetadata,
|
||||
PageHeaderMetadataItem,
|
||||
type ServerLoader,
|
||||
@@ -130,6 +186,7 @@ import {
|
||||
type TeleportOverflowMenuItem,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
@@ -169,6 +226,10 @@ const messages = defineMessages({
|
||||
id: 'instance.action.repair',
|
||||
defaultMessage: 'Repair',
|
||||
},
|
||||
lockedPlayTooltip: {
|
||||
id: 'instance.locked.play-tooltip',
|
||||
defaultMessage: 'This instance has been locked',
|
||||
},
|
||||
starting: {
|
||||
id: 'instance.action.starting',
|
||||
defaultMessage: 'Starting...',
|
||||
@@ -177,6 +238,14 @@ const messages = defineMessages({
|
||||
id: 'instance.action.stopping',
|
||||
defaultMessage: 'Stopping...',
|
||||
},
|
||||
sharedInstanceTooltip: {
|
||||
id: 'instance.shared-instance.tooltip',
|
||||
defaultMessage: "This instance's content is being managed by someone else.",
|
||||
},
|
||||
sharedInstanceOwnerTooltip: {
|
||||
id: 'instance.shared-instance.owner-tooltip',
|
||||
defaultMessage: "This instance's content is being shared to other users.",
|
||||
},
|
||||
})
|
||||
|
||||
const props = withDefaults(
|
||||
@@ -196,6 +265,12 @@ const props = withDefaults(
|
||||
ping?: number
|
||||
minecraftServer?: Labrinth.Projects.v3.Project['minecraft_server']
|
||||
linkedProjectV3?: Labrinth.Projects.v3.Project
|
||||
sharedInstanceManager?: {
|
||||
type: 'user' | 'server'
|
||||
name: string
|
||||
avatarUrl?: string
|
||||
tintBy: string
|
||||
} | null
|
||||
}>(),
|
||||
{
|
||||
iconSrc: null,
|
||||
@@ -212,6 +287,7 @@ const props = withDefaults(
|
||||
ping: undefined,
|
||||
minecraftServer: undefined,
|
||||
linkedProjectV3: undefined,
|
||||
sharedInstanceManager: null,
|
||||
},
|
||||
)
|
||||
|
||||
@@ -224,6 +300,7 @@ const emit = defineEmits<{
|
||||
openFolder: []
|
||||
export: []
|
||||
createShortcut: []
|
||||
report: [event?: MouseEvent]
|
||||
}>()
|
||||
|
||||
const installingStages = [
|
||||
@@ -241,6 +318,21 @@ const loaderDisplayName = computed(() => formatLoaderLabel(props.instance.loader
|
||||
const loaderLabel = computed(() =>
|
||||
[loaderDisplayName.value, props.instance.loader_version].filter(Boolean).join(' '),
|
||||
)
|
||||
const sharedInstanceTooltip = computed(() =>
|
||||
formatMessage(
|
||||
props.instance.shared_instance?.role === 'owner'
|
||||
? messages.sharedInstanceOwnerTooltip
|
||||
: messages.sharedInstanceTooltip,
|
||||
),
|
||||
)
|
||||
const sharedInstanceManagerLabel = computed(() =>
|
||||
props.sharedInstanceManager?.type === 'server' ? 'Linked to' : 'Managed by',
|
||||
)
|
||||
const sharedInstanceManagerAction = computed(() => {
|
||||
const manager = props.sharedInstanceManager
|
||||
if (manager?.type !== 'user') return undefined
|
||||
return () => openUrl(`https://modrinth.com/user/${encodeURIComponent(manager.name)}`)
|
||||
})
|
||||
const playtimeLabel = computed(() => {
|
||||
if (props.timePlayed <= 0) return formatMessage(messages.neverPlayed)
|
||||
|
||||
@@ -271,24 +363,46 @@ const serverPlayActions = computed<JoinedButtonAction[]>(() => [
|
||||
action: () => emit('play'),
|
||||
},
|
||||
])
|
||||
const moreActions = computed<TeleportOverflowMenuItem[]>(() => [
|
||||
{
|
||||
id: 'open-folder',
|
||||
label: formatMessage(messages.openFolder),
|
||||
icon: FolderOpenIcon,
|
||||
action: () => emit('openFolder'),
|
||||
},
|
||||
{
|
||||
id: 'export-mrpack',
|
||||
label: formatMessage(messages.exportModpack),
|
||||
icon: PackageIcon,
|
||||
action: () => emit('export'),
|
||||
},
|
||||
{
|
||||
id: 'create-shortcut',
|
||||
label: formatMessage(messages.createShortcut),
|
||||
icon: ExternalIcon,
|
||||
action: () => emit('createShortcut'),
|
||||
},
|
||||
])
|
||||
const moreActions = computed<TeleportOverflowMenuItem[]>(() => {
|
||||
const actions: TeleportOverflowMenuItem[] = [
|
||||
{
|
||||
id: 'open-folder',
|
||||
label: formatMessage(messages.openFolder),
|
||||
icon: FolderOpenIcon,
|
||||
action: () => emit('openFolder'),
|
||||
},
|
||||
]
|
||||
|
||||
if (!props.instance.quarantined) {
|
||||
actions.push(
|
||||
{
|
||||
id: 'export-mrpack',
|
||||
label: formatMessage(messages.exportModpack),
|
||||
icon: PackageIcon,
|
||||
action: () => emit('export'),
|
||||
},
|
||||
{
|
||||
id: 'create-shortcut',
|
||||
label: formatMessage(messages.createShortcut),
|
||||
icon: ExternalIcon,
|
||||
action: () => emit('createShortcut'),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
if (props.instance.shared_instance?.role === 'member') {
|
||||
actions.push(
|
||||
{ divider: true },
|
||||
{
|
||||
id: 'report-shared-instance',
|
||||
label: formatMessage(commonMessages.reportButton),
|
||||
icon: ReportIcon,
|
||||
color: 'red',
|
||||
action: (event) => emit('report', event),
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
return actions
|
||||
})
|
||||
</script>
|
||||
|
||||
@@ -0,0 +1,116 @@
|
||||
<template>
|
||||
<StackedAdmonitions v-bind="$attrs" :items="stackItems" class="w-full">
|
||||
<template #item="{ item, dismissible }">
|
||||
<InstanceAdmonitionsSharedInstanceStale
|
||||
v-if="item.kind === 'shared-instance-stale'"
|
||||
:instance="instance"
|
||||
@published="emit('published')"
|
||||
/>
|
||||
<InstanceAdmonitionsSharedInstanceWrongAccount
|
||||
v-else-if="item.kind === 'shared-instance-wrong-account'"
|
||||
:expected-user-id="sharedInstanceExpectedUserId"
|
||||
:role="sharedInstanceRole"
|
||||
:signed-out="sharedInstanceSignedOut"
|
||||
/>
|
||||
<InstanceAdmonitionsSharedInstanceUnavailable
|
||||
v-else-if="item.kind === 'shared-instance-unavailable'"
|
||||
:reason="displayedSharedInstanceUnavailableReason"
|
||||
:manager="sharedInstanceUnavailableManager"
|
||||
:dismissible="dismissible"
|
||||
@dismiss="sharedInstanceUnavailableDismissed = true"
|
||||
@delete="emit('delete')"
|
||||
/>
|
||||
</template>
|
||||
</StackedAdmonitions>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { StackedAdmonitions } from '@modrinth/ui'
|
||||
import { computed, ref, watch } from 'vue'
|
||||
|
||||
import type { SharedInstanceUnavailableReason } from '@/helpers/install'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
|
||||
import InstanceAdmonitionsSharedInstanceStale from './instance-admonitions-shared-instance-stale.vue'
|
||||
import InstanceAdmonitionsSharedInstanceUnavailable from './instance-admonitions-shared-instance-unavailable.vue'
|
||||
import InstanceAdmonitionsSharedInstanceWrongAccount from './instance-admonitions-shared-instance-wrong-account.vue'
|
||||
import type { InstanceAdmonitionItem, SharedInstanceRole } from './types'
|
||||
|
||||
defineOptions({
|
||||
inheritAttrs: false,
|
||||
})
|
||||
|
||||
const props = defineProps<{
|
||||
instance: GameInstance
|
||||
sharedInstanceUnavailableReason?: SharedInstanceUnavailableReason | null
|
||||
sharedInstanceUnavailableManager?: string | null
|
||||
sharedInstanceWrongAccount?: boolean
|
||||
sharedInstanceExpectedUserId?: string | null
|
||||
sharedInstanceRole?: SharedInstanceRole | null
|
||||
sharedInstanceSignedOut?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
published: []
|
||||
delete: []
|
||||
}>()
|
||||
|
||||
const sharedInstanceWrongAccount = computed(() => props.sharedInstanceWrongAccount ?? false)
|
||||
const displayedSharedInstanceUnavailableReason = computed<SharedInstanceUnavailableReason | null>(
|
||||
() =>
|
||||
props.instance.quarantined ? 'quarantined' : (props.sharedInstanceUnavailableReason ?? null),
|
||||
)
|
||||
const sharedInstanceUnavailableDismissed = ref(false)
|
||||
const showSharedInstancePublishAdmonition = computed(
|
||||
() =>
|
||||
!sharedInstanceWrongAccount.value &&
|
||||
props.instance.install_stage === 'installed' &&
|
||||
props.instance.shared_instance?.role === 'owner' &&
|
||||
props.instance.shared_instance.status === 'stale',
|
||||
)
|
||||
|
||||
const stackItems = computed<InstanceAdmonitionItem[]>(() => {
|
||||
const items: InstanceAdmonitionItem[] = []
|
||||
|
||||
if (sharedInstanceWrongAccount.value) {
|
||||
items.push({
|
||||
id: 'shared-instance-wrong-account',
|
||||
type: 'warning',
|
||||
dismissible: false,
|
||||
kind: 'shared-instance-wrong-account',
|
||||
})
|
||||
}
|
||||
|
||||
const unavailableReason = displayedSharedInstanceUnavailableReason.value
|
||||
const sharedInstanceQuarantined = unavailableReason === 'quarantined'
|
||||
if (
|
||||
unavailableReason &&
|
||||
(sharedInstanceQuarantined || !sharedInstanceUnavailableDismissed.value)
|
||||
) {
|
||||
items.push({
|
||||
id: 'shared-instance-unavailable',
|
||||
type: 'warning',
|
||||
dismissible: !sharedInstanceQuarantined,
|
||||
kind: 'shared-instance-unavailable',
|
||||
})
|
||||
}
|
||||
|
||||
if (showSharedInstancePublishAdmonition.value) {
|
||||
items.push({
|
||||
id: 'shared-instance-stale',
|
||||
type: 'warning',
|
||||
dismissible: false,
|
||||
kind: 'shared-instance-stale',
|
||||
})
|
||||
}
|
||||
|
||||
return items
|
||||
})
|
||||
|
||||
watch(
|
||||
() => [props.instance.id, displayedSharedInstanceUnavailableReason.value],
|
||||
() => {
|
||||
sharedInstanceUnavailableDismissed.value = false
|
||||
},
|
||||
)
|
||||
</script>
|
||||
+69
@@ -0,0 +1,69 @@
|
||||
import { defineMessages } from '@modrinth/ui'
|
||||
|
||||
export const instanceAdmonitionsMessages = defineMessages({
|
||||
sharedInstanceChangesHeader: {
|
||||
id: 'app.instance.admonitions.shared-instance.changes-header',
|
||||
defaultMessage: "Your changes haven't been shared yet",
|
||||
},
|
||||
sharedInstanceChangesBody: {
|
||||
id: 'app.instance.admonitions.shared-instance.changes-body',
|
||||
defaultMessage: "Your local instance is ahead of the users you've shared it with.",
|
||||
},
|
||||
sharedInstancePublishButton: {
|
||||
id: 'app.instance.admonitions.shared-instance.publish-button',
|
||||
defaultMessage: 'Push update',
|
||||
},
|
||||
sharedInstancePublishingButton: {
|
||||
id: 'app.instance.admonitions.shared-instance.publishing-button',
|
||||
defaultMessage: 'Pushing...',
|
||||
},
|
||||
sharedInstanceReviewingButton: {
|
||||
id: 'app.instance.admonitions.shared-instance.reviewing-button',
|
||||
defaultMessage: 'Reviewing...',
|
||||
},
|
||||
sharedInstanceReviewHeader: {
|
||||
id: 'app.instance.admonitions.shared-instance.review-header',
|
||||
defaultMessage: 'Review changes',
|
||||
},
|
||||
sharedInstanceReviewAdmonitionHeader: {
|
||||
id: 'app.instance.admonitions.shared-instance.review-admonition-header',
|
||||
defaultMessage: 'Push update',
|
||||
},
|
||||
sharedInstanceReviewDescription: {
|
||||
id: 'app.instance.admonitions.shared-instance.review-description',
|
||||
defaultMessage:
|
||||
'Review the content changes that will be shared with everyone using this instance.',
|
||||
},
|
||||
sharedInstanceAddedLabel: {
|
||||
id: 'app.instance.admonitions.shared-instance.added-label',
|
||||
defaultMessage: 'Added',
|
||||
},
|
||||
sharedInstanceRemovedLabel: {
|
||||
id: 'app.instance.admonitions.shared-instance.removed-label',
|
||||
defaultMessage: 'Removed',
|
||||
},
|
||||
sharedInstanceWrongAccountHeader: {
|
||||
id: 'app.instance.shared-instance-wrong-account.warning-header',
|
||||
defaultMessage: 'You are using the wrong Modrinth account',
|
||||
},
|
||||
sharedInstanceSignedOutHeader: {
|
||||
id: 'app.instance.shared-instance-wrong-account.signed-out-header',
|
||||
defaultMessage: 'You need to sign in to Modrinth',
|
||||
},
|
||||
sharedInstanceWrongAccountSignInAs: {
|
||||
id: 'app.instance.shared-instance-wrong-account.sign-in-as-label',
|
||||
defaultMessage: 'Sign in as',
|
||||
},
|
||||
sharedInstanceWrongAccountUserBody: {
|
||||
id: 'app.instance.shared-instance-wrong-account.user-admonition-body-v2',
|
||||
defaultMessage: 'to receive updates for this shared instance.',
|
||||
},
|
||||
sharedInstanceWrongAccountOwnerBody: {
|
||||
id: 'app.instance.shared-instance-wrong-account.owner-admonition-body-v2',
|
||||
defaultMessage: "to manage this shared instance. You won't be able to push updates to users.",
|
||||
},
|
||||
sharedInstanceWrongAccountFallbackUsername: {
|
||||
id: 'app.instance.shared-instance-wrong-account.fallback-username',
|
||||
defaultMessage: 'the linked account',
|
||||
},
|
||||
})
|
||||
+66
@@ -0,0 +1,66 @@
|
||||
<template>
|
||||
<Admonition
|
||||
type="info"
|
||||
inline-actions
|
||||
:header="formatMessage(messages.sharedInstanceChangesHeader)"
|
||||
>
|
||||
{{ formatMessage(messages.sharedInstanceChangesBody) }}
|
||||
<template #actions>
|
||||
<ButtonStyled color="blue">
|
||||
<button class="!h-10" :disabled="isPublishButtonDisabled" @click="reviewChanges">
|
||||
<SpinnerIcon
|
||||
v-if="isReviewingPublish || isPublishing"
|
||||
class="animate-spin"
|
||||
aria-hidden="true"
|
||||
/>
|
||||
<UploadIcon v-else aria-hidden="true" />
|
||||
{{
|
||||
isPublishing
|
||||
? formatMessage(messages.sharedInstancePublishingButton)
|
||||
: isReviewingPublish
|
||||
? formatMessage(messages.sharedInstanceReviewingButton)
|
||||
: formatMessage(messages.sharedInstancePublishButton)
|
||||
}}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</template>
|
||||
</Admonition>
|
||||
|
||||
<SharedInstancePublishModal
|
||||
ref="publishModal"
|
||||
:instance="instance"
|
||||
@published="emit('published')"
|
||||
@state-change="publishState = $event"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SpinnerIcon, UploadIcon } from '@modrinth/assets'
|
||||
import { Admonition, ButtonStyled, useVIntl } from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import SharedInstancePublishModal from '@/components/ui/shared-instances/SharedInstancePublishModal.vue'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
|
||||
import { instanceAdmonitionsMessages as messages } from './instance-admonitions-messages'
|
||||
|
||||
defineProps<{
|
||||
instance: GameInstance
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
published: []
|
||||
}>()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const publishModal = ref<InstanceType<typeof SharedInstancePublishModal>>()
|
||||
const publishState = ref<'idle' | 'reviewing' | 'publishing'>('idle')
|
||||
const isPublishing = computed(() => publishState.value === 'publishing')
|
||||
const isReviewingPublish = computed(() => publishState.value === 'reviewing')
|
||||
|
||||
const isPublishButtonDisabled = computed(() => isPublishing.value || isReviewingPublish.value)
|
||||
|
||||
function reviewChanges(e?: MouseEvent) {
|
||||
publishModal.value?.show(e)
|
||||
}
|
||||
</script>
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
<template>
|
||||
<Admonition
|
||||
type="warning"
|
||||
:inline-actions="reason === 'quarantined'"
|
||||
:header="formatMessage(sharedInstanceUnavailableTitleMessage(reason ?? null))"
|
||||
:dismissible="dismissible"
|
||||
@dismiss="emit('dismiss')"
|
||||
>
|
||||
{{ formatSharedInstanceUnavailable(reason ?? null, manager) }}
|
||||
<template v-if="reason === 'quarantined'" #actions>
|
||||
<ButtonStyled color="orange">
|
||||
<button class="!h-10" @click="emit('delete')">
|
||||
<TrashIcon aria-hidden="true" />
|
||||
{{ formatMessage(messages.deleteInstance) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</template>
|
||||
</Admonition>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { TrashIcon } from '@modrinth/assets'
|
||||
import { Admonition, ButtonStyled, defineMessages, useVIntl } from '@modrinth/ui'
|
||||
|
||||
import type { SharedInstanceUnavailableReason } from '@/helpers/install'
|
||||
import {
|
||||
sharedInstanceUnavailableTitleMessage,
|
||||
useSharedInstanceErrors,
|
||||
} from '@/helpers/shared-instance-errors'
|
||||
|
||||
defineProps<{
|
||||
reason?: SharedInstanceUnavailableReason | null
|
||||
manager?: string | null
|
||||
dismissible?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
dismiss: []
|
||||
delete: []
|
||||
}>()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const { formatSharedInstanceUnavailable } = useSharedInstanceErrors()
|
||||
|
||||
const messages = defineMessages({
|
||||
deleteInstance: {
|
||||
id: 'instance.locked.delete-button',
|
||||
defaultMessage: 'Delete instance',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
<template>
|
||||
<Admonition type="warning" :header="formatMessage(headerMessage)">
|
||||
<span class="flex flex-wrap items-center gap-x-1.5 gap-y-1">
|
||||
<span>{{ formatMessage(messages.sharedInstanceWrongAccountSignInAs) }}</span>
|
||||
<span
|
||||
v-if="sharedInstanceExpectedUser"
|
||||
class="inline-flex max-w-full min-w-0 items-center gap-1.5 align-middle font-semibold text-contrast"
|
||||
>
|
||||
<Avatar
|
||||
:src="sharedInstanceExpectedUser.avatarUrl"
|
||||
:alt="sharedInstanceExpectedUsername"
|
||||
:tint-by="sharedInstanceExpectedUser.tintBy"
|
||||
size="20px"
|
||||
circle
|
||||
no-shadow
|
||||
/>
|
||||
<span class="min-w-0 truncate">{{ sharedInstanceExpectedUsername }}</span>
|
||||
</span>
|
||||
<span v-else class="font-semibold">{{ sharedInstanceExpectedUsername }}</span>
|
||||
<span>{{ formatMessage(bodyMessage) }}</span>
|
||||
</span>
|
||||
</Admonition>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { Admonition, Avatar, useVIntl } from '@modrinth/ui'
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
import { computed } from 'vue'
|
||||
|
||||
import { get_user } from '@/helpers/cache'
|
||||
|
||||
import { instanceAdmonitionsMessages as messages } from './instance-admonitions-messages'
|
||||
import type { SharedInstanceRole } from './types'
|
||||
|
||||
const props = defineProps<{
|
||||
expectedUserId?: string | null
|
||||
role?: SharedInstanceRole | null
|
||||
signedOut?: boolean
|
||||
}>()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const expectedUserId = computed(() => props.expectedUserId ?? null)
|
||||
const expectedUserQuery = useQuery({
|
||||
queryKey: computed(() => ['user', expectedUserId.value]),
|
||||
queryFn: async () => {
|
||||
if (!expectedUserId.value) return null
|
||||
|
||||
return await get_user(expectedUserId.value, 'bypass').catch(() => null)
|
||||
},
|
||||
enabled: () => !!expectedUserId.value,
|
||||
staleTime: 30_000,
|
||||
})
|
||||
const sharedInstanceExpectedUser = computed(() => {
|
||||
const user = expectedUserQuery.data.value
|
||||
if (!user) return null
|
||||
|
||||
return {
|
||||
username: user.username,
|
||||
avatarUrl: user.avatar_url ?? undefined,
|
||||
tintBy: user.id,
|
||||
}
|
||||
})
|
||||
const sharedInstanceExpectedUsername = computed(
|
||||
() =>
|
||||
sharedInstanceExpectedUser.value?.username ||
|
||||
formatMessage(messages.sharedInstanceWrongAccountFallbackUsername),
|
||||
)
|
||||
const headerMessage = computed(() =>
|
||||
props.signedOut
|
||||
? messages.sharedInstanceSignedOutHeader
|
||||
: messages.sharedInstanceWrongAccountHeader,
|
||||
)
|
||||
const bodyMessage = computed(() =>
|
||||
props.role === 'owner'
|
||||
? messages.sharedInstanceWrongAccountOwnerBody
|
||||
: messages.sharedInstanceWrongAccountUserBody,
|
||||
)
|
||||
</script>
|
||||
@@ -0,0 +1,12 @@
|
||||
import type { StackedAdmonitionItem } from '@modrinth/ui'
|
||||
|
||||
export type InstanceAdmonitionKind =
|
||||
| 'shared-instance-stale'
|
||||
| 'shared-instance-unavailable'
|
||||
| 'shared-instance-wrong-account'
|
||||
|
||||
export type InstanceAdmonitionItem = StackedAdmonitionItem & {
|
||||
kind: InstanceAdmonitionKind
|
||||
}
|
||||
|
||||
export type SharedInstanceRole = 'owner' | 'member'
|
||||
@@ -7,7 +7,6 @@ import {
|
||||
injectFilePicker,
|
||||
injectNotificationManager,
|
||||
InstallationSettingsLayout,
|
||||
provideAppBackup,
|
||||
provideInstallationSettings,
|
||||
useDebugLogger,
|
||||
useVIntl,
|
||||
@@ -16,24 +15,25 @@ import type { GameVersionTag, PlatformTag } from '@modrinth/utils'
|
||||
import { useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import SharedInstanceInstallationSettingsControls from '@/components/ui/shared-instances/SharedInstanceInstallationSettingsControls.vue'
|
||||
import { useManagedContentPolicy } from '@/composables/instances/use-managed-content-policy'
|
||||
import { trackEvent } from '@/helpers/analytics'
|
||||
import { get_project_versions, get_version } from '@/helpers/cache'
|
||||
import {
|
||||
install_duplicate_instance,
|
||||
install_existing_instance,
|
||||
install_pack_to_existing_instance,
|
||||
installJobInstanceId,
|
||||
wait_for_install_job,
|
||||
} from '@/helpers/install'
|
||||
import {
|
||||
edit,
|
||||
get_linked_modpack_info,
|
||||
list,
|
||||
unlink_shared_instance,
|
||||
update_managed_modrinth_version,
|
||||
update_repair_modrinth,
|
||||
} from '@/helpers/instance'
|
||||
import { get_loader_versions } from '@/helpers/metadata'
|
||||
import { get_game_versions, get_loaders } from '@/helpers/tags'
|
||||
import { provideInstanceBackup } from '@/providers/instance-backup'
|
||||
import { injectInstanceSettings } from '@/providers/instance-settings'
|
||||
import { useTheming } from '@/store/state'
|
||||
|
||||
@@ -47,6 +47,7 @@ const debug = useDebugLogger('AppInstallationSettings')
|
||||
const themeStore = useTheming()
|
||||
|
||||
const { instance, offline, isMinecraftServer, onUnlinked, closeModal } = injectInstanceSettings()
|
||||
const managedContentPolicy = useManagedContentPolicy(instance)
|
||||
const skipNonEssentialWarnings = computed(() =>
|
||||
themeStore.getFeatureFlag('skip_non_essential_warnings'),
|
||||
)
|
||||
@@ -111,9 +112,14 @@ debug('metadata queries configured', {
|
||||
const isModrinthLinkedModpack = computed(
|
||||
() =>
|
||||
instance.value.link?.type === 'modrinth_modpack' ||
|
||||
instance.value.link?.type === 'server_project_modpack',
|
||||
instance.value.link?.type === 'server_project_modpack' ||
|
||||
(instance.value.link?.type === 'shared_instance' &&
|
||||
!!instance.value.link.modpack_project_id &&
|
||||
!!instance.value.link.modpack_version_id),
|
||||
)
|
||||
const isImportedModpack = computed(() => instance.value.link?.type === 'imported_modpack')
|
||||
const isSharedInstanceManagedModpack = managedContentPolicy.isManagedModpack
|
||||
const canUnlinkSharedInstance = managedContentPolicy.canUnlink
|
||||
|
||||
const modpackInfoQuery = useQuery({
|
||||
queryKey: computed(() => ['linkedModpackInfo', instance.value.id]),
|
||||
@@ -124,12 +130,43 @@ const modpackInfo = modpackInfoQuery.data
|
||||
|
||||
const repairing = ref(false)
|
||||
const reinstalling = ref(false)
|
||||
const unlinkingSharedInstance = ref(false)
|
||||
const installationSettingsBusy = computed(
|
||||
() =>
|
||||
instance.value.quarantined ||
|
||||
instance.value.install_stage !== 'installed' ||
|
||||
repairing.value ||
|
||||
reinstalling.value ||
|
||||
unlinkingSharedInstance.value ||
|
||||
!!offline,
|
||||
)
|
||||
const installationSettingsBusyMessage = computed(() =>
|
||||
instance.value.quarantined ? formatMessage(messages.locked) : null,
|
||||
)
|
||||
|
||||
async function unlinkSharedInstance() {
|
||||
unlinkingSharedInstance.value = true
|
||||
try {
|
||||
await unlink_shared_instance(instance.value.id)
|
||||
await queryClient.invalidateQueries({ queryKey: ['sharedInstanceUsers', instance.value.id] })
|
||||
await queryClient.invalidateQueries({ queryKey: ['linkedModpackInfo', instance.value.id] })
|
||||
onUnlinked()
|
||||
} catch (error) {
|
||||
handleError(error)
|
||||
} finally {
|
||||
unlinkingSharedInstance.value = false
|
||||
}
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
loaderVersion: {
|
||||
id: 'instance.settings.tabs.installation.loader-version',
|
||||
defaultMessage: '{loader} version',
|
||||
},
|
||||
locked: {
|
||||
id: 'instance.settings.tabs.installation.locked',
|
||||
defaultMessage: 'Installation settings are unavailable while this instance is locked.',
|
||||
},
|
||||
})
|
||||
|
||||
function getManifest(loader: string) {
|
||||
@@ -162,27 +199,7 @@ async function installLocalModpackFromPicker() {
|
||||
return !!completed
|
||||
}
|
||||
|
||||
provideAppBackup({
|
||||
async createBackup() {
|
||||
debug('createBackup: start', {
|
||||
instanceId: instance.value.id,
|
||||
instanceName: instance.value.name,
|
||||
})
|
||||
const allInstances = await list()
|
||||
const prefix = `${instance.value.name} - Backup #`
|
||||
const existingNums = allInstances
|
||||
.filter((p) => p.name.startsWith(prefix))
|
||||
.map((p) => parseInt(p.name.slice(prefix.length), 10))
|
||||
.filter((n) => !isNaN(n))
|
||||
const nextNum = existingNums.length > 0 ? Math.max(...existingNums) + 1 : 1
|
||||
const job = await install_duplicate_instance(instance.value.id)
|
||||
const newInstanceId = installJobInstanceId(job)
|
||||
if (newInstanceId) {
|
||||
await edit(newInstanceId, { name: `${prefix}${nextNum}` })
|
||||
}
|
||||
debug('createBackup: done', { newInstanceId, backupName: `${prefix}${nextNum}` })
|
||||
},
|
||||
})
|
||||
provideInstanceBackup(instance)
|
||||
|
||||
provideInstallationSettings({
|
||||
closeSettings: closeModal,
|
||||
@@ -208,14 +225,14 @@ provideInstallationSettings({
|
||||
}
|
||||
return rows
|
||||
}),
|
||||
isLinked: computed(() => isModrinthLinkedModpack.value || isImportedModpack.value),
|
||||
isBusy: computed(
|
||||
isLinked: computed(
|
||||
() =>
|
||||
instance.value.install_stage !== 'installed' ||
|
||||
repairing.value ||
|
||||
reinstalling.value ||
|
||||
!!offline,
|
||||
isModrinthLinkedModpack.value ||
|
||||
isImportedModpack.value ||
|
||||
isSharedInstanceManagedModpack.value,
|
||||
),
|
||||
isBusy: installationSettingsBusy,
|
||||
busyMessage: installationSettingsBusyMessage,
|
||||
skipNonEssentialWarnings,
|
||||
modpack: computed(() => {
|
||||
if (isImportedModpack.value && instance.value.link?.type === 'imported_modpack') {
|
||||
@@ -452,14 +469,28 @@ provideInstallationSettings({
|
||||
isServer: false,
|
||||
isApp: true,
|
||||
showModpackVersionActions: computed(
|
||||
() => isModrinthLinkedModpack.value && !isMinecraftServer.value,
|
||||
() =>
|
||||
isModrinthLinkedModpack.value &&
|
||||
!isMinecraftServer.value &&
|
||||
!isSharedInstanceManagedModpack.value,
|
||||
),
|
||||
isLocalFile: isImportedModpack,
|
||||
isManagedModpack: isSharedInstanceManagedModpack,
|
||||
managedModpackWarning: managedContentPolicy.managedModpackWarning,
|
||||
repairing,
|
||||
reinstalling,
|
||||
})
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<InstallationSettingsLayout />
|
||||
<InstallationSettingsLayout>
|
||||
<template #extra>
|
||||
<SharedInstanceInstallationSettingsControls
|
||||
:can-unlink="canUnlinkSharedInstance"
|
||||
:busy="installationSettingsBusy"
|
||||
:unlinking="unlinkingSharedInstance"
|
||||
:unlink="unlinkSharedInstance"
|
||||
/>
|
||||
</template>
|
||||
</InstallationSettingsLayout>
|
||||
</template>
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
<template>
|
||||
<div>
|
||||
<SharedInstanceInstallationSettingsControls
|
||||
can-unpublish
|
||||
:busy="isBusy"
|
||||
:unpublishing="unpublishing"
|
||||
:unpublish="unpublishSharedInstance"
|
||||
/>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { injectNotificationManager } from '@modrinth/ui'
|
||||
import { useQueryClient } from '@tanstack/vue-query'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import SharedInstanceInstallationSettingsControls from '@/components/ui/shared-instances/SharedInstanceInstallationSettingsControls.vue'
|
||||
import { unpublish_shared_instance } from '@/helpers/instance'
|
||||
import { injectInstanceSettings } from '@/providers/instance-settings'
|
||||
|
||||
const { instance, offline, onUnlinked } = injectInstanceSettings()
|
||||
const { handleError } = injectNotificationManager()
|
||||
const queryClient = useQueryClient()
|
||||
const unpublishing = ref(false)
|
||||
const isBusy = computed(
|
||||
() => instance.value.install_stage !== 'installed' || unpublishing.value || !!offline,
|
||||
)
|
||||
|
||||
async function unpublishSharedInstance() {
|
||||
unpublishing.value = true
|
||||
try {
|
||||
await unpublish_shared_instance(instance.value.id)
|
||||
queryClient.setQueryData(['sharedInstanceUsers', instance.value.id], [])
|
||||
await queryClient.invalidateQueries({ queryKey: ['linkedModpackInfo', instance.value.id] })
|
||||
onUnlinked()
|
||||
} catch (error) {
|
||||
handleError(error)
|
||||
} finally {
|
||||
unpublishing.value = false
|
||||
}
|
||||
}
|
||||
</script>
|
||||
@@ -1,43 +0,0 @@
|
||||
<script setup lang="ts">
|
||||
import { LogInIcon, SpinnerIcon } from '@modrinth/assets'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
|
||||
|
||||
defineProps({
|
||||
onFlowCancel: {
|
||||
type: Function,
|
||||
default() {
|
||||
return async () => {}
|
||||
},
|
||||
},
|
||||
})
|
||||
|
||||
const modal = ref()
|
||||
|
||||
function show() {
|
||||
modal.value.show()
|
||||
}
|
||||
|
||||
function hide() {
|
||||
modal.value.hide()
|
||||
}
|
||||
|
||||
defineExpose({ show, hide })
|
||||
</script>
|
||||
<template>
|
||||
<ModalWrapper ref="modal" @hide="onFlowCancel">
|
||||
<template #title>
|
||||
<span class="items-center gap-2 text-lg font-extrabold text-contrast">
|
||||
<LogInIcon /> Sign in
|
||||
</span>
|
||||
</template>
|
||||
|
||||
<div class="flex justify-center gap-2">
|
||||
<SpinnerIcon class="w-12 h-12 animate-spin" />
|
||||
</div>
|
||||
<p class="text-sm text-secondary">
|
||||
Please sign in at the browser window that just opened to continue.
|
||||
</p>
|
||||
</ModalWrapper>
|
||||
</template>
|
||||
@@ -4,8 +4,8 @@
|
||||
:header="formatMessage(messages.installToPlay)"
|
||||
:closable="true"
|
||||
:on-hide="show_ads_window"
|
||||
max-width="640px"
|
||||
width="640px"
|
||||
max-width="544px"
|
||||
width="544px"
|
||||
>
|
||||
<div v-if="requiredContentProject" class="flex w-full flex-col gap-6">
|
||||
<p class="m-0 text-primary">
|
||||
@@ -423,8 +423,8 @@ const messages = defineMessages({
|
||||
defaultMessage: 'Install anyway',
|
||||
},
|
||||
dontInstall: {
|
||||
id: 'app.modal.install-to-play.dont-install',
|
||||
defaultMessage: 'Dont install',
|
||||
id: 'app.modal.install-to-play.external-files-dont-install',
|
||||
defaultMessage: "Don't install",
|
||||
},
|
||||
})
|
||||
|
||||
|
||||
@@ -6,6 +6,7 @@ import {
|
||||
CoffeeIcon,
|
||||
InfoIcon,
|
||||
MonitorIcon,
|
||||
UsersIcon,
|
||||
WrenchIcon,
|
||||
} from '@modrinth/assets'
|
||||
import {
|
||||
@@ -25,6 +26,7 @@ import GeneralSettings from '@/components/ui/instance_settings/GeneralSettings.v
|
||||
import HooksSettings from '@/components/ui/instance_settings/HooksSettings.vue'
|
||||
import InstallationSettings from '@/components/ui/instance_settings/InstallationSettings.vue'
|
||||
import JavaSettings from '@/components/ui/instance_settings/JavaSettings.vue'
|
||||
import SharingSettings from '@/components/ui/instance_settings/SharingSettings.vue'
|
||||
import WindowSettings from '@/components/ui/instance_settings/WindowSettings.vue'
|
||||
import { get_project_v3 } from '@/helpers/cache'
|
||||
import { get_linked_modpack_info } from '@/helpers/instance'
|
||||
@@ -97,6 +99,15 @@ const tabs = computed<TabbedModalTab[]>(() => [
|
||||
icon: WrenchIcon,
|
||||
content: InstallationSettings,
|
||||
},
|
||||
{
|
||||
name: defineMessage({
|
||||
id: 'instance.settings.tabs.sharing',
|
||||
defaultMessage: 'Sharing',
|
||||
}),
|
||||
icon: UsersIcon,
|
||||
content: SharingSettings,
|
||||
shown: props.instance.shared_instance?.role === 'owner' && !props.instance.quarantined,
|
||||
},
|
||||
{
|
||||
name: defineMessage({
|
||||
id: 'instance.settings.tabs.window',
|
||||
|
||||
@@ -0,0 +1,265 @@
|
||||
<template>
|
||||
<NewModal
|
||||
ref="modal"
|
||||
:header="formatMessage(authenticating ? messages.signingInHeader : messages.header)"
|
||||
:on-hide="handleHide"
|
||||
no-padding
|
||||
max-width="548px"
|
||||
width="100%"
|
||||
>
|
||||
<div v-if="authenticating === null" class="flex w-full flex-col gap-6 p-6">
|
||||
<div class="flex flex-col gap-2 px-3">
|
||||
<h2 class="m-0 text-xl font-semibold leading-7 text-contrast">
|
||||
{{ formatMessage(messages.signInHeading) }}
|
||||
</h2>
|
||||
<p class="m-0 text-base leading-6 text-primary">
|
||||
{{ formatMessage(messages.description) }}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-6">
|
||||
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
|
||||
<ButtonStyled>
|
||||
<button class="w-full !shadow-none" type="button" @click="authenticate('sign-up')">
|
||||
<UserPlusIcon aria-hidden="true" />
|
||||
{{ formatMessage(messages.createAccountButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled color="brand">
|
||||
<button class="w-full" type="button" @click="authenticate('sign-in')">
|
||||
<LogInIcon aria-hidden="true" />
|
||||
{{ formatMessage(messages.signInButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
|
||||
<p class="m-0 text-center text-base font-medium leading-6 text-primary">
|
||||
<IntlFormatted :message-id="messages.supportPrompt">
|
||||
<template #support="{ children }">
|
||||
<button
|
||||
type="button"
|
||||
class="inline cursor-pointer border-0 bg-transparent p-0 text-base font-medium leading-6 text-blue hover:underline"
|
||||
@click="openSupport"
|
||||
>
|
||||
<component :is="() => children" />
|
||||
</button>
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div v-else class="flex w-full flex-col gap-6 p-6">
|
||||
<div class="flex flex-col gap-2.5 px-3">
|
||||
<div class="flex flex-col gap-2">
|
||||
<h2 class="m-0 text-xl font-semibold leading-7 text-contrast">
|
||||
{{ formatMessage(messages.continueInBrowserHeading) }}
|
||||
</h2>
|
||||
<p class="m-0 text-base leading-6 text-primary">
|
||||
{{ formatMessage(messages.browserDescription) }}
|
||||
</p>
|
||||
</div>
|
||||
<div class="flex items-center gap-1.5 text-primary">
|
||||
<SpinnerIcon aria-hidden="true" class="h-5 w-5 shrink-0 animate-spin" />
|
||||
<span class="text-base leading-6">
|
||||
{{ formatMessage(messages.waitingForBrowser) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex flex-col gap-6">
|
||||
<div class="grid grid-cols-1 gap-2 sm:grid-cols-2">
|
||||
<ButtonStyled type="outlined">
|
||||
<button class="w-full" type="button" @click="modal?.hide()">
|
||||
<XIcon aria-hidden="true" />
|
||||
{{ formatMessage(messages.cancelButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled>
|
||||
<button
|
||||
class="w-full !shadow-none"
|
||||
type="button"
|
||||
:disabled="reopeningBrowser"
|
||||
@click="reopenBrowser"
|
||||
>
|
||||
<RefreshCwIcon aria-hidden="true" />
|
||||
{{ formatMessage(messages.openBrowserAgainButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
|
||||
<p class="m-0 text-center text-base font-medium leading-6 text-primary">
|
||||
<IntlFormatted :message-id="messages.supportPrompt">
|
||||
<template #support="{ children }">
|
||||
<button
|
||||
type="button"
|
||||
class="inline cursor-pointer border-0 bg-transparent p-0 text-base font-medium leading-6 text-blue hover:underline"
|
||||
@click="openSupport"
|
||||
>
|
||||
<component :is="() => children" />
|
||||
</button>
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</NewModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { LogInIcon, RefreshCwIcon, SpinnerIcon, UserPlusIcon, XIcon } from '@modrinth/assets'
|
||||
import { ButtonStyled, defineMessages, IntlFormatted, NewModal, useVIntl } from '@modrinth/ui'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import { ref } from 'vue'
|
||||
|
||||
import { cancelLogin, type ModrinthAuthFlow } from '@/helpers/mr_auth'
|
||||
|
||||
const props = defineProps<{
|
||||
requestAuth: (flow: ModrinthAuthFlow) => Promise<boolean>
|
||||
}>()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const authenticating = ref<ModrinthAuthFlow | null>(null)
|
||||
const reopeningBrowser = ref(false)
|
||||
let resolveShow: ((signedIn: boolean) => void) | undefined
|
||||
let authenticationId = 0
|
||||
let activeAuthentication: Promise<void> | undefined
|
||||
|
||||
function show(event?: MouseEvent) {
|
||||
resetAuthentication(true)
|
||||
resolveShow?.(false)
|
||||
const modalInstance = modal.value
|
||||
if (!modalInstance) return Promise.resolve(false)
|
||||
|
||||
return new Promise<boolean>((resolve) => {
|
||||
resolveShow = resolve
|
||||
modalInstance.show(event)
|
||||
})
|
||||
}
|
||||
|
||||
function showSigningIn(flow: ModrinthAuthFlow = 'sign-in', event?: MouseEvent) {
|
||||
const result = show(event)
|
||||
authenticate(flow)
|
||||
return result
|
||||
}
|
||||
|
||||
function finish(signedIn: boolean) {
|
||||
resolveShow?.(signedIn)
|
||||
resolveShow = undefined
|
||||
}
|
||||
|
||||
function authenticate(flow: ModrinthAuthFlow) {
|
||||
const id = ++authenticationId
|
||||
authenticating.value = flow
|
||||
|
||||
const authentication = (async () => {
|
||||
try {
|
||||
if ((await props.requestAuth(flow)) && authenticationId === id) {
|
||||
authenticating.value = null
|
||||
activeAuthentication = undefined
|
||||
finish(true)
|
||||
modal.value?.hide()
|
||||
}
|
||||
} finally {
|
||||
if (authenticationId === id) {
|
||||
authenticating.value = null
|
||||
activeAuthentication = undefined
|
||||
}
|
||||
}
|
||||
})()
|
||||
|
||||
activeAuthentication = authentication
|
||||
}
|
||||
|
||||
async function reopenBrowser() {
|
||||
const flow = authenticating.value
|
||||
if (!flow || reopeningBrowser.value) return
|
||||
|
||||
reopeningBrowser.value = true
|
||||
const previousAuthentication = activeAuthentication
|
||||
++authenticationId
|
||||
|
||||
try {
|
||||
await cancelLogin()
|
||||
await previousAuthentication?.catch(() => undefined)
|
||||
if (authenticating.value === flow) authenticate(flow)
|
||||
} finally {
|
||||
reopeningBrowser.value = false
|
||||
}
|
||||
}
|
||||
|
||||
function resetAuthentication(cancelActive: boolean) {
|
||||
const wasAuthenticating = authenticating.value !== null
|
||||
++authenticationId
|
||||
activeAuthentication = undefined
|
||||
authenticating.value = null
|
||||
reopeningBrowser.value = false
|
||||
|
||||
if (cancelActive && wasAuthenticating) void cancelLogin()
|
||||
}
|
||||
|
||||
function handleHide() {
|
||||
resetAuthentication(true)
|
||||
finish(false)
|
||||
}
|
||||
|
||||
function openSupport() {
|
||||
openUrl('https://support.modrinth.com')
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
header: {
|
||||
id: 'modal.modrinth-account-required.header',
|
||||
defaultMessage: 'Account required',
|
||||
},
|
||||
signingInHeader: {
|
||||
id: 'modal.modrinth-account-required.signing-in-header',
|
||||
defaultMessage: 'Signing in',
|
||||
},
|
||||
signInHeading: {
|
||||
id: 'modal.modrinth-account-required.sign-in-heading',
|
||||
defaultMessage: 'Sign in to a Modrinth account',
|
||||
},
|
||||
description: {
|
||||
id: 'modal.modrinth-account-required.description',
|
||||
defaultMessage:
|
||||
"You'll need to sign into your Modrinth account before you can use this feature.",
|
||||
},
|
||||
createAccountButton: {
|
||||
id: 'modal.modrinth-account-required.create-account-button',
|
||||
defaultMessage: 'Create an account',
|
||||
},
|
||||
signInButton: {
|
||||
id: 'modal.modrinth-account-required.sign-in-button',
|
||||
defaultMessage: 'Sign in to Modrinth',
|
||||
},
|
||||
continueInBrowserHeading: {
|
||||
id: 'modal.modrinth-account-required.continue-in-browser-heading',
|
||||
defaultMessage: 'Continue in your browser',
|
||||
},
|
||||
browserDescription: {
|
||||
id: 'modal.modrinth-account-required.browser-description',
|
||||
defaultMessage:
|
||||
'A new tab opened to sign in. Complete the sign in there, then return to the app.',
|
||||
},
|
||||
waitingForBrowser: {
|
||||
id: 'modal.modrinth-account-required.waiting-for-browser',
|
||||
defaultMessage: 'Waiting for browser confirmation...',
|
||||
},
|
||||
cancelButton: {
|
||||
id: 'modal.modrinth-account-required.cancel-button',
|
||||
defaultMessage: 'Cancel',
|
||||
},
|
||||
openBrowserAgainButton: {
|
||||
id: 'modal.modrinth-account-required.open-browser-again-button',
|
||||
defaultMessage: 'Open browser again',
|
||||
},
|
||||
supportPrompt: {
|
||||
id: 'modal.modrinth-account-required.support-prompt',
|
||||
defaultMessage: 'Having trouble signing in? <support>Get support</support>',
|
||||
},
|
||||
})
|
||||
|
||||
defineExpose({ show, showSigningIn })
|
||||
</script>
|
||||
@@ -8,6 +8,7 @@
|
||||
:diffs="normalizedDiffs"
|
||||
:version-date="versionDate"
|
||||
:show-external-warnings="showExternalWarnings"
|
||||
:external-warning-description="formatMessage(messages.externalWarningDescription)"
|
||||
:confirm-label="formatMessage(commonMessages.updateButton)"
|
||||
:confirm-icon="DownloadIcon"
|
||||
:removed-label="formatMessage(messages.removed)"
|
||||
@@ -76,10 +77,15 @@ const { formatMessage } = useVIntl()
|
||||
const { startInstallingServer, stopInstallingServer } = injectServerInstall()
|
||||
type UpdateCompleteCallback = () => void | Promise<void>
|
||||
|
||||
defineProps<{
|
||||
const { showExternalWarnings } = defineProps<{
|
||||
showExternalWarnings?: boolean
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
cancel: []
|
||||
complete: []
|
||||
}>()
|
||||
|
||||
const diffModal = ref<InstanceType<typeof ContentDiffModal>>()
|
||||
const instance = ref<GameInstance | null>(null)
|
||||
const onUpdateComplete = ref<UpdateCompleteCallback>(() => {})
|
||||
@@ -87,16 +93,16 @@ const diffs = ref<DependencyDiff[]>([])
|
||||
const modpackVersionId = ref<string | null>(null)
|
||||
const modpackVersion = ref<Version | null>(null)
|
||||
|
||||
const normalizedDiffs = computed<ContentDiffItem[]>(() =>
|
||||
diffs.value.map((diff) => ({
|
||||
const normalizedDiffs = computed<ContentDiffItem[]>(() => {
|
||||
return diffs.value.map((diff) => ({
|
||||
type: diff.type,
|
||||
external: Boolean(diff.fileName && !diff.project),
|
||||
projectName: diff.project?.title,
|
||||
fileName: diff.fileName,
|
||||
currentVersionName: diff.currentVersion?.version_number,
|
||||
newVersionName: diff.newVersion?.version_number,
|
||||
})),
|
||||
)
|
||||
}))
|
||||
})
|
||||
|
||||
const versionDate = computed(() =>
|
||||
modpackVersion.value?.date_published
|
||||
@@ -242,7 +248,6 @@ async function checkUpdateAvailable(inst: GameInstance): Promise<DependencyDiff[
|
||||
}
|
||||
|
||||
async function handleUpdate() {
|
||||
hide()
|
||||
const serverProjectId = instance.value?.link?.project_id
|
||||
if (serverProjectId) startInstallingServer(serverProjectId)
|
||||
try {
|
||||
@@ -255,11 +260,12 @@ async function handleUpdate() {
|
||||
console.error('Error updating instance:', error)
|
||||
} finally {
|
||||
if (serverProjectId) stopInstallingServer(serverProjectId)
|
||||
emit('complete')
|
||||
}
|
||||
}
|
||||
|
||||
function handleDecline() {
|
||||
hide()
|
||||
emit('cancel')
|
||||
}
|
||||
|
||||
function show(
|
||||
@@ -293,12 +299,17 @@ const messages = defineMessages({
|
||||
updateRequiredDescription: {
|
||||
id: 'app.modal.update-to-play.update-required-description',
|
||||
defaultMessage:
|
||||
'An update is required to play {name}. Please update to the latest version to launch the game.',
|
||||
'An update is required to play {name}. Please update to latest version to launch the game.',
|
||||
},
|
||||
removed: {
|
||||
id: 'app.modal.update-to-play.removed',
|
||||
defaultMessage: 'Removed',
|
||||
},
|
||||
externalWarningDescription: {
|
||||
id: 'app.modal.update-to-play.server-modpack-unknown-files-description',
|
||||
defaultMessage:
|
||||
'This server modpack update contains files that aren’t published on Modrinth. We strongly recommend only installing files from sources you trust.',
|
||||
},
|
||||
})
|
||||
|
||||
const hasUpdate = computed(() => {
|
||||
|
||||
+100
@@ -0,0 +1,100 @@
|
||||
<template>
|
||||
<NewModal ref="modal" :header="formatMessage(messages.header)" fade="warning" max-width="500px">
|
||||
<p class="m-0 text-secondary">
|
||||
<IntlFormatted :message-id="messages.body" :values="{ instanceName }">
|
||||
<template #bold="{ children }">
|
||||
<span class="font-medium text-contrast"><component :is="() => children" /></span>
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</p>
|
||||
|
||||
<template #actions>
|
||||
<div class="flex justify-end gap-2">
|
||||
<ButtonStyled type="outlined">
|
||||
<button @click="handleCancel">
|
||||
<XIcon />
|
||||
{{ formatMessage(commonMessages.cancelButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled>
|
||||
<button @click="handleGoToInstance">
|
||||
{{ formatMessage(messages.instance) }}
|
||||
<RightArrowIcon />
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled color="orange">
|
||||
<button @click="handleInstallAnyway">
|
||||
<DownloadIcon />
|
||||
{{ formatMessage(messages.installAnyway) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DownloadIcon, RightArrowIcon, XIcon } from '@modrinth/assets'
|
||||
import {
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
IntlFormatted,
|
||||
NewModal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
|
||||
const messages = defineMessages({
|
||||
header: {
|
||||
id: 'app.instance.shared-instance-already-installed.header',
|
||||
defaultMessage: 'Shared instance already installed',
|
||||
},
|
||||
body: {
|
||||
id: 'app.instance.shared-instance-already-installed.body',
|
||||
defaultMessage:
|
||||
'This shared instance is already installed as <bold>{instanceName}</bold>. Are you sure you want to install another copy?',
|
||||
},
|
||||
instance: {
|
||||
id: 'app.instance.shared-instance-already-installed.instance',
|
||||
defaultMessage: 'Instance',
|
||||
},
|
||||
installAnyway: {
|
||||
id: 'app.instance.shared-instance-already-installed.install-anyway',
|
||||
defaultMessage: 'Install anyway',
|
||||
},
|
||||
})
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: 'cancel' | 'go-to-instance' | 'install-anyway'): void
|
||||
}>()
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const instanceName = ref('')
|
||||
|
||||
function show(name: string) {
|
||||
instanceName.value = name
|
||||
modal.value?.show()
|
||||
}
|
||||
|
||||
function handleCancel() {
|
||||
modal.value?.hide()
|
||||
emit('cancel')
|
||||
}
|
||||
|
||||
function handleGoToInstance() {
|
||||
modal.value?.hide()
|
||||
emit('go-to-instance')
|
||||
}
|
||||
|
||||
function handleInstallAnyway() {
|
||||
modal.value?.hide()
|
||||
emit('install-anyway')
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
show,
|
||||
})
|
||||
</script>
|
||||
+195
@@ -0,0 +1,195 @@
|
||||
<template>
|
||||
<div v-if="canUnpublish" class="flex flex-col gap-2.5">
|
||||
<span class="text-lg font-semibold text-contrast">{{ formatMessage(messages.title) }}</span>
|
||||
<div>
|
||||
<ButtonStyled color="orange">
|
||||
<button :disabled="busy" @click="unpublishModal?.show()">
|
||||
<SpinnerIcon v-if="unpublishing" class="animate-spin" />
|
||||
<UnlinkIcon v-else class="size-5" />
|
||||
{{ formatMessage(unpublishing ? messages.unpublishingButton : messages.unpublishButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
<span class="text-primary">{{ formatMessage(messages.unpublishDescription) }}</span>
|
||||
</div>
|
||||
<div v-if="canUnlink" class="flex flex-col gap-2.5">
|
||||
<span class="text-lg font-semibold text-contrast">{{
|
||||
formatMessage(messages.linkedTitle)
|
||||
}}</span>
|
||||
<div>
|
||||
<ButtonStyled color="orange">
|
||||
<button :disabled="busy" @click="unlinkModal?.show()">
|
||||
<SpinnerIcon v-if="unlinking" class="animate-spin" />
|
||||
<UnlinkIcon v-else class="size-5" />
|
||||
{{ formatMessage(unlinking ? messages.unlinkingButton : messages.unlinkButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
<span class="text-primary">{{ formatMessage(messages.unlinkDescription) }}</span>
|
||||
</div>
|
||||
|
||||
<NewModal
|
||||
ref="unpublishModal"
|
||||
:header="formatMessage(messages.unpublishModalHeader)"
|
||||
fade="warning"
|
||||
max-width="500px"
|
||||
>
|
||||
<Admonition type="warning" :header="formatMessage(messages.unpublishModalAdmonitionHeader)">{{
|
||||
formatMessage(messages.unpublishModalBody)
|
||||
}}</Admonition>
|
||||
<template #actions
|
||||
><div class="flex justify-end gap-2">
|
||||
<ButtonStyled type="outlined"
|
||||
><button class="!border" @click="unpublishModal?.hide()">
|
||||
<XIcon />{{ formatMessage(commonMessages.cancelButton) }}
|
||||
</button></ButtonStyled
|
||||
><ButtonStyled color="orange"
|
||||
><button :disabled="busy" @click="confirmUnpublish">
|
||||
<UnlinkIcon />{{ formatMessage(messages.unpublishButton) }}
|
||||
</button></ButtonStyled
|
||||
>
|
||||
</div></template
|
||||
>
|
||||
</NewModal>
|
||||
<NewModal
|
||||
ref="unlinkModal"
|
||||
:header="formatMessage(messages.unlinkModalHeader)"
|
||||
fade="warning"
|
||||
max-width="500px"
|
||||
:on-hide="() => backupCreator?.cancelBackup()"
|
||||
>
|
||||
<div class="flex flex-col gap-6">
|
||||
<Admonition type="warning" :header="formatMessage(messages.unlinkModalAdmonitionHeader)">{{
|
||||
formatMessage(messages.unlinkModalBody)
|
||||
}}</Admonition>
|
||||
<InlineBackupCreator
|
||||
ref="backupCreator"
|
||||
backup-name="Before unlinking shared instance"
|
||||
@update:buttons-disabled="backupBusy = $event"
|
||||
/>
|
||||
</div>
|
||||
<template #actions
|
||||
><div class="flex justify-end gap-2">
|
||||
<ButtonStyled type="outlined"
|
||||
><button class="!border" @click="unlinkModal?.hide()">
|
||||
<XIcon />{{ formatMessage(commonMessages.cancelButton) }}
|
||||
</button></ButtonStyled
|
||||
><ButtonStyled color="orange"
|
||||
><button :disabled="busy || backupBusy" @click="confirmUnlink">
|
||||
<UnlinkIcon />{{ formatMessage(messages.unlinkButton) }}
|
||||
</button></ButtonStyled
|
||||
>
|
||||
</div></template
|
||||
>
|
||||
</NewModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { SpinnerIcon, UnlinkIcon, XIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Admonition,
|
||||
ButtonStyled,
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
InlineBackupCreator,
|
||||
NewModal,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { ref } from 'vue'
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
canUnpublish?: boolean
|
||||
canUnlink?: boolean
|
||||
busy: boolean
|
||||
unpublishing?: boolean
|
||||
unlinking?: boolean
|
||||
unpublish?: () => Promise<void>
|
||||
unlink?: () => Promise<void>
|
||||
}>(),
|
||||
{
|
||||
canUnpublish: false,
|
||||
canUnlink: false,
|
||||
unpublishing: false,
|
||||
unlinking: false,
|
||||
unpublish: undefined,
|
||||
unlink: undefined,
|
||||
},
|
||||
)
|
||||
const { formatMessage } = useVIntl()
|
||||
const unpublishModal = ref<InstanceType<typeof NewModal>>()
|
||||
const unlinkModal = ref<InstanceType<typeof NewModal>>()
|
||||
const backupCreator = ref<InstanceType<typeof InlineBackupCreator>>()
|
||||
const backupBusy = ref(false)
|
||||
|
||||
async function confirmUnpublish() {
|
||||
unpublishModal.value?.hide()
|
||||
await props.unpublish?.()
|
||||
}
|
||||
async function confirmUnlink() {
|
||||
unlinkModal.value?.hide()
|
||||
await props.unlink?.()
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
title: {
|
||||
id: 'installation-settings.shared-instance.title',
|
||||
defaultMessage: 'Unpublish instance',
|
||||
},
|
||||
linkedTitle: {
|
||||
id: 'installation-settings.shared-instance.linked-title',
|
||||
defaultMessage: 'Linked shared instance',
|
||||
},
|
||||
unpublishButton: {
|
||||
id: 'installation-settings.shared-instance.unpublish-button',
|
||||
defaultMessage: 'Unpublish shared instance',
|
||||
},
|
||||
unpublishingButton: {
|
||||
id: 'installation-settings.shared-instance.unpublishing-button',
|
||||
defaultMessage: 'Unpublishing...',
|
||||
},
|
||||
unpublishDescription: {
|
||||
id: 'installation-settings.shared-instance.unpublish-description',
|
||||
defaultMessage:
|
||||
'Remove this shared instance from Modrinth and stop sending updates to anyone using it. Your local instance will not be affected.',
|
||||
},
|
||||
unlinkButton: {
|
||||
id: 'installation-settings.shared-instance.unlink-button',
|
||||
defaultMessage: 'Unlink shared instance',
|
||||
},
|
||||
unlinkingButton: {
|
||||
id: 'installation-settings.shared-instance.unlinking-button',
|
||||
defaultMessage: 'Unlinking...',
|
||||
},
|
||||
unlinkDescription: {
|
||||
id: 'installation-settings.shared-instance.unlink-description',
|
||||
defaultMessage: 'Disconnect this local instance from future shared updates.',
|
||||
},
|
||||
unpublishModalHeader: {
|
||||
id: 'installation-settings.unpublish-shared-instance.modal.header',
|
||||
defaultMessage: 'Unpublish shared instance',
|
||||
},
|
||||
unpublishModalAdmonitionHeader: {
|
||||
id: 'installation-settings.unpublish-shared-instance.modal.admonition-header',
|
||||
defaultMessage: 'Unpublishing shared instance',
|
||||
},
|
||||
unpublishModalBody: {
|
||||
id: 'installation-settings.unpublish-shared-instance.modal.admonition-body',
|
||||
defaultMessage:
|
||||
"This deletes the shared instance from Modrinth's servers. People using it in the Modrinth App will stop receiving updates, but your local instance and its content will stay on this device.",
|
||||
},
|
||||
unlinkModalHeader: {
|
||||
id: 'installation-settings.unlink-shared-instance.modal.header',
|
||||
defaultMessage: 'Unlink shared instance',
|
||||
},
|
||||
unlinkModalAdmonitionHeader: {
|
||||
id: 'installation-settings.unlink-shared-instance.modal.admonition-header',
|
||||
defaultMessage: 'Unlinking shared instance',
|
||||
},
|
||||
unlinkModalBody: {
|
||||
id: 'installation-settings.unlink-shared-instance.modal.admonition-body',
|
||||
defaultMessage:
|
||||
'This only affects your local instance. Your installed content will stay on this device, and the shared instance and other people using it will not be affected.',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
@@ -0,0 +1,189 @@
|
||||
<template>
|
||||
<ContentDiffModal
|
||||
ref="publishReviewModal"
|
||||
:header="formatMessage(messages.header)"
|
||||
:admonition-header="formatMessage(messages.admonitionHeader)"
|
||||
:description="formatMessage(messages.description)"
|
||||
:diffs="publishDiffs"
|
||||
:confirm-label="formatMessage(messages.publishButton)"
|
||||
:confirm-icon="UploadIcon"
|
||||
:confirm-disabled="publishDiffs.length === 0 && selectedConfigPaths.length === 0"
|
||||
:added-label="formatMessage(messages.addedLabel)"
|
||||
:removed-label="formatMessage(messages.removedLabel)"
|
||||
@confirm="publishChanges"
|
||||
@cancel="finishReview"
|
||||
>
|
||||
<template #additional-content>
|
||||
<Accordion
|
||||
class="min-w-0"
|
||||
overflow-visible
|
||||
button-class="w-full bg-transparent m-0 p-0 border-none"
|
||||
>
|
||||
<template #title>
|
||||
<FileCogIcon class="size-4 shrink-0 text-primary" />
|
||||
<span class="text-lg font-semibold text-contrast">
|
||||
{{ formatMessage(messages.configTitle) }}
|
||||
</span>
|
||||
</template>
|
||||
<div class="flex min-w-0 flex-col gap-3 pt-4">
|
||||
<div class="max-h-[292px] overflow-y-auto rounded-[20px]">
|
||||
<FileTreeSelect
|
||||
v-model="selectedConfigPaths"
|
||||
:items="configFileItems"
|
||||
:show-size="false"
|
||||
:show-modified="false"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</Accordion>
|
||||
</template>
|
||||
</ContentDiffModal>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { FileCogIcon, UploadIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Accordion,
|
||||
type ContentDiffItem,
|
||||
ContentDiffModal,
|
||||
defineMessages,
|
||||
FileTreeSelect,
|
||||
type FileTreeSelectItem,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import {
|
||||
getSharedInstanceUnavailableReason,
|
||||
isSharedInstanceUnavailableError,
|
||||
} from '@/helpers/install'
|
||||
import { get_shared_instance_publish_preview, publish_shared_instance } from '@/helpers/instance'
|
||||
import { useSharedInstanceErrors } from '@/helpers/shared-instance-errors'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
|
||||
type SharedInstancePublishState = 'idle' | 'reviewing' | 'publishing'
|
||||
|
||||
const props = defineProps<{
|
||||
instance: GameInstance
|
||||
}>()
|
||||
|
||||
const emit = defineEmits<{
|
||||
published: []
|
||||
'state-change': [state: SharedInstancePublishState]
|
||||
}>()
|
||||
|
||||
const { formatMessage } = useVIntl()
|
||||
const { notifySharedInstanceError, notifySharedInstanceUnavailable } = useSharedInstanceErrors()
|
||||
const publishReviewModal = ref<InstanceType<typeof ContentDiffModal>>()
|
||||
const publishDiffs = ref<ContentDiffItem[]>([])
|
||||
const configFilePaths = ref<string[]>([])
|
||||
const selectedConfigPaths = ref<string[]>([])
|
||||
const state = ref<SharedInstancePublishState>('idle')
|
||||
const configFileItems = computed<FileTreeSelectItem[]>(() =>
|
||||
configFilePaths.value.map((path) => ({ path, type: 'file' })),
|
||||
)
|
||||
|
||||
async function show(e?: MouseEvent) {
|
||||
if (state.value !== 'idle') return
|
||||
|
||||
setState('reviewing')
|
||||
let reviewOpened = false
|
||||
try {
|
||||
const preview = await get_shared_instance_publish_preview(props.instance.id)
|
||||
if (!preview) {
|
||||
notifySharedInstanceUnavailable()
|
||||
emit('published')
|
||||
return
|
||||
}
|
||||
|
||||
publishDiffs.value = preview.diffs.map((diff) => ({
|
||||
type: diff.type,
|
||||
projectName: diff.projectName ?? undefined,
|
||||
fileName: diff.fileName ?? undefined,
|
||||
currentVersionName: diff.currentVersionName ?? undefined,
|
||||
newVersionName: diff.newVersionName ?? undefined,
|
||||
fileCount: diff.configFileCount ?? undefined,
|
||||
disabled: diff.disabled,
|
||||
}))
|
||||
configFilePaths.value = preview.configFiles
|
||||
selectedConfigPaths.value = []
|
||||
if (!publishReviewModal.value) return
|
||||
|
||||
publishReviewModal.value.show(e)
|
||||
reviewOpened = true
|
||||
} catch (error) {
|
||||
handlePublishError(error)
|
||||
} finally {
|
||||
if (!reviewOpened) finishReview()
|
||||
}
|
||||
}
|
||||
|
||||
async function publishChanges() {
|
||||
if (state.value !== 'reviewing') return
|
||||
|
||||
setState('publishing')
|
||||
try {
|
||||
await publish_shared_instance(props.instance.id, selectedConfigPaths.value)
|
||||
emit('published')
|
||||
} catch (error) {
|
||||
handlePublishError(error)
|
||||
} finally {
|
||||
setState('idle')
|
||||
}
|
||||
}
|
||||
|
||||
function finishReview() {
|
||||
if (state.value === 'reviewing') {
|
||||
setState('idle')
|
||||
}
|
||||
}
|
||||
|
||||
function handlePublishError(error: unknown) {
|
||||
if (isSharedInstanceUnavailableError(error)) {
|
||||
notifySharedInstanceUnavailable(getSharedInstanceUnavailableReason(error))
|
||||
emit('published')
|
||||
return
|
||||
}
|
||||
|
||||
notifySharedInstanceError(error)
|
||||
}
|
||||
|
||||
function setState(nextState: SharedInstancePublishState) {
|
||||
state.value = nextState
|
||||
emit('state-change', nextState)
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
header: {
|
||||
id: 'instance.shared-instance.publish-review.header',
|
||||
defaultMessage: 'Review changes',
|
||||
},
|
||||
admonitionHeader: {
|
||||
id: 'instance.shared-instance.publish-review.admonition-header',
|
||||
defaultMessage: 'Push update to players',
|
||||
},
|
||||
description: {
|
||||
id: 'instance.shared-instance.publish-review.description',
|
||||
defaultMessage:
|
||||
'Review the content changes and choose any config files to include in this update.',
|
||||
},
|
||||
publishButton: {
|
||||
id: 'instance.shared-instance.publish-review.publish-button',
|
||||
defaultMessage: 'Push update',
|
||||
},
|
||||
addedLabel: {
|
||||
id: 'instance.shared-instance.publish-review.added-label',
|
||||
defaultMessage: 'Added',
|
||||
},
|
||||
removedLabel: {
|
||||
id: 'instance.shared-instance.publish-review.removed-label',
|
||||
defaultMessage: 'Removed',
|
||||
},
|
||||
configTitle: {
|
||||
id: 'instance.shared-instance.publish-review.config-title-v2',
|
||||
defaultMessage: 'Select config files',
|
||||
},
|
||||
})
|
||||
|
||||
defineExpose({ show })
|
||||
</script>
|
||||
@@ -0,0 +1,134 @@
|
||||
<template>
|
||||
<ContentDiffModal
|
||||
ref="modal"
|
||||
:header="formatMessage(messages.updateToPlay)"
|
||||
:admonition-header="formatMessage(messages.updateRequired)"
|
||||
:description="instance ? formatMessage(messages.description, { name: instance.name }) : ''"
|
||||
:diffs="diffs"
|
||||
:confirm-label="formatMessage(commonMessages.updateButton)"
|
||||
:confirm-icon="DownloadIcon"
|
||||
:added-label="formatMessage(messages.addedLabel)"
|
||||
:removed-label="formatMessage(messages.removedLabel)"
|
||||
show-report-button
|
||||
show-external-warnings
|
||||
:external-warning-description="formatMessage(messages.externalWarningDescription)"
|
||||
@confirm="update"
|
||||
@cancel="emit('cancel')"
|
||||
@report="emit('report', $event)"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { DownloadIcon } from '@modrinth/assets'
|
||||
import {
|
||||
commonMessages,
|
||||
type ContentDiffItem,
|
||||
ContentDiffModal,
|
||||
defineMessages,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, ref } from 'vue'
|
||||
|
||||
import {
|
||||
getSharedInstanceUnavailableReason,
|
||||
install_update_shared_instance,
|
||||
isSharedInstanceUnavailableError,
|
||||
type SharedInstanceUnavailableReason,
|
||||
type SharedInstanceUpdatePreview,
|
||||
wait_for_install_job,
|
||||
} from '@/helpers/install'
|
||||
import { useSharedInstanceErrors } from '@/helpers/shared-instance-errors'
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
|
||||
type UpdateCompleteCallback = () => void | Promise<void>
|
||||
|
||||
const emit = defineEmits<{
|
||||
cancel: []
|
||||
complete: []
|
||||
report: [event?: MouseEvent]
|
||||
sharedInstanceUnavailable: [reason: SharedInstanceUnavailableReason | null]
|
||||
}>()
|
||||
const modal = ref<InstanceType<typeof ContentDiffModal>>()
|
||||
const instance = ref<GameInstance | null>(null)
|
||||
const preview = ref<SharedInstanceUpdatePreview | null>(null)
|
||||
const onComplete = ref<UpdateCompleteCallback>(() => {})
|
||||
const { formatMessage } = useVIntl()
|
||||
const { notifySharedInstanceError } = useSharedInstanceErrors()
|
||||
const diffs = computed<ContentDiffItem[]>(
|
||||
() =>
|
||||
preview.value?.diffs
|
||||
// TODO: This is TEMP!!! Hashing needs to be done on backend
|
||||
.filter((diff) => !(diff.type === 'updated' && !diff.projectId && diff.fileName))
|
||||
.map((diff) => ({
|
||||
type: diff.type,
|
||||
projectName: diff.projectName ?? undefined,
|
||||
fileName: diff.fileName ?? undefined,
|
||||
currentVersionName: diff.currentVersionName ?? undefined,
|
||||
newVersionName: diff.newVersionName ?? undefined,
|
||||
fileCount: diff.configFileCount ?? undefined,
|
||||
disabled: diff.disabled,
|
||||
external: diff.type === 'added' && !diff.projectId && !!diff.fileName,
|
||||
})) ?? [],
|
||||
)
|
||||
|
||||
async function update() {
|
||||
try {
|
||||
if (instance.value) {
|
||||
const job = await install_update_shared_instance(instance.value.id)
|
||||
await wait_for_install_job(job.job_id)
|
||||
await onComplete.value()
|
||||
}
|
||||
} catch (error) {
|
||||
if (isSharedInstanceUnavailableError(error)) {
|
||||
emit('sharedInstanceUnavailable', getSharedInstanceUnavailableReason(error))
|
||||
return
|
||||
}
|
||||
notifySharedInstanceError(error)
|
||||
} finally {
|
||||
emit('complete')
|
||||
}
|
||||
}
|
||||
|
||||
function show(
|
||||
instanceValue: GameInstance,
|
||||
previewValue: SharedInstanceUpdatePreview,
|
||||
callback: UpdateCompleteCallback = () => {},
|
||||
event?: MouseEvent,
|
||||
) {
|
||||
instance.value = instanceValue
|
||||
preview.value = previewValue
|
||||
onComplete.value = callback
|
||||
modal.value?.show(event)
|
||||
}
|
||||
function hide() {
|
||||
modal.value?.hide()
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
updateToPlay: { id: 'app.modal.update-to-play.header', defaultMessage: 'Update to play' },
|
||||
updateRequired: {
|
||||
id: 'app.modal.update-to-play.update-required',
|
||||
defaultMessage: 'Update required',
|
||||
},
|
||||
description: {
|
||||
id: 'app.modal.update-to-play.update-required-description',
|
||||
defaultMessage:
|
||||
'An update is required to play {name}. Please update to latest version to launch the game.',
|
||||
},
|
||||
addedLabel: {
|
||||
id: 'app.modal.update-to-play.shared-instance-added-label',
|
||||
defaultMessage: 'Added',
|
||||
},
|
||||
removedLabel: {
|
||||
id: 'app.modal.update-to-play.shared-instance-removed-label',
|
||||
defaultMessage: 'Removed',
|
||||
},
|
||||
externalWarningDescription: {
|
||||
id: 'app.modal.update-to-play.shared-instance-unknown-files-description',
|
||||
defaultMessage:
|
||||
'This shared instance update contains files that aren’t published on Modrinth. We strongly recommend only installing files from sources you trust.',
|
||||
},
|
||||
})
|
||||
|
||||
defineExpose({ show, hide })
|
||||
</script>
|
||||
+533
@@ -0,0 +1,533 @@
|
||||
<template>
|
||||
<NewModal
|
||||
ref="modal"
|
||||
:header="
|
||||
reportMode
|
||||
? formatMessage(messages.reportSharedInstance)
|
||||
: formatMessage(messages.installToPlay)
|
||||
"
|
||||
:closable="!submitLoading"
|
||||
:on-hide="handleHide"
|
||||
:max-width="reportMode ? '816px' : '544px'"
|
||||
:width="reportMode ? '816px' : '544px'"
|
||||
:no-padding="reportMode"
|
||||
:scrollable="reportMode"
|
||||
>
|
||||
<div v-if="preview" class="flex w-full flex-col gap-6" :class="{ 'p-6 pb-2': reportMode }">
|
||||
<Admonition v-if="reportMode" type="info">
|
||||
<div class="flex flex-col gap-2">
|
||||
<p class="m-0">
|
||||
<IntlFormatted :message-id="messages.reportDescription">
|
||||
<template #rules-link="{ children }">
|
||||
<AutoLink class="text-link hover:underline" to="https://modrinth.com/legal/rules">
|
||||
<component :is="() => children" />
|
||||
</AutoLink>
|
||||
</template>
|
||||
<template #terms-link="{ children }">
|
||||
<AutoLink class="text-link hover:underline" to="https://modrinth.com/legal/terms">
|
||||
<component :is="() => children" />
|
||||
</AutoLink>
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</p>
|
||||
<ul class="m-0 list-disc pl-5">
|
||||
<li>
|
||||
<IntlFormatted :message-id="messages.supportAndBugReports">
|
||||
<template #support-link="{ children }">
|
||||
<AutoLink class="text-link hover:underline" to="https://support.modrinth.com">
|
||||
<component :is="() => children" />
|
||||
</AutoLink>
|
||||
</template>
|
||||
<template #github-link="{ children }">
|
||||
<AutoLink
|
||||
class="text-link hover:underline"
|
||||
to="https://github.com/modrinth/code/issues"
|
||||
>
|
||||
<component :is="() => children" />
|
||||
</AutoLink>
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</li>
|
||||
<li>
|
||||
<IntlFormatted :message-id="messages.legalClaims">
|
||||
<template #copyright-link="{ children }">
|
||||
<AutoLink
|
||||
class="text-link hover:underline"
|
||||
to="https://modrinth.com/legal/copyright"
|
||||
>
|
||||
<component :is="() => children" />
|
||||
</AutoLink>
|
||||
</template>
|
||||
</IntlFormatted>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</Admonition>
|
||||
<p v-else class="m-0 text-primary">
|
||||
{{ formatMessage(messages.inviteWarning) }}
|
||||
</p>
|
||||
<SharedInstanceInstallSummary
|
||||
:preview="preview"
|
||||
:heading="reportMode ? formatMessage(messages.contentYouAreReporting) : undefined"
|
||||
@view-contents="openViewContents"
|
||||
/>
|
||||
<Transition
|
||||
enter-active-class="overflow-hidden transition-all duration-200 ease-out"
|
||||
enter-from-class="max-h-0 opacity-0"
|
||||
enter-to-class="max-h-[400px] opacity-100"
|
||||
leave-active-class="overflow-hidden transition-all duration-200 ease-in"
|
||||
leave-from-class="max-h-[400px] opacity-100"
|
||||
leave-to-class="max-h-0 opacity-0"
|
||||
>
|
||||
<div v-if="reportMode" class="flex flex-col gap-6">
|
||||
<div class="flex flex-col gap-2.5">
|
||||
<span class="font-semibold text-contrast">
|
||||
{{ formatMessage(messages.reportReason) }}
|
||||
</span>
|
||||
<Combobox v-model="reportReason" :options="reportReasonOptions" />
|
||||
</div>
|
||||
<div class="flex flex-col gap-2.5">
|
||||
<span class="font-semibold text-contrast">
|
||||
{{ formatMessage(messages.additionalContext) }}
|
||||
</span>
|
||||
<MarkdownEditor
|
||||
v-model="additionalContext"
|
||||
:placeholder="formatMessage(messages.additionalContextPlaceholder)"
|
||||
:on-image-upload="onImageUpload"
|
||||
:min-height="120"
|
||||
:max-height="240"
|
||||
/>
|
||||
</div>
|
||||
<div v-if="reportOnly" class="flex flex-col gap-2">
|
||||
<Checkbox v-model="deleteInstance" :label="formatMessage(messages.deleteInstance)" />
|
||||
</div>
|
||||
</div>
|
||||
</Transition>
|
||||
<Admonition
|
||||
v-if="!reportMode && hasExternalFiles"
|
||||
type="warning"
|
||||
:header="formatMessage(messages.unknownFilesWarning)"
|
||||
>
|
||||
{{ formatMessage(messages.unknownFilesDescription) }}
|
||||
</Admonition>
|
||||
|
||||
<div v-if="!reportMode && hasExternalFiles" class="relative w-full">
|
||||
<div
|
||||
ref="externalFileTable"
|
||||
class="max-h-[242px] overflow-y-auto rounded-2xl"
|
||||
@scroll="checkTableScrollState"
|
||||
>
|
||||
<Table
|
||||
:columns="externalFileColumns"
|
||||
:data="externalFileRows"
|
||||
row-key="id"
|
||||
virtualized
|
||||
:virtual-row-height="48"
|
||||
class="shadow-sm"
|
||||
>
|
||||
<template #cell-name="{ value }">
|
||||
<span class="block truncate" :title="String(value)">{{ value }}</span>
|
||||
</template>
|
||||
</Table>
|
||||
</div>
|
||||
<Transition
|
||||
enter-active-class="transition-all duration-200 ease-out"
|
||||
enter-from-class="opacity-0 max-h-0"
|
||||
enter-to-class="opacity-100 max-h-2"
|
||||
leave-active-class="transition-all duration-200 ease-in"
|
||||
leave-from-class="opacity-100 max-h-2"
|
||||
leave-to-class="opacity-0 max-h-0"
|
||||
>
|
||||
<div
|
||||
v-if="showTableTopFade"
|
||||
class="pointer-events-none absolute left-0 right-0 top-0 z-10 h-2 bg-gradient-to-b from-bg-raised to-transparent"
|
||||
/>
|
||||
</Transition>
|
||||
<Transition
|
||||
enter-active-class="transition-all duration-200 ease-out"
|
||||
enter-from-class="opacity-0 max-h-0"
|
||||
enter-to-class="opacity-100 max-h-2"
|
||||
leave-active-class="transition-all duration-200 ease-in"
|
||||
leave-from-class="opacity-100 max-h-2"
|
||||
leave-to-class="opacity-0 max-h-0"
|
||||
>
|
||||
<div
|
||||
v-if="showTableBottomFade"
|
||||
class="pointer-events-none absolute bottom-0 left-0 right-0 z-10 h-2 bg-gradient-to-t from-bg-raised to-transparent"
|
||||
/>
|
||||
</Transition>
|
||||
</div>
|
||||
|
||||
<p v-if="!reportMode && hasExternalFiles" class="m-0 text-primary">
|
||||
{{ formatMessage(messages.reviewedFiles) }}
|
||||
</p>
|
||||
<div v-if="!reportMode" class="flex w-full items-center justify-between gap-2">
|
||||
<ButtonStyled color="red" type="transparent">
|
||||
<button @click="reportMode = true">
|
||||
<ReportIcon />{{ formatMessage(commonMessages.reportButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<div class="flex items-center gap-2">
|
||||
<template v-if="hasExternalFiles">
|
||||
<ButtonStyled type="transparent" color="orange">
|
||||
<button @click="accept">
|
||||
{{ formatMessage(messages.installAnyway) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled color="brand">
|
||||
<button @click="handleCancel">
|
||||
<BanIcon />{{ formatMessage(messages.dontInstall) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</template>
|
||||
<template v-else>
|
||||
<ButtonStyled type="outlined">
|
||||
<button class="!border" @click="handleCancel">
|
||||
<XIcon />{{ formatMessage(commonMessages.cancelButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled color="brand">
|
||||
<button @click="accept">
|
||||
<DownloadIcon />{{ formatMessage(messages.installButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template v-if="reportMode" #actions>
|
||||
<div class="flex justify-end gap-2">
|
||||
<ButtonStyled type="outlined">
|
||||
<button class="!border" :disabled="submitLoading" @click="handleCancel">
|
||||
<XIcon />{{ formatMessage(commonMessages.cancelButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
<ButtonStyled color="brand">
|
||||
<button :disabled="!canSubmitReport" @click="submitReport">
|
||||
<SpinnerIcon v-if="submitLoading" class="animate-spin" />
|
||||
<SendIcon v-else />
|
||||
{{ formatMessage(commonMessages.reportButton) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
</template>
|
||||
</NewModal>
|
||||
<ModpackContentModal
|
||||
ref="contentModal"
|
||||
:header="formatMessage(messages.sharedInstanceContent)"
|
||||
:modpack-name="preview?.name ?? ''"
|
||||
:modpack-icon-url="preview?.iconUrl ?? undefined"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import type { Labrinth } from '@modrinth/api-client'
|
||||
import { BanIcon, DownloadIcon, ReportIcon, SendIcon, SpinnerIcon, XIcon } from '@modrinth/assets'
|
||||
import {
|
||||
Admonition,
|
||||
AutoLink,
|
||||
ButtonStyled,
|
||||
Checkbox,
|
||||
Combobox,
|
||||
type ComboboxOption,
|
||||
commonMessages,
|
||||
defineMessages,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
IntlFormatted,
|
||||
MarkdownEditor,
|
||||
ModpackContentModal,
|
||||
NewModal,
|
||||
Table,
|
||||
type TableColumn,
|
||||
useScrollIndicator,
|
||||
useVIntl,
|
||||
} from '@modrinth/ui'
|
||||
import { computed, nextTick, ref } from 'vue'
|
||||
|
||||
import { hide_ads_window, show_ads_window } from '@/helpers/ads'
|
||||
import { toError } from '@/helpers/errors'
|
||||
import type { SharedInstanceInstallPreview } from '@/helpers/install'
|
||||
import { create_report } from '@/helpers/reports'
|
||||
|
||||
import SharedInstanceInstallSummary from './shared-instance-install-summary.vue'
|
||||
import { useSharedInstancePreviewContent } from './use-shared-instance-preview-content'
|
||||
|
||||
type ExternalFileColumn = 'name'
|
||||
type ExternalFileRow = {
|
||||
id: string
|
||||
name: string
|
||||
}
|
||||
|
||||
const modal = ref<InstanceType<typeof NewModal>>()
|
||||
const contentModal = ref<InstanceType<typeof ModpackContentModal>>()
|
||||
const externalFileTable = ref<HTMLElement | null>(null)
|
||||
const preview = ref<SharedInstanceInstallPreview | null>(null)
|
||||
const install = ref<() => void | Promise<void>>(() => {})
|
||||
const reportMode = ref(false)
|
||||
const reportOnly = ref(false)
|
||||
type ReportReason = 'malicious' | 'inappropriate' | 'spam'
|
||||
const reportReason = ref<ReportReason>('malicious')
|
||||
const additionalContext = ref('')
|
||||
const deleteInstance = ref(true)
|
||||
const submitLoading = ref(false)
|
||||
const uploadedImageIDs = ref<string[]>([])
|
||||
const emit = defineEmits<{
|
||||
reported: [deleteInstance: boolean]
|
||||
}>()
|
||||
const { formatMessage } = useVIntl()
|
||||
const client = injectModrinthClient()
|
||||
const { addNotification, handleError } = injectNotificationManager()
|
||||
const { load } = useSharedInstancePreviewContent()
|
||||
const {
|
||||
showTopFade: showTableTopFade,
|
||||
showBottomFade: showTableBottomFade,
|
||||
checkScrollState: checkTableScrollState,
|
||||
forceCheck: forceCheckTableScroll,
|
||||
} = useScrollIndicator(externalFileTable)
|
||||
const hasExternalFiles = computed(() => Boolean(preview.value?.externalFiles.length))
|
||||
const externalFileRows = computed<ExternalFileRow[]>(() =>
|
||||
(preview.value?.externalFiles ?? [])
|
||||
.map((file, index) => ({
|
||||
id: `${index}-${file.fileType}-${file.fileName}`,
|
||||
name: file.fileName,
|
||||
}))
|
||||
.sort((left, right) => left.name.localeCompare(right.name)),
|
||||
)
|
||||
const reportReasonOptions = computed<ComboboxOption<ReportReason>[]>(() => [
|
||||
{ value: 'malicious', label: formatMessage(messages.maliciousReason) },
|
||||
{ value: 'inappropriate', label: formatMessage(messages.inappropriateReason) },
|
||||
{ value: 'spam', label: formatMessage(messages.spamReason) },
|
||||
])
|
||||
const canSubmitReport = computed(
|
||||
() => Boolean(preview.value && additionalContext.value.trim()) && !submitLoading.value,
|
||||
)
|
||||
|
||||
async function accept() {
|
||||
hide()
|
||||
try {
|
||||
await install.value()
|
||||
} catch (error) {
|
||||
console.error('Failed to install shared instance:', error)
|
||||
}
|
||||
}
|
||||
async function openViewContents() {
|
||||
if (!preview.value) return
|
||||
contentModal.value?.showLoading()
|
||||
try {
|
||||
contentModal.value?.show(await load(preview.value))
|
||||
} catch (error) {
|
||||
console.error('Failed to load shared instance contents:', error)
|
||||
contentModal.value?.show([])
|
||||
}
|
||||
}
|
||||
async function submitReport() {
|
||||
const reportPreview = preview.value
|
||||
const body = additionalContext.value.trim()
|
||||
if (!reportPreview || !body || submitLoading.value) return
|
||||
|
||||
submitLoading.value = true
|
||||
try {
|
||||
const uploadedImages = uploadedImageIDs.value.slice(-10)
|
||||
await create_report({
|
||||
report_type: reportReason.value,
|
||||
item_type: 'shared-instance',
|
||||
item_id: `${reportPreview.sharedInstanceId}/${reportPreview.version}`,
|
||||
body,
|
||||
uploaded_images: uploadedImages,
|
||||
})
|
||||
|
||||
const shouldDeleteInstance = reportOnly.value && deleteInstance.value
|
||||
hide()
|
||||
addNotification({
|
||||
type: 'success',
|
||||
title: formatMessage(messages.reportSubmitted),
|
||||
})
|
||||
emit('reported', shouldDeleteInstance)
|
||||
} catch (error) {
|
||||
handleError(toError(error))
|
||||
} finally {
|
||||
submitLoading.value = false
|
||||
}
|
||||
}
|
||||
async function onImageUpload(file: File) {
|
||||
const imageExtensionByType: Partial<Record<string, Labrinth.Images.v3.ImageExtension>> = {
|
||||
'image/gif': 'gif',
|
||||
'image/jpeg': 'jpeg',
|
||||
'image/png': 'png',
|
||||
'image/webp': 'webp',
|
||||
}
|
||||
const extension = imageExtensionByType[file.type]
|
||||
if (!extension) {
|
||||
throw new Error(formatMessage(messages.invalidImageType))
|
||||
}
|
||||
if (file.size > 1024 * 1024) {
|
||||
throw new Error(formatMessage(messages.imageTooLarge))
|
||||
}
|
||||
|
||||
const image = await client.labrinth.images_v3.uploadImage(file, extension, {
|
||||
context: 'report',
|
||||
}).promise
|
||||
uploadedImageIDs.value.push(image.id)
|
||||
return image.url
|
||||
}
|
||||
function handleCancel() {
|
||||
if (reportMode.value && !reportOnly.value) {
|
||||
reportMode.value = false
|
||||
void nextTick(() => forceCheckTableScroll())
|
||||
return
|
||||
}
|
||||
hide()
|
||||
}
|
||||
function handleHide() {
|
||||
resetReportState()
|
||||
show_ads_window()
|
||||
}
|
||||
function resetReportState() {
|
||||
reportMode.value = false
|
||||
reportOnly.value = false
|
||||
reportReason.value = 'malicious'
|
||||
additionalContext.value = ''
|
||||
deleteInstance.value = true
|
||||
submitLoading.value = false
|
||||
uploadedImageIDs.value = []
|
||||
}
|
||||
function show(
|
||||
previewValue: SharedInstanceInstallPreview,
|
||||
installValue: () => void | Promise<void>,
|
||||
event?: MouseEvent,
|
||||
) {
|
||||
resetReportState()
|
||||
install.value = installValue
|
||||
showPreview(previewValue, event)
|
||||
}
|
||||
function showReport(previewValue: SharedInstanceInstallPreview, event?: MouseEvent) {
|
||||
resetReportState()
|
||||
reportMode.value = true
|
||||
reportOnly.value = true
|
||||
install.value = () => {}
|
||||
showPreview(previewValue, event)
|
||||
}
|
||||
function showPreview(previewValue: SharedInstanceInstallPreview, event?: MouseEvent) {
|
||||
preview.value = previewValue
|
||||
hide_ads_window()
|
||||
modal.value?.show(event)
|
||||
void nextTick(() => forceCheckTableScroll())
|
||||
}
|
||||
function hide() {
|
||||
modal.value?.hide()
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
installToPlay: { id: 'app.modal.install-to-play.header', defaultMessage: 'Install to play' },
|
||||
reportSharedInstance: {
|
||||
id: 'app.modal.install-to-play.report-shared-instance-header',
|
||||
defaultMessage: 'Report shared instance',
|
||||
},
|
||||
reportSubmitted: {
|
||||
id: 'app.modal.install-to-play.report-submitted',
|
||||
defaultMessage: 'Report submitted',
|
||||
},
|
||||
sharedInstanceContent: {
|
||||
id: 'app.modal.install-to-play.shared-instance-content',
|
||||
defaultMessage: 'Shared instance content',
|
||||
},
|
||||
inviteWarning: {
|
||||
id: 'app.modal.install-to-play.invite-warning',
|
||||
defaultMessage:
|
||||
'This invite was created by another Modrinth user, not Modrinth. Only accept invites from people you trust.',
|
||||
},
|
||||
reportDescription: {
|
||||
id: 'app.modal.install-to-play.report-description',
|
||||
defaultMessage:
|
||||
'Use this form to report instances that may violate our <rules-link>Rules</rules-link> or <terms-link>Terms of Use</terms-link>.',
|
||||
},
|
||||
supportAndBugReports: {
|
||||
id: 'app.modal.install-to-play.report-support-and-bugs',
|
||||
defaultMessage:
|
||||
'For support requests, contact our <support-link>support team</support-link>. For bug reports, open a <github-link>GitHub issue</github-link>.',
|
||||
},
|
||||
legalClaims: {
|
||||
id: 'app.modal.install-to-play.report-legal-claims',
|
||||
defaultMessage:
|
||||
'For DMCA notices or other legal claims, see our <copyright-link>Copyright Policy</copyright-link>.',
|
||||
},
|
||||
contentYouAreReporting: {
|
||||
id: 'app.modal.install-to-play.content-you-are-reporting',
|
||||
defaultMessage: 'Instance you’re reporting',
|
||||
},
|
||||
reportReason: {
|
||||
id: 'app.modal.install-to-play.report-reason',
|
||||
defaultMessage: 'Which rule does this instance violate?',
|
||||
},
|
||||
maliciousReason: {
|
||||
id: 'app.modal.install-to-play.report-reason.malicious',
|
||||
defaultMessage: 'Malicious',
|
||||
},
|
||||
inappropriateReason: {
|
||||
id: 'app.modal.install-to-play.report-reason.inappropriate',
|
||||
defaultMessage: 'Inappropriate',
|
||||
},
|
||||
spamReason: {
|
||||
id: 'app.modal.install-to-play.report-reason.spam',
|
||||
defaultMessage: 'Spam',
|
||||
},
|
||||
additionalContext: {
|
||||
id: 'app.modal.install-to-play.additional-context',
|
||||
defaultMessage: 'Additional context',
|
||||
},
|
||||
additionalContextPlaceholder: {
|
||||
id: 'app.modal.install-to-play.additional-context-placeholder',
|
||||
defaultMessage: 'Include links and images if possible and relevant',
|
||||
},
|
||||
invalidImageType: {
|
||||
id: 'app.modal.install-to-play.report-image-invalid-type',
|
||||
defaultMessage: 'File is not an accepted image type',
|
||||
},
|
||||
imageTooLarge: {
|
||||
id: 'app.modal.install-to-play.report-image-too-large',
|
||||
defaultMessage: 'File exceeds the 1 MiB size limit',
|
||||
},
|
||||
deleteInstance: {
|
||||
id: 'app.modal.install-to-play.delete-instance',
|
||||
defaultMessage: 'Delete instance',
|
||||
},
|
||||
unknownFilesWarning: {
|
||||
id: 'app.modal.install-to-play.unknown-files-warning',
|
||||
defaultMessage: 'Unknown files warning',
|
||||
},
|
||||
unknownFilesDescription: {
|
||||
id: 'app.modal.install-to-play.shared-instance-unknown-files-description',
|
||||
defaultMessage:
|
||||
'This shared instance contains files that aren’t published on Modrinth. We strongly recommend only installing files from sources you trust.',
|
||||
},
|
||||
unrecognizedFiles: {
|
||||
id: 'app.modal.install-to-play.unrecognized-files',
|
||||
defaultMessage: 'Unrecognized files',
|
||||
},
|
||||
reviewedFiles: {
|
||||
id: 'app.modal.install-to-play.reviewed-files',
|
||||
defaultMessage:
|
||||
'A file is only reviewed if it’s published to Modrinth, regardless of its file format (including .mrpack).',
|
||||
},
|
||||
installAnyway: {
|
||||
id: 'app.modal.install-to-play.install-anyway',
|
||||
defaultMessage: 'Install anyway',
|
||||
},
|
||||
dontInstall: {
|
||||
id: 'app.modal.install-to-play.external-files-dont-install',
|
||||
defaultMessage: "Don't install",
|
||||
},
|
||||
installButton: { id: 'app.modal.install-to-play.install-button', defaultMessage: 'Install' },
|
||||
})
|
||||
|
||||
const externalFileColumns = computed<TableColumn<ExternalFileColumn>[]>(() => [
|
||||
{
|
||||
key: 'name',
|
||||
label: formatMessage(messages.unrecognizedFiles),
|
||||
cellClass: '!h-12',
|
||||
},
|
||||
])
|
||||
|
||||
defineExpose({ show, showReport, hide })
|
||||
</script>
|
||||
+60
@@ -0,0 +1,60 @@
|
||||
<template>
|
||||
<div class="flex flex-col gap-2.5">
|
||||
<div class="flex items-center justify-between">
|
||||
<span class="font-semibold text-contrast">{{
|
||||
heading ?? formatMessage(messages.sharedInstance)
|
||||
}}</span>
|
||||
<ButtonStyled type="transparent">
|
||||
<button @click="emit('viewContents')">
|
||||
<EyeIcon />
|
||||
{{ formatMessage(messages.viewContents) }}
|
||||
</button>
|
||||
</ButtonStyled>
|
||||
</div>
|
||||
<div class="flex items-center gap-3 rounded-2xl bg-surface-2 p-3">
|
||||
<Avatar
|
||||
:src="preview.iconUrl"
|
||||
:alt="preview.name"
|
||||
size="56px"
|
||||
no-shadow
|
||||
class="!rounded-2xl"
|
||||
/>
|
||||
<div class="flex min-w-0 flex-col gap-0.5">
|
||||
<span class="truncate font-semibold text-contrast">{{ preview.name }}</span>
|
||||
<span class="truncate text-sm font-medium text-secondary">
|
||||
{{ loaderDisplay }} {{ preview.gameVersion }}
|
||||
<template v-if="preview.modCount">
|
||||
· {{ formatMessage(messages.modCount, { count: preview.modCount }) }}
|
||||
</template>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { EyeIcon } from '@modrinth/assets'
|
||||
import { Avatar, ButtonStyled, defineMessages, formatLoader, useVIntl } from '@modrinth/ui'
|
||||
import { computed, toRefs } from 'vue'
|
||||
|
||||
import type { SharedInstanceInstallPreview } from '@/helpers/install'
|
||||
|
||||
const props = defineProps<{ preview: SharedInstanceInstallPreview; heading?: string }>()
|
||||
const { preview, heading } = toRefs(props)
|
||||
const emit = defineEmits<{ viewContents: [] }>()
|
||||
const { formatMessage } = useVIntl()
|
||||
const loaderDisplay = computed(() =>
|
||||
preview.value.loader ? formatLoader(formatMessage, preview.value.loader) : '',
|
||||
)
|
||||
const messages = defineMessages({
|
||||
sharedInstance: {
|
||||
id: 'app.modal.install-to-play.shared-instance',
|
||||
defaultMessage: 'Shared instance',
|
||||
},
|
||||
viewContents: { id: 'app.modal.install-to-play.view-contents', defaultMessage: 'View contents' },
|
||||
modCount: {
|
||||
id: 'app.modal.install-to-play.mod-count',
|
||||
defaultMessage: '{count, plural, one {# mod} other {# mods}}',
|
||||
},
|
||||
})
|
||||
</script>
|
||||
+135
@@ -0,0 +1,135 @@
|
||||
import type { Labrinth } from '@modrinth/api-client'
|
||||
import type { ContentItem } from '@modrinth/ui'
|
||||
|
||||
import { get_project_many, get_version, get_version_many } from '@/helpers/cache.js'
|
||||
import type { SharedInstanceInstallPreview } from '@/helpers/install'
|
||||
|
||||
type VersionDependency = Labrinth.Versions.v2.Dependency & { version_id?: string }
|
||||
|
||||
export function useSharedInstancePreviewContent() {
|
||||
async function load(preview: SharedInstanceInstallPreview): Promise<ContentItem[]> {
|
||||
return [
|
||||
...preview.externalFiles.map(externalFileContentItem),
|
||||
...(await modpackContentItems(preview)),
|
||||
...(await contentItemsFromVersionIds(
|
||||
preview.contentVersionIds.filter((id) => id !== preview.modpackVersionId),
|
||||
)),
|
||||
]
|
||||
}
|
||||
|
||||
async function modpackContentItems(preview: SharedInstanceInstallPreview) {
|
||||
if (!preview.modpackVersionId) return []
|
||||
const version = await get_version(preview.modpackVersionId, 'must_revalidate')
|
||||
return await contentItemsFromDependencies(version?.dependencies ?? [])
|
||||
}
|
||||
|
||||
async function contentItemsFromDependencies(dependencies: Labrinth.Versions.v2.Dependency[]) {
|
||||
const deps = dependencies as VersionDependency[]
|
||||
const projectIds = unique(deps.map((dep) => dep.project_id).filter((id): id is string => !!id))
|
||||
const versionIds = unique(deps.map((dep) => dep.version_id).filter((id): id is string => !!id))
|
||||
const [projects, versions]: [Labrinth.Projects.v2.Project[], Labrinth.Versions.v2.Version[]] =
|
||||
await Promise.all([
|
||||
projectIds.length ? get_project_many(projectIds, 'must_revalidate') : [],
|
||||
versionIds.length ? get_version_many(versionIds, 'must_revalidate') : [],
|
||||
])
|
||||
const projectMap = new Map(projects.map((project) => [project.id, project]))
|
||||
const versionMap = new Map(versions.map((version) => [version.id, version]))
|
||||
|
||||
return deps.map((dependency): ContentItem => {
|
||||
const project = dependency.project_id ? projectMap.get(dependency.project_id) : null
|
||||
const version = dependency.version_id ? versionMap.get(dependency.version_id) : null
|
||||
const fileName =
|
||||
version?.files?.[0]?.filename ?? dependency.file_name ?? project?.title ?? 'Unknown'
|
||||
return contentItem(
|
||||
version?.id ?? project?.id ?? fileName,
|
||||
fileName,
|
||||
project,
|
||||
version,
|
||||
!project && !version,
|
||||
dependency.project_id ?? fileName,
|
||||
dependency.file_name ?? fileName,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
async function contentItemsFromVersionIds(versionIds: string[]) {
|
||||
const versions: Labrinth.Versions.v2.Version[] = versionIds.length
|
||||
? await get_version_many(unique(versionIds), 'must_revalidate')
|
||||
: []
|
||||
const projectIds = unique(versions.map((version) => version.project_id).filter(Boolean))
|
||||
const projects: Labrinth.Projects.v2.Project[] = projectIds.length
|
||||
? await get_project_many(projectIds, 'must_revalidate')
|
||||
: []
|
||||
const projectMap = new Map(projects.map((project) => [project.id, project]))
|
||||
return versions.map((version): ContentItem => {
|
||||
const project = projectMap.get(version.project_id)
|
||||
const fileName = version.files?.[0]?.filename ?? project?.title ?? version.name ?? 'Unknown'
|
||||
return contentItem(
|
||||
version.id,
|
||||
fileName,
|
||||
project,
|
||||
version,
|
||||
false,
|
||||
version.project_id,
|
||||
version.name,
|
||||
)
|
||||
})
|
||||
}
|
||||
|
||||
return { load }
|
||||
}
|
||||
|
||||
function contentItem(
|
||||
id: string,
|
||||
fileName: string,
|
||||
project?: Labrinth.Projects.v2.Project | null,
|
||||
version?: Labrinth.Versions.v2.Version | null,
|
||||
external = false,
|
||||
fallbackProjectId = id,
|
||||
fallbackTitle = fileName,
|
||||
projectType = project?.project_type ?? 'mod',
|
||||
): ContentItem {
|
||||
return {
|
||||
id,
|
||||
file_name: fileName,
|
||||
project_type: projectType,
|
||||
has_update: false,
|
||||
update_version_id: null,
|
||||
external,
|
||||
project: {
|
||||
id: project?.id ?? fallbackProjectId,
|
||||
slug: project?.slug ?? fallbackProjectId,
|
||||
title: project?.title ?? fallbackTitle,
|
||||
icon_url: project?.icon_url ?? undefined,
|
||||
},
|
||||
...(version
|
||||
? {
|
||||
version: {
|
||||
id: version.id,
|
||||
file_name: fileName,
|
||||
version_number: version.version_number ?? undefined,
|
||||
date_published: version.date_published ?? undefined,
|
||||
},
|
||||
}
|
||||
: {}),
|
||||
}
|
||||
}
|
||||
|
||||
function externalFileContentItem(
|
||||
file: SharedInstanceInstallPreview['externalFiles'][number],
|
||||
): ContentItem {
|
||||
return contentItem(
|
||||
`external:${file.fileType}:${file.fileName}`,
|
||||
file.fileName,
|
||||
null,
|
||||
null,
|
||||
true,
|
||||
file.fileName,
|
||||
file.fileName,
|
||||
file.fileType,
|
||||
)
|
||||
}
|
||||
|
||||
function unique<T>(values: T[]) {
|
||||
return Array.from(new Set(values))
|
||||
}
|
||||
+48
@@ -0,0 +1,48 @@
|
||||
<template>
|
||||
<ModrinthAccountRequiredModal ref="accountRequiredModal" :request-auth="requestAuth" />
|
||||
<SharedInstanceInstallModal ref="installModal" />
|
||||
<SharedInstanceAlreadyInstalledModal
|
||||
ref="alreadyInstalledModal"
|
||||
@cancel="handleAlreadyInstalledCancel"
|
||||
@go-to-instance="handleAlreadyInstalledGoToInstance"
|
||||
@install-anyway="handleAlreadyInstalledInstallAnyway"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { injectAuth } from '@modrinth/ui'
|
||||
import { nextTick, ref } from 'vue'
|
||||
|
||||
import ModrinthAccountRequiredModal from '@/components/ui/modal/ModrinthAccountRequiredModal.vue'
|
||||
import SharedInstanceInstallModal from '@/components/ui/shared-instances/shared-instance-install-modal/index.vue'
|
||||
import SharedInstanceAlreadyInstalledModal from '@/components/ui/shared-instances/SharedInstanceAlreadyInstalledModal.vue'
|
||||
import type { ModrinthAuthFlow } from '@/helpers/mr_auth'
|
||||
|
||||
import type { SharedInstanceInviteHandler } from './shared-instance-invite-types'
|
||||
import { useSharedInstanceInviteHandler } from './use-shared-instance-invite-handler'
|
||||
|
||||
const auth = injectAuth()
|
||||
const installModal = ref<InstanceType<typeof SharedInstanceInstallModal>>()
|
||||
const alreadyInstalledModal = ref<InstanceType<typeof SharedInstanceAlreadyInstalledModal>>()
|
||||
const accountRequiredModal = ref<InstanceType<typeof ModrinthAccountRequiredModal>>()
|
||||
const {
|
||||
handleNotification,
|
||||
installFromInviteId,
|
||||
clearNotifications,
|
||||
handleAlreadyInstalledCancel,
|
||||
handleAlreadyInstalledGoToInstance,
|
||||
handleAlreadyInstalledInstallAnyway,
|
||||
} = useSharedInstanceInviteHandler(installModal, alreadyInstalledModal, accountRequiredModal)
|
||||
|
||||
async function requestAuth(flow: ModrinthAuthFlow) {
|
||||
await auth.requestSignIn('', flow, { showModal: false })
|
||||
await nextTick()
|
||||
return !!auth.session_token.value
|
||||
}
|
||||
|
||||
defineExpose<SharedInstanceInviteHandler>({
|
||||
handleNotification,
|
||||
installFromInviteId,
|
||||
clearNotifications,
|
||||
})
|
||||
</script>
|
||||
+29
@@ -0,0 +1,29 @@
|
||||
import type {
|
||||
AppNotification,
|
||||
SharedInstanceInvite,
|
||||
SharedInstanceInviteNotificationBody,
|
||||
} from './shared-instance-invite-types'
|
||||
|
||||
function optionalString(value: unknown) {
|
||||
return typeof value === 'string' ? value : null
|
||||
}
|
||||
|
||||
export function parseSharedInstanceInviteNotification(
|
||||
notification: AppNotification,
|
||||
): SharedInstanceInvite | null {
|
||||
if (notification.body?.type !== 'shared_instance_invite') return null
|
||||
|
||||
const body = notification.body as SharedInstanceInviteNotificationBody
|
||||
const sharedInstanceId = optionalString(body.shared_instance_id)
|
||||
const sharedInstanceName = optionalString(body.shared_instance_name)
|
||||
if (!sharedInstanceId || !sharedInstanceName) return null
|
||||
|
||||
return {
|
||||
sharedInstanceId,
|
||||
sharedInstanceName,
|
||||
invitedById: optionalString(body.invited_by),
|
||||
invitedByUsername: optionalString(body.invited_by_username),
|
||||
invitedByAvatarUrl: optionalString(body.invited_by_avatar_url),
|
||||
instanceIconUrl: optionalString(body.shared_instance_icon),
|
||||
}
|
||||
}
|
||||
+30
@@ -0,0 +1,30 @@
|
||||
export type SharedInstanceInviteNotificationBody = {
|
||||
type: 'shared_instance_invite'
|
||||
shared_instance_id?: unknown
|
||||
shared_instance_name?: unknown
|
||||
invited_by?: unknown
|
||||
invited_by_username?: unknown
|
||||
invited_by_avatar_url?: unknown
|
||||
shared_instance_icon?: unknown
|
||||
}
|
||||
|
||||
export type AppNotification = {
|
||||
id: string | number
|
||||
read?: boolean
|
||||
body?: { type?: unknown } & Record<string, unknown>
|
||||
}
|
||||
|
||||
export type SharedInstanceInvite = {
|
||||
sharedInstanceId: string
|
||||
sharedInstanceName: string
|
||||
invitedById: string | null
|
||||
invitedByUsername: string | null
|
||||
invitedByAvatarUrl: string | null
|
||||
instanceIconUrl: string | null
|
||||
}
|
||||
|
||||
export type SharedInstanceInviteHandler = {
|
||||
handleNotification(notification: AppNotification): Promise<boolean>
|
||||
installFromInviteId(inviteId: string): Promise<void>
|
||||
clearNotifications(): void
|
||||
}
|
||||
+282
@@ -0,0 +1,282 @@
|
||||
import { ModrinthApiError } from '@modrinth/api-client'
|
||||
import {
|
||||
injectAuth,
|
||||
injectModrinthClient,
|
||||
injectNotificationManager,
|
||||
injectPopupNotificationManager,
|
||||
} from '@modrinth/ui'
|
||||
import { useQueryClient } from '@tanstack/vue-query'
|
||||
import { openUrl } from '@tauri-apps/plugin-opener'
|
||||
import { type Ref, watch } from 'vue'
|
||||
import { useRouter } from 'vue-router'
|
||||
|
||||
import { config } from '@/config'
|
||||
import { get_user } from '@/helpers/cache'
|
||||
import { toError } from '@/helpers/errors'
|
||||
import {
|
||||
install_accept_shared_instance_invite,
|
||||
install_get_shared_instance_preview,
|
||||
install_shared_instance,
|
||||
} from '@/helpers/install'
|
||||
import { list } from '@/helpers/instance'
|
||||
import { useTheming } from '@/store/state'
|
||||
|
||||
import { parseSharedInstanceInviteNotification } from './shared-instance-invite-parser'
|
||||
import type { AppNotification, SharedInstanceInvite } from './shared-instance-invite-types'
|
||||
|
||||
type InstallModal = {
|
||||
show(
|
||||
preview: Awaited<ReturnType<typeof install_get_shared_instance_preview>>,
|
||||
install: () => Promise<void>,
|
||||
): void
|
||||
}
|
||||
|
||||
type AccountRequiredModal = {
|
||||
show(event?: MouseEvent): Promise<boolean>
|
||||
}
|
||||
|
||||
type AlreadyInstalledModal = {
|
||||
show(instanceName: string): void
|
||||
}
|
||||
|
||||
export function useSharedInstanceInviteHandler(
|
||||
installModal: Ref<InstallModal | undefined>,
|
||||
alreadyInstalledModal: Ref<AlreadyInstalledModal | undefined>,
|
||||
accountRequiredModal: Ref<AccountRequiredModal | undefined>,
|
||||
) {
|
||||
const auth = injectAuth()
|
||||
const client = injectModrinthClient()
|
||||
const { handleError } = injectNotificationManager()
|
||||
const popupNotificationManager = injectPopupNotificationManager()
|
||||
const queryClient = useQueryClient()
|
||||
const router = useRouter()
|
||||
const themeStore = useTheming()
|
||||
const displayedNotifications = new Set<string | number>()
|
||||
const displayedNotificationKeys = new Set<string>()
|
||||
const popupNotificationIds = new Set<string | number>()
|
||||
let notificationGeneration = 0
|
||||
let pendingAlreadyInstalled:
|
||||
| {
|
||||
instanceId: string
|
||||
preview: Awaited<ReturnType<typeof install_get_shared_instance_preview>>
|
||||
install: () => Promise<void>
|
||||
onGoToInstance?: () => void | Promise<void>
|
||||
}
|
||||
| undefined
|
||||
|
||||
async function markNotificationRead(notification: AppNotification) {
|
||||
try {
|
||||
await client.labrinth.notifications_v2.markAsRead(String(notification.id))
|
||||
} catch (error) {
|
||||
if (error instanceof ModrinthApiError && error.statusCode === 404) return
|
||||
throw error
|
||||
}
|
||||
}
|
||||
|
||||
async function resolveInvite(invite: SharedInstanceInvite) {
|
||||
const [invitedBy, sharedInstance] = await Promise.all([
|
||||
!invite.invitedByUsername && invite.invitedById
|
||||
? get_user(invite.invitedById, 'bypass').catch(() => null)
|
||||
: null,
|
||||
client.sharedinstances.instances_v1.get(invite.sharedInstanceId).catch(() => null),
|
||||
])
|
||||
|
||||
return {
|
||||
...invite,
|
||||
invitedByUsername: invite.invitedByUsername ?? invitedBy?.username ?? null,
|
||||
invitedByAvatarUrl: invite.invitedByAvatarUrl ?? invitedBy?.avatar_url ?? null,
|
||||
instanceIconUrl: sharedInstance ? sharedInstance.icon : invite.instanceIconUrl,
|
||||
}
|
||||
}
|
||||
|
||||
function showInstall(
|
||||
preview: Awaited<ReturnType<typeof install_get_shared_instance_preview>>,
|
||||
install: () => Promise<void>,
|
||||
) {
|
||||
if (!installModal.value) throw new Error('Shared instance install modal is not available.')
|
||||
installModal.value.show(preview, install)
|
||||
}
|
||||
|
||||
async function showInstallOrAlreadyInstalled(
|
||||
sharedInstanceId: string,
|
||||
preview: Awaited<ReturnType<typeof install_get_shared_instance_preview>>,
|
||||
install: () => Promise<void>,
|
||||
onGoToInstance?: () => void | Promise<void>,
|
||||
) {
|
||||
const existingInstance = (await list()).find(
|
||||
(instance) => instance.shared_instance?.id === sharedInstanceId,
|
||||
)
|
||||
|
||||
if (!existingInstance || themeStore.getFeatureFlag('skip_non_essential_warnings')) {
|
||||
showInstall(preview, install)
|
||||
return
|
||||
}
|
||||
|
||||
if (!alreadyInstalledModal.value) {
|
||||
throw new Error('Shared instance already installed modal is not available.')
|
||||
}
|
||||
|
||||
pendingAlreadyInstalled = {
|
||||
instanceId: existingInstance.id,
|
||||
preview,
|
||||
install,
|
||||
onGoToInstance,
|
||||
}
|
||||
alreadyInstalledModal.value.show(existingInstance.name)
|
||||
}
|
||||
|
||||
function handleAlreadyInstalledCancel() {
|
||||
pendingAlreadyInstalled = undefined
|
||||
}
|
||||
|
||||
async function handleAlreadyInstalledGoToInstance() {
|
||||
const pending = pendingAlreadyInstalled
|
||||
pendingAlreadyInstalled = undefined
|
||||
if (!pending) return
|
||||
|
||||
if (pending.onGoToInstance) {
|
||||
try {
|
||||
await pending.onGoToInstance()
|
||||
} catch (error) {
|
||||
handleError(toError(error))
|
||||
}
|
||||
}
|
||||
await router.push(`/instance/${encodeURIComponent(pending.instanceId)}/`)
|
||||
}
|
||||
|
||||
function handleAlreadyInstalledInstallAnyway() {
|
||||
const pending = pendingAlreadyInstalled
|
||||
pendingAlreadyInstalled = undefined
|
||||
if (!pending) return
|
||||
showInstall(pending.preview, pending.install)
|
||||
}
|
||||
|
||||
async function acceptNotification(notification: AppNotification, invite: SharedInstanceInvite) {
|
||||
try {
|
||||
const preview = await install_get_shared_instance_preview(
|
||||
invite.sharedInstanceId,
|
||||
invite.sharedInstanceName,
|
||||
)
|
||||
if (invite.instanceIconUrl) preview.iconUrl = invite.instanceIconUrl
|
||||
|
||||
await showInstallOrAlreadyInstalled(
|
||||
invite.sharedInstanceId,
|
||||
preview,
|
||||
async () => {
|
||||
await install_shared_instance(
|
||||
invite.sharedInstanceId,
|
||||
invite.sharedInstanceName,
|
||||
invite.invitedById,
|
||||
null,
|
||||
null,
|
||||
invite.instanceIconUrl,
|
||||
)
|
||||
await markNotificationRead(notification)
|
||||
await queryClient.invalidateQueries({ queryKey: ['instances'] })
|
||||
},
|
||||
() => markNotificationRead(notification),
|
||||
)
|
||||
} catch (error) {
|
||||
handleError(toError(error))
|
||||
}
|
||||
}
|
||||
|
||||
async function handleNotification(notification: AppNotification) {
|
||||
const parsedInvite = parseSharedInstanceInviteNotification(notification)
|
||||
if (!parsedInvite) return false
|
||||
if (displayedNotifications.has(notification.id)) return true
|
||||
|
||||
const generation = notificationGeneration
|
||||
displayedNotifications.add(notification.id)
|
||||
const invite = await resolveInvite(parsedInvite)
|
||||
if (generation !== notificationGeneration) return true
|
||||
|
||||
const notificationKey = JSON.stringify([
|
||||
invite.invitedById ?? invite.invitedByUsername,
|
||||
invite.sharedInstanceName,
|
||||
invite.instanceIconUrl,
|
||||
])
|
||||
if (displayedNotificationKeys.has(notificationKey)) {
|
||||
await markNotificationRead(notification).catch((error) => handleError(toError(error)))
|
||||
return true
|
||||
}
|
||||
|
||||
displayedNotificationKeys.add(notificationKey)
|
||||
const popupNotification = popupNotificationManager.addPopupNotification({
|
||||
title: invite.sharedInstanceName,
|
||||
autoCloseMs: null,
|
||||
toast: {
|
||||
type: 'instance-invite',
|
||||
actorName: invite.invitedByUsername,
|
||||
actorAvatarUrl: invite.invitedByAvatarUrl ?? undefined,
|
||||
entityName: invite.sharedInstanceName,
|
||||
entityIconUrl: invite.instanceIconUrl ?? undefined,
|
||||
onAccept: () => acceptNotification(notification, invite),
|
||||
onDecline: () =>
|
||||
markNotificationRead(notification).catch((error) => handleError(toError(error))),
|
||||
onOpenActor: () => {
|
||||
if (invite.invitedByUsername) {
|
||||
openUrl(`${config.siteUrl}/user/${encodeURIComponent(invite.invitedByUsername)}`)
|
||||
}
|
||||
},
|
||||
},
|
||||
})
|
||||
popupNotificationIds.add(popupNotification.id)
|
||||
return true
|
||||
}
|
||||
|
||||
function clearNotifications() {
|
||||
notificationGeneration++
|
||||
for (const id of popupNotificationIds) {
|
||||
popupNotificationManager.removeNotification(id)
|
||||
}
|
||||
displayedNotifications.clear()
|
||||
displayedNotificationKeys.clear()
|
||||
popupNotificationIds.clear()
|
||||
pendingAlreadyInstalled = undefined
|
||||
}
|
||||
|
||||
async function requireAccount() {
|
||||
if (!auth.isReady?.value) {
|
||||
await new Promise<void>((resolve) => {
|
||||
const stop = watch(auth.isReady!, (ready) => {
|
||||
if (ready) {
|
||||
stop()
|
||||
resolve()
|
||||
}
|
||||
})
|
||||
})
|
||||
}
|
||||
if (auth.session_token.value) return true
|
||||
return (await accountRequiredModal.value?.show()) ?? false
|
||||
}
|
||||
|
||||
async function installFromInviteId(inviteId: string) {
|
||||
try {
|
||||
if (!(await requireAccount())) return
|
||||
const invite = await install_accept_shared_instance_invite(inviteId)
|
||||
await showInstallOrAlreadyInstalled(invite.sharedInstanceId, invite.preview, async () => {
|
||||
await install_shared_instance(
|
||||
invite.sharedInstanceId,
|
||||
invite.preview.name,
|
||||
invite.managerId,
|
||||
invite.serverManagerName,
|
||||
invite.serverManagerIconUrl,
|
||||
invite.instanceIconUrl,
|
||||
)
|
||||
await queryClient.invalidateQueries({ queryKey: ['instances'] })
|
||||
})
|
||||
} catch (error) {
|
||||
handleError(toError(error))
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
handleNotification,
|
||||
installFromInviteId,
|
||||
clearNotifications,
|
||||
handleAlreadyInstalledCancel,
|
||||
handleAlreadyInstalledGoToInstance,
|
||||
handleAlreadyInstalledInstallAnyway,
|
||||
}
|
||||
}
|
||||
@@ -80,6 +80,7 @@ const playing = ref(false)
|
||||
|
||||
const play = async (event: MouseEvent) => {
|
||||
event?.stopPropagation()
|
||||
if (props.instance.quarantined) return
|
||||
loading.value = true
|
||||
await run(props.instance.id)
|
||||
.catch((err) => handleSevereError(err, { instanceId: props.instance.id }))
|
||||
@@ -192,8 +193,14 @@ onUnmounted(() => {
|
||||
</ButtonStyled>
|
||||
<ButtonStyled v-else>
|
||||
<button
|
||||
v-tooltip="playing ? 'Instance is already open' : null"
|
||||
:disabled="playing || loading"
|
||||
v-tooltip="
|
||||
instance.quarantined
|
||||
? 'This instance has been locked'
|
||||
: playing
|
||||
? 'Instance is already open'
|
||||
: null
|
||||
"
|
||||
:disabled="instance.quarantined || playing || loading"
|
||||
@click="play"
|
||||
>
|
||||
<SpinnerIcon v-if="loading" class="animate-spin" />
|
||||
|
||||
@@ -176,6 +176,7 @@ function refreshServer(address: string, instanceId: string) {
|
||||
}
|
||||
|
||||
async function joinWorld(world: WorldWithInstance, instance?: GameInstance) {
|
||||
if (instance?.quarantined) return
|
||||
console.log(`Joining world ${getWorldIdentifier(world)}`)
|
||||
if (world.type === 'server') {
|
||||
await start_join_server(world.instance_id, world.address).catch(handleError)
|
||||
@@ -192,6 +193,7 @@ async function joinWorld(world: WorldWithInstance, instance?: GameInstance) {
|
||||
}
|
||||
|
||||
async function playInstance(instance: GameInstance) {
|
||||
if (instance.quarantined) return
|
||||
await run(instance.id)
|
||||
.catch((err) => handleSevereError(err, { instanceId: instance.id }))
|
||||
.finally(() => {
|
||||
@@ -300,6 +302,7 @@ onUnmounted(() => {
|
||||
item.world.type === 'singleplayer' &&
|
||||
hasWorldQuickPlaySupport(gameVersions, item.instance.game_version || '')
|
||||
"
|
||||
:quarantined="item.instance.quarantined"
|
||||
:server-status="
|
||||
item.world.type === 'server' ? serverData[item.world.address].status : undefined
|
||||
"
|
||||
|
||||
@@ -77,6 +77,7 @@ const props = withDefaults(
|
||||
startingInstance?: boolean
|
||||
supportsServerQuickPlay?: boolean
|
||||
supportsWorldQuickPlay?: boolean
|
||||
quarantined?: boolean
|
||||
currentProtocol?: ProtocolVersion | null
|
||||
highlighted?: boolean
|
||||
|
||||
@@ -105,6 +106,7 @@ const props = withDefaults(
|
||||
startingInstance: false,
|
||||
supportsServerQuickPlay: true,
|
||||
supportsWorldQuickPlay: false,
|
||||
quarantined: false,
|
||||
currentProtocol: null,
|
||||
|
||||
refreshing: false,
|
||||
@@ -139,7 +141,7 @@ const managed = computed(() => props.managed)
|
||||
const shortcutInstanceId = computed(() => props.shortcutInstanceId ?? props.instanceId)
|
||||
|
||||
async function createShortcut() {
|
||||
if (!shortcutInstanceId.value) return
|
||||
if (!shortcutInstanceId.value || props.quarantined) return
|
||||
|
||||
try {
|
||||
const shortcutPath = await createInstanceShortcut(
|
||||
@@ -422,23 +424,26 @@ const messages = defineMessages({
|
||||
<ButtonStyled v-else>
|
||||
<button
|
||||
v-tooltip="
|
||||
world.type === 'server'
|
||||
? !supportsServerQuickPlay
|
||||
? formatMessage(messages.noServerQuickPlay)
|
||||
: playingOtherWorld
|
||||
? formatMessage(messages.gameAlreadyOpen)
|
||||
: !serverStatus
|
||||
? formatMessage(messages.noContact)
|
||||
: serverIncompatible
|
||||
? formatMessage(messages.incompatibleServer)
|
||||
: null
|
||||
: !supportsWorldQuickPlay
|
||||
? formatMessage(messages.noSingleplayerQuickPlay)
|
||||
: playingOtherWorld || locked
|
||||
? formatMessage(messages.gameAlreadyOpen)
|
||||
: null
|
||||
quarantined
|
||||
? 'This instance has been locked'
|
||||
: world.type === 'server'
|
||||
? !supportsServerQuickPlay
|
||||
? formatMessage(messages.noServerQuickPlay)
|
||||
: playingOtherWorld
|
||||
? formatMessage(messages.gameAlreadyOpen)
|
||||
: !serverStatus
|
||||
? formatMessage(messages.noContact)
|
||||
: serverIncompatible
|
||||
? formatMessage(messages.incompatibleServer)
|
||||
: null
|
||||
: !supportsWorldQuickPlay
|
||||
? formatMessage(messages.noSingleplayerQuickPlay)
|
||||
: playingOtherWorld || locked
|
||||
? formatMessage(messages.gameAlreadyOpen)
|
||||
: null
|
||||
"
|
||||
:disabled="
|
||||
quarantined ||
|
||||
playingOtherWorld ||
|
||||
startingInstance ||
|
||||
(world.type == 'server' && !supportsServerQuickPlay) ||
|
||||
@@ -457,7 +462,7 @@ const messages = defineMessages({
|
||||
{
|
||||
id: 'play-instance',
|
||||
shown: !!instanceId,
|
||||
disabled: playingInstance,
|
||||
disabled: playingInstance || quarantined,
|
||||
action: () => emit('play-instance'),
|
||||
},
|
||||
{
|
||||
@@ -511,7 +516,7 @@ const messages = defineMessages({
|
||||
},
|
||||
{
|
||||
id: 'create-shortcut',
|
||||
shown: !!shortcutInstanceId,
|
||||
shown: !!shortcutInstanceId && !quarantined,
|
||||
action: () => createShortcut(),
|
||||
},
|
||||
{
|
||||
|
||||
@@ -53,6 +53,10 @@ const messages = defineMessages({
|
||||
id: 'app.action-bar.install.unknown-instance',
|
||||
defaultMessage: 'Unknown instance',
|
||||
},
|
||||
updatingSharedContent: {
|
||||
id: 'app.action-bar.install.updating-shared-content',
|
||||
defaultMessage: 'Updating shared content',
|
||||
},
|
||||
})
|
||||
|
||||
const phaseMessages = defineMessages({
|
||||
@@ -268,6 +272,9 @@ export async function useInstallJobNotifications(opts: {
|
||||
version: job.details.major_version,
|
||||
})
|
||||
}
|
||||
if (job.kind === 'update_shared_instance' && job.phase === 'downloading_content') {
|
||||
return formatMessage(messages.updatingSharedContent)
|
||||
}
|
||||
return formatMessage(phaseMessages[job.phase])
|
||||
}
|
||||
|
||||
|
||||
@@ -27,14 +27,14 @@ interface BrowseServerInstance {
|
||||
interface ContextMenuHandle {
|
||||
showMenu: (
|
||||
event: MouseEvent,
|
||||
result: Labrinth.Search.v2.ResultSearchProject | Labrinth.Search.v3.ResultSearchProject,
|
||||
result: Labrinth.Search.v3.ResultSearchProject,
|
||||
options: { name: string }[],
|
||||
) => void
|
||||
}
|
||||
|
||||
interface ContextMenuOptionClick {
|
||||
option: 'open_link' | 'copy_link'
|
||||
item: Labrinth.Search.v2.ResultSearchProject | Labrinth.Search.v3.ResultSearchProject
|
||||
item: Labrinth.Search.v3.ResultSearchProject
|
||||
}
|
||||
|
||||
export interface UseAppServerBrowseOptions {
|
||||
@@ -263,10 +263,7 @@ export function useAppServerBrowse(options: UseAppServerBrowseOptions) {
|
||||
return actions
|
||||
}
|
||||
|
||||
function handleRightClick(
|
||||
event: MouseEvent,
|
||||
result: Labrinth.Search.v2.ResultSearchProject | Labrinth.Search.v3.ResultSearchProject,
|
||||
) {
|
||||
function handleRightClick(event: MouseEvent, result: Labrinth.Search.v3.ResultSearchProject) {
|
||||
contextMenuRef.value?.showMenu(event, result, [{ name: 'open_link' }, { name: 'copy_link' }])
|
||||
}
|
||||
|
||||
@@ -315,9 +312,7 @@ export function useAppServerBrowse(options: UseAppServerBrowseOptions) {
|
||||
}
|
||||
}
|
||||
|
||||
function getProjectUrl(
|
||||
item: Labrinth.Search.v2.ResultSearchProject | Labrinth.Search.v3.ResultSearchProject,
|
||||
) {
|
||||
const projectType = 'project_types' in item ? item.project_types?.[0] : item.project_type
|
||||
function getProjectUrl(item: Labrinth.Search.v3.ResultSearchProject) {
|
||||
const projectType = item.project_types?.[0]
|
||||
return `https://modrinth.com/${projectType ?? 'project'}/${item.slug ?? item.project_id}`
|
||||
}
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
import { type ContentActionWarning, type ContentItem, defineMessages, useVIntl } from '@modrinth/ui'
|
||||
import { computed, type Ref } from 'vue'
|
||||
|
||||
import type { GameInstance } from '@/helpers/types'
|
||||
|
||||
const managedSourceKinds = new Set(['shared_instance', 'modrinth_modpack', 'imported_modpack'])
|
||||
|
||||
export function useManagedContentPolicy(instance: Ref<GameInstance>) {
|
||||
const { formatMessage } = useVIntl()
|
||||
const isManagedModpack = computed(() => instance.value.shared_instance?.role === 'member')
|
||||
const isQuarantined = computed(() => instance.value.quarantined)
|
||||
const canUnpublish = computed(() => instance.value.shared_instance?.role === 'owner')
|
||||
const canUnlink = computed(() => instance.value.shared_instance?.role === 'member')
|
||||
const managedModpackWarning = computed(() => ({
|
||||
admonitionHeader: formatMessage(messages.warningHeader),
|
||||
changeVersionBody: formatMessage(messages.changeVersionBody),
|
||||
unlinkBody: formatMessage(messages.unlinkBody),
|
||||
}))
|
||||
|
||||
function isManagedContent(item: ContentItem) {
|
||||
return (
|
||||
isQuarantined.value ||
|
||||
(isManagedModpack.value && !!item.source_kind && managedSourceKinds.has(item.source_kind))
|
||||
)
|
||||
}
|
||||
|
||||
function canMutateContent(item: ContentItem) {
|
||||
return !isManagedContent(item)
|
||||
}
|
||||
|
||||
function canUpdateContent(item: ContentItem) {
|
||||
return (
|
||||
canMutateContent(item) && !!item.file_path && !!item.has_update && !!item.update_version_id
|
||||
)
|
||||
}
|
||||
|
||||
function deleteWarning(items: ContentItem[]): ContentActionWarning | null {
|
||||
if (!items.some(isManagedContent)) return null
|
||||
return {
|
||||
admonitionHeader: formatMessage(messages.warningHeader),
|
||||
admonitionBody: formatMessage(
|
||||
items.length === 1 ? messages.deleteSingleBody : messages.deleteBulkBody,
|
||||
),
|
||||
actionLabel: formatMessage(
|
||||
items.length === 1 ? messages.deleteButton : messages.deleteManyButton,
|
||||
{ count: items.length },
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
function disableWarning(items: ContentItem[]): ContentActionWarning | null {
|
||||
if (!items.some(isManagedContent)) return null
|
||||
return {
|
||||
admonitionHeader: formatMessage(messages.warningHeader),
|
||||
admonitionBody: formatMessage(
|
||||
items.length === 1 ? messages.disableSingleBody : messages.disableBulkBody,
|
||||
),
|
||||
actionLabel: formatMessage(
|
||||
items.length === 1 ? messages.disableButton : messages.disableManyButton,
|
||||
{ count: items.length },
|
||||
),
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
isManagedModpack,
|
||||
isQuarantined,
|
||||
canUnpublish,
|
||||
canUnlink,
|
||||
managedModpackWarning,
|
||||
isManagedContent,
|
||||
canMutateContent,
|
||||
canUpdateContent,
|
||||
deleteWarning,
|
||||
disableWarning,
|
||||
}
|
||||
}
|
||||
|
||||
const messages = defineMessages({
|
||||
warningHeader: {
|
||||
id: 'content.shared-instance.warning-header',
|
||||
defaultMessage: 'This is part of the shared instance',
|
||||
},
|
||||
changeVersionBody: {
|
||||
id: 'content.shared-instance.change-version-body',
|
||||
defaultMessage:
|
||||
'Changing the version only changes your local copy. Future shared instance updates may restore or change it again.',
|
||||
},
|
||||
unlinkBody: {
|
||||
id: 'content.shared-instance.unlink-body',
|
||||
defaultMessage:
|
||||
'Unlinking only changes your local copy. Future shared instance updates may restore or change it again.',
|
||||
},
|
||||
deleteSingleBody: {
|
||||
id: 'content.shared-instance.delete-single-body',
|
||||
defaultMessage:
|
||||
'Deleting it only changes your local copy. Future shared instance updates may restore or change it again.',
|
||||
},
|
||||
deleteBulkBody: {
|
||||
id: 'content.shared-instance.delete-bulk-body',
|
||||
defaultMessage:
|
||||
'Some selected projects are part of the shared instance. Deleting them only changes your local copy, and future shared instance updates may restore or change them again.',
|
||||
},
|
||||
deleteButton: { id: 'content.shared-instance.delete-button', defaultMessage: 'Delete anyway' },
|
||||
deleteManyButton: {
|
||||
id: 'content.shared-instance.delete-many-button',
|
||||
defaultMessage: 'Delete {count, number} projects anyway',
|
||||
},
|
||||
disableSingleBody: {
|
||||
id: 'content.shared-instance.disable-single-body',
|
||||
defaultMessage:
|
||||
'Disabling it only changes your local copy. Future shared instance updates may re-enable, restore, or change it again.',
|
||||
},
|
||||
disableBulkBody: {
|
||||
id: 'content.shared-instance.disable-bulk-body',
|
||||
defaultMessage:
|
||||
'Some selected projects are part of the shared instance. Disabling them only changes your local copy, and future shared instance updates may re-enable, restore, or change them again.',
|
||||
},
|
||||
disableButton: { id: 'content.shared-instance.disable-button', defaultMessage: 'Disable anyway' },
|
||||
disableManyButton: {
|
||||
id: 'content.shared-instance.disable-many-button',
|
||||
defaultMessage: 'Disable {count, number} projects anyway',
|
||||
},
|
||||
})
|
||||
@@ -0,0 +1,148 @@
|
||||
import { useMutation, useQuery, useQueryClient } from '@tanstack/vue-query'
|
||||
import { computed, type MaybeRefOrGetter, onUnmounted, toValue } from 'vue'
|
||||
|
||||
import { toError } from '@/helpers/errors'
|
||||
import { friend_listener } from '@/helpers/events.js'
|
||||
import {
|
||||
acceptCachedFriend,
|
||||
add_friend,
|
||||
createPendingFriend,
|
||||
type FriendCacheUser,
|
||||
friendsQueryKey,
|
||||
type FriendWithUserData,
|
||||
getFriendsWithUserData,
|
||||
getFriendUserId,
|
||||
matchesFriend,
|
||||
remove_friend,
|
||||
removeCachedFriend,
|
||||
upsertCachedFriend,
|
||||
} from '@/helpers/friends'
|
||||
import type { ModrinthCredentials } from '@/helpers/mr_auth'
|
||||
|
||||
type FriendsMutationContext = {
|
||||
queryKey: ReturnType<typeof friendsQueryKey>
|
||||
previousFriends?: FriendWithUserData[]
|
||||
}
|
||||
|
||||
type AddFriendMutationVariables = {
|
||||
userId: string
|
||||
user: FriendCacheUser
|
||||
acceptExisting: boolean
|
||||
}
|
||||
|
||||
type RemoveFriendMutationVariables = {
|
||||
userId: string
|
||||
user: FriendWithUserData
|
||||
}
|
||||
|
||||
export function useFriends(options: {
|
||||
currentUserId: MaybeRefOrGetter<string | null | undefined>
|
||||
getCredentials: () => ModrinthCredentials | null | Promise<ModrinthCredentials | null>
|
||||
enabled?: MaybeRefOrGetter<boolean>
|
||||
onError?: (error: Error) => void
|
||||
}) {
|
||||
const queryClient = useQueryClient()
|
||||
const queryKey = computed(() => friendsQueryKey(toValue(options.currentUserId)))
|
||||
const query = useQuery({
|
||||
queryKey,
|
||||
queryFn: async () => getFriendsWithUserData(await options.getCredentials()),
|
||||
enabled: () => !!toValue(options.currentUserId) && toValue(options.enabled ?? true),
|
||||
staleTime: 30_000,
|
||||
})
|
||||
const friends = computed(() => query.data.value ?? [])
|
||||
|
||||
function restore(context?: FriendsMutationContext) {
|
||||
if (!context) return
|
||||
if (context.previousFriends === undefined) {
|
||||
queryClient.removeQueries({ queryKey: context.queryKey, exact: true })
|
||||
return
|
||||
}
|
||||
queryClient.setQueryData(context.queryKey, context.previousFriends)
|
||||
}
|
||||
|
||||
const addMutation = useMutation({
|
||||
mutationFn: ({ userId }: AddFriendMutationVariables) => add_friend(userId),
|
||||
onMutate: async ({ user, acceptExisting }): Promise<FriendsMutationContext> => {
|
||||
const activeQueryKey = queryKey.value
|
||||
await queryClient.cancelQueries({ queryKey: activeQueryKey })
|
||||
const previousFriends = queryClient.getQueryData<FriendWithUserData[]>(activeQueryKey)
|
||||
const currentUserId = toValue(options.currentUserId)
|
||||
queryClient.setQueryData<FriendWithUserData[]>(activeQueryKey, (cachedFriends = []) =>
|
||||
acceptExisting
|
||||
? acceptCachedFriend(cachedFriends, user.id, user.username, currentUserId)
|
||||
: upsertCachedFriend(
|
||||
cachedFriends,
|
||||
createPendingFriend(user, currentUserId),
|
||||
currentUserId,
|
||||
),
|
||||
)
|
||||
return { queryKey: activeQueryKey, previousFriends }
|
||||
},
|
||||
onError: (error, _variables, context) => {
|
||||
restore(context)
|
||||
options.onError?.(toError(error))
|
||||
},
|
||||
onSettled: (_data, _error, _variables, context) => {
|
||||
void queryClient.invalidateQueries({ queryKey: context?.queryKey ?? queryKey.value })
|
||||
},
|
||||
})
|
||||
|
||||
const removeMutation = useMutation({
|
||||
mutationFn: ({ userId }: RemoveFriendMutationVariables) => remove_friend(userId),
|
||||
onMutate: async ({ user, userId }): Promise<FriendsMutationContext> => {
|
||||
const activeQueryKey = queryKey.value
|
||||
await queryClient.cancelQueries({ queryKey: activeQueryKey })
|
||||
const previousFriends = queryClient.getQueryData<FriendWithUserData[]>(activeQueryKey)
|
||||
queryClient.setQueryData<FriendWithUserData[]>(activeQueryKey, (cachedFriends = []) =>
|
||||
removeCachedFriend(cachedFriends, userId, user.username, toValue(options.currentUserId)),
|
||||
)
|
||||
return { queryKey: activeQueryKey, previousFriends }
|
||||
},
|
||||
onError: (error, _variables, context) => {
|
||||
restore(context)
|
||||
options.onError?.(toError(error))
|
||||
},
|
||||
onSettled: (_data, _error, _variables, context) => {
|
||||
void queryClient.invalidateQueries({ queryKey: context?.queryKey ?? queryKey.value })
|
||||
},
|
||||
})
|
||||
|
||||
function requestFriend(user: FriendCacheUser, acceptExisting = false) {
|
||||
addMutation.mutate({ userId: user.id, user, acceptExisting })
|
||||
}
|
||||
|
||||
function acceptFriend(friend: FriendWithUserData) {
|
||||
const userId = getFriendUserId(friend, toValue(options.currentUserId))
|
||||
requestFriend({ id: userId, username: friend.username, avatarUrl: friend.avatar }, true)
|
||||
}
|
||||
|
||||
function removeFriend(friend: FriendWithUserData) {
|
||||
const userId = getFriendUserId(friend, toValue(options.currentUserId))
|
||||
removeMutation.mutate({ userId, user: friend })
|
||||
}
|
||||
|
||||
function findFriend(id: string, username: string) {
|
||||
return friends.value.find((friend) =>
|
||||
matchesFriend(friend, id, username, toValue(options.currentUserId)),
|
||||
)
|
||||
}
|
||||
|
||||
let unlisten: (() => void) | undefined
|
||||
void friend_listener(() => {
|
||||
void queryClient.invalidateQueries({ queryKey: queryKey.value })
|
||||
}).then((listener) => {
|
||||
unlisten = listener
|
||||
})
|
||||
onUnmounted(() => unlisten?.())
|
||||
|
||||
return {
|
||||
query,
|
||||
queryKey,
|
||||
friends,
|
||||
loading: computed(() => !!toValue(options.currentUserId) && query.isLoading.value),
|
||||
requestFriend,
|
||||
acceptFriend,
|
||||
removeFriend,
|
||||
findFriend,
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
import { useQuery } from '@tanstack/vue-query'
|
||||
import { computed, type Ref } from 'vue'
|
||||
|
||||
import { get_user } from '@/helpers/cache.js'
|
||||
|
||||
export function useUserQuery(userId: Ref<string | null | undefined>) {
|
||||
return useQuery({
|
||||
queryKey: computed(() => ['user', userId.value]),
|
||||
queryFn: async ({ queryKey }) => {
|
||||
const id = queryKey[1]
|
||||
if (typeof id !== 'string') return null
|
||||
return await get_user(id, 'bypass').catch(() => null)
|
||||
},
|
||||
enabled: () => !!userId.value,
|
||||
staleTime: 30_000,
|
||||
})
|
||||
}
|
||||
@@ -7,6 +7,9 @@ const labrinthBaseUrl = trimTrailingSlash(
|
||||
const archonBaseUrl = trimTrailingSlash(
|
||||
import.meta.env.MODRINTH_ARCHON_BASE_URL || 'https://archon.modrinth.com',
|
||||
)
|
||||
const sharedInstancesBaseUrl = trimTrailingSlash(
|
||||
import.meta.env.SHARED_INSTANCES_API_BASE_URL || 'https://shared-instances.modrinth.com',
|
||||
)
|
||||
|
||||
export const config = {
|
||||
siteUrl,
|
||||
@@ -15,4 +18,5 @@ export const config = {
|
||||
'pk_test_51JbFxJJygY5LJFfKV50mnXzz3YLvBVe2Gd1jn7ljWAkaBlRz3VQdxN9mXcPSrFbSqxwAb0svte9yhnsmm7qHfcWn00R611Ce7b',
|
||||
labrinthBaseUrl,
|
||||
archonBaseUrl,
|
||||
sharedInstancesBaseUrl,
|
||||
}
|
||||
|
||||
@@ -16,8 +16,8 @@ export async function hide_ads_window(reset) {
|
||||
return await invoke('plugin:ads|hide_ads_window', { reset })
|
||||
}
|
||||
|
||||
export async function get_ads_consent_required() {
|
||||
return await invoke('plugin:ads|get_ads_consent_required')
|
||||
export async function should_show_ads_consent_popup() {
|
||||
return await invoke('plugin:ads|should_show_ads_consent_popup')
|
||||
}
|
||||
|
||||
export async function perform_ads_consent_action(action) {
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
export function toError(error: unknown) {
|
||||
if (error instanceof Error) return error
|
||||
if (typeof error === 'string') return new Error(error)
|
||||
if (error && typeof error === 'object') {
|
||||
const record = error as Record<string, unknown>
|
||||
const message = record.message ?? record.error
|
||||
if (typeof message === 'string') return new Error(message)
|
||||
return new Error(JSON.stringify(error))
|
||||
}
|
||||
return new Error(String(error))
|
||||
}
|
||||
@@ -6,6 +6,8 @@ import dayjs from 'dayjs'
|
||||
import { get_user_many } from '@/helpers/cache'
|
||||
import type { ModrinthCredentials } from '@/helpers/mr_auth'
|
||||
|
||||
export const friendsQueryKey = (userId?: string | null) => ['friends', userId ?? null] as const
|
||||
|
||||
export type UserStatus = {
|
||||
user_id: string
|
||||
instance_name: string | null
|
||||
@@ -46,6 +48,111 @@ export type FriendWithUserData = {
|
||||
online: boolean
|
||||
avatar: string
|
||||
}
|
||||
|
||||
export type FriendCacheUser = {
|
||||
id: string
|
||||
username: string
|
||||
avatarUrl?: string | null
|
||||
}
|
||||
|
||||
export async function getFriendsWithUserData(
|
||||
credentials: ModrinthCredentials | null,
|
||||
): Promise<FriendWithUserData[]> {
|
||||
if (!credentials) return []
|
||||
|
||||
const friendsList = await friends()
|
||||
return await transformFriends(friendsList, credentials)
|
||||
}
|
||||
|
||||
export function createPendingFriend(
|
||||
user: FriendCacheUser,
|
||||
currentUserId?: string | null,
|
||||
): FriendWithUserData {
|
||||
return {
|
||||
id: user.id,
|
||||
friend_id: currentUserId ?? null,
|
||||
status: null,
|
||||
last_updated: null,
|
||||
created: dayjs(),
|
||||
username: user.username,
|
||||
accepted: false,
|
||||
online: false,
|
||||
avatar: user.avatarUrl ?? '',
|
||||
}
|
||||
}
|
||||
|
||||
export function getFriendUserId(
|
||||
friend: Pick<FriendWithUserData, 'id' | 'friend_id'>,
|
||||
currentUserId?: string | null,
|
||||
) {
|
||||
return friend.id === currentUserId && friend.friend_id ? friend.friend_id : friend.id
|
||||
}
|
||||
|
||||
export function matchesFriend(
|
||||
friend: FriendWithUserData,
|
||||
id: string,
|
||||
username: string,
|
||||
currentUserId?: string | null,
|
||||
) {
|
||||
const friendId = getFriendUserId(friend, currentUserId)
|
||||
return (
|
||||
normalizeFriendKey(friendId) === normalizeFriendKey(id) ||
|
||||
normalizeFriendKey(friend.username) === normalizeFriendKey(username)
|
||||
)
|
||||
}
|
||||
|
||||
export function upsertCachedFriend(
|
||||
friends: FriendWithUserData[],
|
||||
friend: FriendWithUserData,
|
||||
currentUserId?: string | null,
|
||||
) {
|
||||
const existingFriend = friends.find((cachedFriend) =>
|
||||
matchesFriend(cachedFriend, friend.id, friend.username, currentUserId),
|
||||
)
|
||||
|
||||
if (!existingFriend) return [friend, ...friends]
|
||||
|
||||
return friends.map((cachedFriend) =>
|
||||
matchesFriend(cachedFriend, friend.id, friend.username, currentUserId)
|
||||
? {
|
||||
...cachedFriend,
|
||||
...friend,
|
||||
id: cachedFriend.id,
|
||||
friend_id: cachedFriend.friend_id,
|
||||
}
|
||||
: cachedFriend,
|
||||
)
|
||||
}
|
||||
|
||||
export function acceptCachedFriend(
|
||||
friends: FriendWithUserData[],
|
||||
id: string,
|
||||
username: string,
|
||||
currentUserId?: string | null,
|
||||
) {
|
||||
return friends.map((friend) =>
|
||||
matchesFriend(friend, id, username, currentUserId)
|
||||
? {
|
||||
...friend,
|
||||
accepted: true,
|
||||
}
|
||||
: friend,
|
||||
)
|
||||
}
|
||||
|
||||
export function removeCachedFriend(
|
||||
friends: FriendWithUserData[],
|
||||
id: string,
|
||||
username: string,
|
||||
currentUserId?: string | null,
|
||||
) {
|
||||
return friends.filter((friend) => !matchesFriend(friend, id, username, currentUserId))
|
||||
}
|
||||
|
||||
export function normalizeFriendKey(value: string) {
|
||||
return value.trim().toLowerCase()
|
||||
}
|
||||
|
||||
export async function transformFriends(
|
||||
friends: UserFriend[],
|
||||
credentials: ModrinthCredentials | null,
|
||||
|
||||
@@ -45,6 +45,92 @@ export interface InstallPostInstallEdit {
|
||||
link?: InstanceLink | null
|
||||
}
|
||||
|
||||
export interface SharedInstanceInstallPreview {
|
||||
sharedInstanceId: string
|
||||
version: number
|
||||
name: string
|
||||
iconUrl?: string | null
|
||||
gameVersion: string
|
||||
loader: InstanceLoader
|
||||
modCount: number
|
||||
externalFileCount: number
|
||||
modpackVersionId?: string | null
|
||||
contentVersionIds: string[]
|
||||
externalFiles: SharedInstanceExternalFilePreview[]
|
||||
}
|
||||
|
||||
export interface SharedInstanceInviteInstallPreview {
|
||||
sharedInstanceId: string
|
||||
managerId?: string | null
|
||||
serverManagerName?: string | null
|
||||
serverManagerIconUrl?: string | null
|
||||
instanceIconUrl?: string | null
|
||||
preview: SharedInstanceInstallPreview
|
||||
}
|
||||
|
||||
export interface SharedInstanceExternalFilePreview {
|
||||
fileName: string
|
||||
fileType: string
|
||||
}
|
||||
|
||||
export interface SharedInstanceUpdatePreview {
|
||||
sharedInstanceId: string
|
||||
currentVersion?: number | null
|
||||
latestVersion: number
|
||||
updateAvailable: boolean
|
||||
diffs: SharedInstanceUpdateDiff[]
|
||||
}
|
||||
|
||||
export interface SharedInstanceUpdateDiff {
|
||||
type:
|
||||
| 'added'
|
||||
| 'removed'
|
||||
| 'updated'
|
||||
| 'modpack_linked'
|
||||
| 'modpack_updated'
|
||||
| 'modpack_unlinked'
|
||||
| 'game_version_updated'
|
||||
| 'loader_updated'
|
||||
| 'config_files_updated'
|
||||
projectId?: string | null
|
||||
projectName?: string | null
|
||||
fileName?: string | null
|
||||
currentVersionName?: string | null
|
||||
newVersionName?: string | null
|
||||
configFileCount?: number | null
|
||||
disabled?: boolean
|
||||
}
|
||||
|
||||
export const SHARED_INSTANCE_UNAVAILABLE_ERROR_CODE = 'shared_instance_unavailable'
|
||||
|
||||
export type SharedInstanceUnavailableReason = 'deleted' | 'access_revoked' | 'quarantined'
|
||||
|
||||
function isRecord(value: unknown): value is Record<string, unknown> {
|
||||
return typeof value === 'object' && value !== null
|
||||
}
|
||||
|
||||
export function isSharedInstanceUnavailableError(error: unknown) {
|
||||
return getSharedInstanceUnavailableReason(error) !== null
|
||||
}
|
||||
|
||||
export function getSharedInstanceUnavailableReason(
|
||||
error: unknown,
|
||||
): SharedInstanceUnavailableReason | null {
|
||||
if (!isRecord(error) || error.code !== SHARED_INSTANCE_UNAVAILABLE_ERROR_CODE) return null
|
||||
return error.reason === 'deleted' ||
|
||||
error.reason === 'access_revoked' ||
|
||||
error.reason === 'quarantined'
|
||||
? error.reason
|
||||
: null
|
||||
}
|
||||
|
||||
export function getErrorMessage(error: unknown): string {
|
||||
if (typeof error === 'string') return error
|
||||
if (error instanceof Error) return error.message || 'Unknown error'
|
||||
if (isRecord(error) && typeof error.message === 'string') return error.message
|
||||
return 'Unknown error'
|
||||
}
|
||||
|
||||
export type InstallJobStatus =
|
||||
| 'queued'
|
||||
| 'running'
|
||||
@@ -90,6 +176,7 @@ export interface InstallErrorView {
|
||||
code: string
|
||||
phase?: InstallPhaseId | null
|
||||
message: string
|
||||
reason?: SharedInstanceUnavailableReason | null
|
||||
api?: {
|
||||
error: string
|
||||
status?: number | null
|
||||
@@ -122,6 +209,8 @@ export interface InstallJobSnapshot {
|
||||
kind:
|
||||
| 'create_instance'
|
||||
| 'create_modpack_instance'
|
||||
| 'create_shared_instance'
|
||||
| 'update_shared_instance'
|
||||
| 'import_instance'
|
||||
| 'duplicate_instance'
|
||||
| 'install_existing_instance'
|
||||
@@ -172,6 +261,58 @@ export async function install_create_modpack_instance(
|
||||
})
|
||||
}
|
||||
|
||||
export async function install_get_shared_instance_preview(sharedInstanceId: string, name: string) {
|
||||
return await invoke<SharedInstanceInstallPreview>(
|
||||
'plugin:install|install_get_shared_instance_preview',
|
||||
{
|
||||
sharedInstanceId,
|
||||
name,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
export async function install_accept_shared_instance_invite(inviteId: string) {
|
||||
return await invoke<SharedInstanceInviteInstallPreview>(
|
||||
'plugin:install|install_accept_shared_instance_invite',
|
||||
{
|
||||
inviteId,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
export async function install_get_shared_instance_update_preview(instanceId: string) {
|
||||
return await invoke<SharedInstanceUpdatePreview | null>(
|
||||
'plugin:install|install_get_shared_instance_update_preview',
|
||||
{
|
||||
instanceId,
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
export async function install_shared_instance(
|
||||
sharedInstanceId: string,
|
||||
name: string,
|
||||
managerId?: string | null,
|
||||
serverManagerName?: string | null,
|
||||
serverManagerIconUrl?: string | null,
|
||||
instanceIconUrl?: string | null,
|
||||
) {
|
||||
return await invoke<InstallJobSnapshot>('plugin:install|install_shared_instance', {
|
||||
sharedInstanceId,
|
||||
name,
|
||||
managerId,
|
||||
serverManagerName,
|
||||
serverManagerIconUrl,
|
||||
instanceIconUrl,
|
||||
})
|
||||
}
|
||||
|
||||
export async function install_update_shared_instance(instanceId: string) {
|
||||
return await invoke<InstallJobSnapshot>('plugin:install|install_update_shared_instance', {
|
||||
instanceId,
|
||||
})
|
||||
}
|
||||
|
||||
export async function install_import_instance(
|
||||
launcherType: string,
|
||||
basePath: string,
|
||||
@@ -249,7 +390,8 @@ export function isInstallJobFinished(status: InstallJobStatus) {
|
||||
function settleInstallJob(job: InstallJobSnapshot) {
|
||||
if (job.status === 'succeeded') return job
|
||||
|
||||
throw new Error(job.error?.message ?? `Install job ${job.job_id} ${job.status}`)
|
||||
if (job.error) throw job.error
|
||||
throw new Error(`Install job ${job.job_id} ${job.status}`)
|
||||
}
|
||||
|
||||
export async function wait_for_install_job(jobId: string) {
|
||||
|
||||
@@ -7,13 +7,14 @@ import type { Labrinth } from '@modrinth/api-client'
|
||||
import type { ContentItem, ContentOwner } from '@modrinth/ui'
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
|
||||
import type { InstallJobSnapshot } from './install'
|
||||
import type { InstallJobSnapshot, SharedInstanceUpdateDiff } from './install'
|
||||
import type {
|
||||
CacheBehaviour,
|
||||
ContentFile,
|
||||
ContentFileProjectType,
|
||||
GameInstance,
|
||||
InstanceLoader,
|
||||
SharedInstanceAttachment,
|
||||
} from './types'
|
||||
|
||||
export async function remove(instanceId: string): Promise<void> {
|
||||
@@ -335,3 +336,93 @@ export async function edit(instanceId: string, editInstance: Partial<GameInstanc
|
||||
export async function edit_icon(instanceId: string, iconPath: string | null): Promise<void> {
|
||||
return await invoke('plugin:instance|instance_edit_icon', { instanceId, iconPath })
|
||||
}
|
||||
|
||||
export type SharedInstanceUsers = {
|
||||
user_ids: string[]
|
||||
users: SharedInstanceUser[]
|
||||
tokens: number
|
||||
}
|
||||
|
||||
export type SharedInstanceJoinType = 'owner' | 'invite' | 'link'
|
||||
|
||||
export type SharedInstanceUser = {
|
||||
id: string
|
||||
joined_at?: string | null
|
||||
join_type: SharedInstanceJoinType
|
||||
last_played?: string | null
|
||||
}
|
||||
|
||||
export interface SharedInstancePublishPreview {
|
||||
sharedInstanceId: string
|
||||
latestVersion: number
|
||||
diffs: SharedInstanceUpdateDiff[]
|
||||
configFiles: string[]
|
||||
}
|
||||
|
||||
export interface SharedInstanceInviteLink {
|
||||
inviteId: string
|
||||
expiresAt: string
|
||||
maxUses: number
|
||||
}
|
||||
|
||||
export async function can_current_user_use_shared_instances(): Promise<boolean> {
|
||||
return await invoke('plugin:instance|instance_share_can_current_user_use')
|
||||
}
|
||||
|
||||
export async function get_shared_instance_users(instanceId: string): Promise<SharedInstanceUsers> {
|
||||
return await invoke('plugin:instance|instance_share_get_users', { instanceId })
|
||||
}
|
||||
|
||||
export async function invite_shared_instance_users(
|
||||
instanceId: string,
|
||||
userIds: string[],
|
||||
): Promise<SharedInstanceUsers> {
|
||||
return await invoke('plugin:instance|instance_share_invite_users', { instanceId, userIds })
|
||||
}
|
||||
|
||||
export async function create_shared_instance_invite_link(
|
||||
instanceId: string,
|
||||
options: {
|
||||
maxAgeSeconds?: number
|
||||
maxUses?: number
|
||||
replaceInviteId?: string
|
||||
} = {},
|
||||
): Promise<SharedInstanceInviteLink> {
|
||||
return await invoke('plugin:instance|instance_share_create_invite_link', {
|
||||
instanceId,
|
||||
...options,
|
||||
})
|
||||
}
|
||||
|
||||
export async function remove_shared_instance_users(
|
||||
instanceId: string,
|
||||
userIds: string[],
|
||||
hasPendingRecipients: boolean,
|
||||
): Promise<SharedInstanceUsers> {
|
||||
return await invoke('plugin:instance|instance_share_remove_users', {
|
||||
instanceId,
|
||||
userIds,
|
||||
hasPendingRecipients,
|
||||
})
|
||||
}
|
||||
|
||||
export async function get_shared_instance_publish_preview(
|
||||
instanceId: string,
|
||||
): Promise<SharedInstancePublishPreview | null> {
|
||||
return await invoke('plugin:instance|instance_share_get_publish_preview', { instanceId })
|
||||
}
|
||||
|
||||
export async function publish_shared_instance(
|
||||
instanceId: string,
|
||||
configPaths: string[],
|
||||
): Promise<SharedInstanceAttachment> {
|
||||
return await invoke('plugin:instance|instance_share_publish', { instanceId, configPaths })
|
||||
}
|
||||
|
||||
export async function unlink_shared_instance(instanceId: string): Promise<void> {
|
||||
return await invoke('plugin:instance|instance_share_unlink', { instanceId })
|
||||
}
|
||||
|
||||
export async function unpublish_shared_instance(instanceId: string): Promise<void> {
|
||||
return await invoke('plugin:instance|instance_share_unpublish', { instanceId })
|
||||
}
|
||||
|
||||
@@ -12,8 +12,10 @@ export type ModrinthCredentials = {
|
||||
active: boolean
|
||||
}
|
||||
|
||||
export async function login(): Promise<ModrinthCredentials> {
|
||||
return await invoke('plugin:mr-auth|modrinth_login')
|
||||
export type ModrinthAuthFlow = 'sign-in' | 'sign-up'
|
||||
|
||||
export async function login(flow: ModrinthAuthFlow = 'sign-in'): Promise<ModrinthCredentials> {
|
||||
return await invoke('plugin:mr-auth|modrinth_login', { flow })
|
||||
}
|
||||
|
||||
export async function logout(): Promise<void> {
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
|
||||
export type ReportItemType = 'project' | 'version' | 'user' | 'shared-instance'
|
||||
|
||||
export interface CreateReportRequest {
|
||||
report_type: string
|
||||
item_id: string
|
||||
item_type: ReportItemType
|
||||
body: string
|
||||
uploaded_images: string[]
|
||||
}
|
||||
|
||||
export interface CreateReportResponse {
|
||||
id: string
|
||||
}
|
||||
|
||||
export async function create_report(request: CreateReportRequest) {
|
||||
return await invoke<CreateReportResponse>('plugin:reports|reports_create', { request })
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
import { defineMessages, injectNotificationManager, useVIntl } from '@modrinth/ui'
|
||||
|
||||
import { getErrorMessage, type SharedInstanceUnavailableReason } from '@/helpers/install'
|
||||
|
||||
export const sharedInstanceErrorMessages = defineMessages({
|
||||
unavailableTitle: {
|
||||
id: 'instance.shared-instance.unavailable.title',
|
||||
defaultMessage: 'Shared instance no longer available',
|
||||
},
|
||||
lockedTitle: {
|
||||
id: 'instance.shared-instance.unavailable.locked-title',
|
||||
defaultMessage: 'Instance locked',
|
||||
},
|
||||
unavailableText: {
|
||||
id: 'instance.shared-instance.unavailable.text',
|
||||
defaultMessage:
|
||||
"Your local instance is still available, but it is no longer linked and won't receive updates.",
|
||||
},
|
||||
deletedText: {
|
||||
id: 'instance.shared-instance.unavailable.deleted-text',
|
||||
defaultMessage:
|
||||
'The primary instance was deleted. This instance is still available, but it is no longer linked and will no longer receive updates.',
|
||||
},
|
||||
accessRevokedText: {
|
||||
id: 'instance.shared-instance.unavailable.access-revoked-text',
|
||||
defaultMessage:
|
||||
'Your access to the shared instance was revoked. This instance is still available, but it is no longer linked and will no longer receive updates.',
|
||||
},
|
||||
lockedText: {
|
||||
id: 'instance.shared-instance.unavailable.locked-text',
|
||||
defaultMessage:
|
||||
'This shared instance was locked by the Content Moderation team. It will no longer receive updates from the primary instance and cannot be played.',
|
||||
},
|
||||
unavailableFallbackManager: {
|
||||
id: 'instance.shared-instance.unavailable.manager-fallback',
|
||||
defaultMessage: 'the instance manager',
|
||||
},
|
||||
errorTitle: {
|
||||
id: 'instance.shared-instance.error.title',
|
||||
defaultMessage: 'Something has gone wrong',
|
||||
},
|
||||
})
|
||||
|
||||
export function sharedInstanceUnavailableTextMessage(
|
||||
reason: SharedInstanceUnavailableReason | null,
|
||||
) {
|
||||
if (reason === 'deleted') return sharedInstanceErrorMessages.deletedText
|
||||
if (reason === 'access_revoked') return sharedInstanceErrorMessages.accessRevokedText
|
||||
if (reason === 'quarantined') return sharedInstanceErrorMessages.lockedText
|
||||
return sharedInstanceErrorMessages.unavailableText
|
||||
}
|
||||
|
||||
export function sharedInstanceUnavailableTitleMessage(
|
||||
reason: SharedInstanceUnavailableReason | null,
|
||||
) {
|
||||
return reason === 'quarantined'
|
||||
? sharedInstanceErrorMessages.lockedTitle
|
||||
: sharedInstanceErrorMessages.unavailableTitle
|
||||
}
|
||||
|
||||
export function useSharedInstanceErrors() {
|
||||
const { formatMessage } = useVIntl()
|
||||
const { addNotification } = injectNotificationManager()
|
||||
|
||||
function formatSharedInstanceUnavailable(
|
||||
reason: SharedInstanceUnavailableReason | null = null,
|
||||
manager?: string | null,
|
||||
) {
|
||||
return formatMessage(sharedInstanceUnavailableTextMessage(reason), {
|
||||
manager: manager || formatMessage(sharedInstanceErrorMessages.unavailableFallbackManager),
|
||||
})
|
||||
}
|
||||
|
||||
function notifySharedInstanceUnavailable(
|
||||
reason: SharedInstanceUnavailableReason | null = null,
|
||||
manager?: string | null,
|
||||
) {
|
||||
addNotification({
|
||||
type: 'warning',
|
||||
title: formatMessage(sharedInstanceUnavailableTitleMessage(reason)),
|
||||
text: formatSharedInstanceUnavailable(reason, manager),
|
||||
})
|
||||
}
|
||||
|
||||
function notifySharedInstanceError(error: unknown) {
|
||||
addNotification({
|
||||
type: 'error',
|
||||
title: formatMessage(sharedInstanceErrorMessages.errorTitle),
|
||||
text: getErrorMessage(error),
|
||||
})
|
||||
}
|
||||
|
||||
return {
|
||||
formatSharedInstanceUnavailable,
|
||||
notifySharedInstanceError,
|
||||
notifySharedInstanceUnavailable,
|
||||
}
|
||||
}
|
||||
+32
-1
@@ -17,6 +17,8 @@ export type GameInstance = {
|
||||
groups: string[]
|
||||
|
||||
link?: InstanceLink | null
|
||||
shared_instance?: SharedInstanceAttachment | null
|
||||
quarantined: boolean
|
||||
update_channel: ReleaseChannel
|
||||
|
||||
created: Date
|
||||
@@ -86,18 +88,47 @@ export type InstanceLink = InstanceLinkIdentity &
|
||||
}
|
||||
| {
|
||||
type: 'shared_instance'
|
||||
shared_instance_id: string
|
||||
modpack_project_id?: ModrinthId | null
|
||||
modpack_version_id?: ModrinthId | null
|
||||
}
|
||||
)
|
||||
|
||||
export type SharedInstanceAttachment = {
|
||||
id: string
|
||||
role: 'owner' | 'member'
|
||||
manager_id?: string | null
|
||||
server_manager_name?: string | null
|
||||
server_manager_icon_url?: string | null
|
||||
linked_user_id?: string | null
|
||||
status:
|
||||
| 'unknown'
|
||||
| 'up_to_date'
|
||||
| 'update_available'
|
||||
| 'applying'
|
||||
| 'stale'
|
||||
| 'not_ready'
|
||||
| 'error'
|
||||
applied_version?: number | null
|
||||
latest_version?: number | null
|
||||
}
|
||||
|
||||
export type Instance = GameInstance
|
||||
|
||||
type ReleaseChannel = 'release' | 'beta' | 'alpha'
|
||||
|
||||
export type InstanceLoader = 'vanilla' | 'forge' | 'fabric' | 'quilt' | 'neoforge'
|
||||
|
||||
export type ContentSourceKind =
|
||||
| 'local'
|
||||
| 'modrinth_modpack'
|
||||
| 'server_project'
|
||||
| 'modrinth_hosting'
|
||||
| 'imported_modpack'
|
||||
| 'shared_instance'
|
||||
|
||||
type ContentFile = {
|
||||
enabled: boolean
|
||||
source_kind?: ContentSourceKind | null
|
||||
metadata?: {
|
||||
project_id: string
|
||||
version_id: string
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
import { invoke } from '@tauri-apps/api/core'
|
||||
|
||||
export type SearchUser = {
|
||||
id: string
|
||||
username: string
|
||||
avatar_url: string | null
|
||||
}
|
||||
|
||||
export async function search_user(query: string): Promise<SearchUser[]> {
|
||||
return await invoke<SearchUser[]>('plugin:users|search_user', { query })
|
||||
}
|
||||
@@ -125,6 +125,15 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "عرض التسجيل"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "قبول الكل"
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "إدارة التفضيلات"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "رفض الكل"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "يتيح العرض المتقدم لتأثيرات مثل التشويش الذي قد تسبب مشكلات في الأداء دون استخدام العرض المسرع بالأجهزة."
|
||||
},
|
||||
@@ -428,24 +437,33 @@
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "نزل للعب"
|
||||
},
|
||||
"app.modal.install-to-play.install-anyway": {
|
||||
"message": "تثبيت على أي حال"
|
||||
},
|
||||
"app.modal.install-to-play.install-button": {
|
||||
"message": "تثبيت"
|
||||
},
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# تعديل} other {# تعديلات}}"
|
||||
},
|
||||
"app.modal.install-to-play.reviewed-files": {
|
||||
"message": "لا يتم مراجعة الملف إلا إذا تم نشره على Modrinth، بغض النظر عن صيغته (بما في ذلك .mrpack)."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "النماذج المشتركة"
|
||||
},
|
||||
"app.modal.install-to-play.unknown-files-warning": {
|
||||
"message": "تحذير ملفات غير معروفة"
|
||||
},
|
||||
"app.modal.install-to-play.unrecognized-files": {
|
||||
"message": "ملفات غير متعرّف عليها"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "عرض المحتويات"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "حدث للعب"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "هناك تحديث مطلوب للعب بـ {name}. الرجاء التحديث إلى أحدث اصدار لتشغيل اللعبة."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "هذا المشروع مُثبَّت بالفعل"
|
||||
},
|
||||
@@ -641,6 +659,12 @@
|
||||
"app.skins.title": {
|
||||
"message": "اختيار المظهر"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "إيقاف"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "تشغيل"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "انتهى تنزيل تطبيق Modrinth v{version}. أعد التحميل للتحديث الآن، أو تلقائيًا عند إغلاق تطبيق Modrinth."
|
||||
},
|
||||
@@ -752,6 +776,24 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>سجّل الدخول إلى حساب Modrinth</link> لإضافة الأصدقاء ومعرفة ما الذي يلعبونه!"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "إنشاء اختصار"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "مزيد من الخيارات"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "فتح المجلد"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "إصلاح"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "قيد التشغيل..."
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "قيد الإيقاف..."
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "إضافة واللعب"
|
||||
},
|
||||
@@ -794,6 +836,9 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "حفظ ك..."
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "لم تُلعب من قبل"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "العنوان"
|
||||
},
|
||||
|
||||
@@ -380,9 +380,6 @@
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Aktualizuj pro hraní"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Pro hraní {name} je vyžadována aktualizace. Prosím aktualizuj na nejnovější verzi, abys mohl hru spustit."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Tento projekt je již nainstalován"
|
||||
},
|
||||
|
||||
@@ -11,6 +11,12 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Gem flere kørende instances"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Kopiere"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Kopier detaljer"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Tilsidesæt"
|
||||
},
|
||||
@@ -20,6 +26,27 @@
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Prøv igen"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Annulleret på grund af appen blev lukket"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Annulleret"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Kunne ikke download filer"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "Downloaded filer er korrupt"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Kunne ikke gemme filer"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "Download kunne ikke blive fuldført"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "Instance kunne ikke blive fundet"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Ukendt instance"
|
||||
},
|
||||
@@ -287,9 +314,6 @@
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Opdater for at spille"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "En opdatering er krævet for at spille {name}. Venligst opdater til den seneste version for at køre spillet."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Dette projekt er allerede installeret"
|
||||
},
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"message": "Bereinigung konnte nicht abgeschlossen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Dateien konnte nicht heruntergeladen werden"
|
||||
"message": "Dateien konnten nicht heruntergeladen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "Heruntergeladene Datei ist beschädigt"
|
||||
@@ -84,11 +84,14 @@
|
||||
"message": "Das Pack konnte nicht heruntergeladen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "Irgendwas ist schiefgelaufen"
|
||||
"message": "Etwas ist schiefgelaufen"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Unbekannte Instanz"
|
||||
},
|
||||
"app.action-bar.install.updating-shared-content": {
|
||||
"message": "Geteilte Inhalte werden aktualisiert"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "Installationen"
|
||||
},
|
||||
@@ -125,6 +128,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Protokolle anzeigen"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "Alle akzeptieren"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "Werbung ermöglicht Modrinth und finanziert die Auszahlungen an die Ersteller. Unsere Partner speichern möglicherweise Cookies in der App oder greifen auf diese zu, um Werbung zu personalisieren und die Leistung zu messen."
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "Einstellungen verwalten"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "Alle ablehnen"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "Deine Privatsphäre und wie Werbung Modrinth unterstützt"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Aktiviert erweiterte Rendering-Funktionen wie Unschärfeeffekte, welche ohne hardwarebeschleunigtes Rendering zu Leistungsproblemen führen können."
|
||||
},
|
||||
@@ -323,6 +341,36 @@
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Loader-Prozesse werden ausgeführt"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.added-label": {
|
||||
"message": "Hinzugefügt"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-body": {
|
||||
"message": "Deine lokale Instanz ist den Benutzern, mit denen du sie geteilt hast, voraus."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-header": {
|
||||
"message": "Deine Änderungen wurden noch nicht geteilt"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publish-button": {
|
||||
"message": "Update senden"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publishing-button": {
|
||||
"message": "Wird gesendet..."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.removed-label": {
|
||||
"message": "Entfernt"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-admonition-header": {
|
||||
"message": "Update senden"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-description": {
|
||||
"message": "Überprüfe die Inhaltsänderungen, die allen Nutzern dieser Instanz bereitgestellt werden."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-header": {
|
||||
"message": "Änderungen überprüfen"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.reviewing-button": {
|
||||
"message": "Wird überprüft..."
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "Alle Daten deiner Instanz werden permanent gelöscht, inlusive deiner Welten, Konfigurationen und allen installierten Inhalten."
|
||||
},
|
||||
@@ -359,6 +407,9 @@
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "Projekt"
|
||||
},
|
||||
"app.instance.mods.locked-content": {
|
||||
"message": "Inhalte in gesperrten Instanzen können nicht geändert werden."
|
||||
},
|
||||
"app.instance.mods.project-was-added": {
|
||||
"message": "\"{name}\" wurde hinzugefügt"
|
||||
},
|
||||
@@ -374,6 +425,102 @@
|
||||
"app.instance.mods.successfully-uploaded": {
|
||||
"message": "Erfolgreich hochgeladen"
|
||||
},
|
||||
"app.instance.share.empty.description": {
|
||||
"message": "Du kannst diese Instanz mit deinen Freunden teilen!"
|
||||
},
|
||||
"app.instance.share.empty.heading": {
|
||||
"message": "Keine Freunde eingeladen"
|
||||
},
|
||||
"app.instance.share.empty.invite-friends-button": {
|
||||
"message": "Freunde einladen"
|
||||
},
|
||||
"app.instance.share.invite-modal.heading": {
|
||||
"message": "{name} teilen"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-prefix": {
|
||||
"message": "Du musst dich als"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-suffix": {
|
||||
"message": "anmelden um diese Seite aufzurufen."
|
||||
},
|
||||
"app.instance.share.locked.linked-account-fallback": {
|
||||
"message": "das verknüpfte Konto"
|
||||
},
|
||||
"app.instance.share.locked.signed-out-heading": {
|
||||
"message": "Nicht angemeldet"
|
||||
},
|
||||
"app.instance.share.locked.switch-account-button": {
|
||||
"message": "Konto wechseln"
|
||||
},
|
||||
"app.instance.share.locked.wrong-account-heading": {
|
||||
"message": "Falsches Konto"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-access": {
|
||||
"message": "Diese Person wird für diese geteilte Instanz erhalten keine Updates mehr erhalten"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-installed-copy": {
|
||||
"message": "Jede bereits installierte Kopie bleibt auf deren Gerät erhalten"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-invite-again": {
|
||||
"message": "Du kannst diese Person später erneut einladen"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-last-user": {
|
||||
"message": "Dies ist der letzte Benutzer, das Teilen wird für diese Instanz deaktiviert"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effects-label": {
|
||||
"message": "Was passiert?"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.header": {
|
||||
"message": "Zugriff widerrufen"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.remove-button": {
|
||||
"message": "Zugriff widerrufen"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.user-avatar-alt": {
|
||||
"message": "Avatar von {username}"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.warning-body": {
|
||||
"message": "Falls du den Zugriff von {username} auf diese geteilte Instanz widerrufst, musst du diese Person erneut einladen, bevor diese Updates erhalten kann."
|
||||
},
|
||||
"app.instance.share.sign-in.button": {
|
||||
"message": "Anmelden"
|
||||
},
|
||||
"app.instance.share.unlink.body": {
|
||||
"message": "Du musst die Verknüpfung zu diesem Modpack trennen, um deine Instanz zu teilen"
|
||||
},
|
||||
"app.instance.share.unlink.header": {
|
||||
"message": "Zum Teilen muss die Verknüpfung getrennt werden"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.body": {
|
||||
"message": "Diese geteilte Instanz ist bereits als <bold>{instanceName}</bold> installiert. Möchtest du wirklich eine weitere Kopie installieren?"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.header": {
|
||||
"message": "Geteilte Instanz bereits installiert"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.install-anyway": {
|
||||
"message": "Trotzdem Installieren"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.instance": {
|
||||
"message": "Instanz"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.fallback-username": {
|
||||
"message": "das verknüpfte Konto"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.owner-admonition-body-v2": {
|
||||
"message": "um diese geteilte Instanz zu verwalten. Du wirst keine Updates an Nutzer senden können."
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.sign-in-as-label": {
|
||||
"message": "Anmelden als"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.signed-out-header": {
|
||||
"message": "Du musst dich bei Modrinth anmelden"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.user-admonition-body-v2": {
|
||||
"message": "um Updates für diese geteilte Instanz zu erhalten."
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.warning-header": {
|
||||
"message": "Du nutzt das falsche Modrinth-Konto"
|
||||
},
|
||||
"app.instance.worlds.add-server": {
|
||||
"message": "Server hinzufügen"
|
||||
},
|
||||
@@ -425,7 +572,19 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Durchsuche {count} Welten..."
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"app.modal.install-to-play.additional-context": {
|
||||
"message": "Zusätzlicher Kontext"
|
||||
},
|
||||
"app.modal.install-to-play.additional-context-placeholder": {
|
||||
"message": "Füge gegebenenfalls relevante Links und Bilder hinzu"
|
||||
},
|
||||
"app.modal.install-to-play.content-you-are-reporting": {
|
||||
"message": "Die Instanz, die du meldest"
|
||||
},
|
||||
"app.modal.install-to-play.delete-instance": {
|
||||
"message": "Instanz löschen"
|
||||
},
|
||||
"app.modal.install-to-play.external-files-dont-install": {
|
||||
"message": "Nicht Installieren"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
@@ -443,12 +602,51 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# Mod} other {# Mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.report-description": {
|
||||
"message": "Nutze dieses Formular, um Instanzen zu melden, die möglicherweise gegen unsere <rules-link>Regeln</rules-link> oder <terms-link>Nutzungsbedingungen</terms-link> verstoßen."
|
||||
},
|
||||
"app.modal.install-to-play.report-image-invalid-type": {
|
||||
"message": "Datei ist kein zulässiger Bildtyp"
|
||||
},
|
||||
"app.modal.install-to-play.report-image-too-large": {
|
||||
"message": "Datei überschreitet die Größenbeschränkung von 1 MiB"
|
||||
},
|
||||
"app.modal.install-to-play.report-legal-claims": {
|
||||
"message": "Informationen zu DMCA-Meldungen oder anderen rechtlichen Forderungen findest du in unserer <copyright-link>Urheberrechtsrichtlinie</copyright-link>."
|
||||
},
|
||||
"app.modal.install-to-play.report-reason": {
|
||||
"message": "Gegen welche Regel verstößt diese Instanz?"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.inappropriate": {
|
||||
"message": "Unangemessen"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.malicious": {
|
||||
"message": "Bösartig"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.spam": {
|
||||
"message": "Spam"
|
||||
},
|
||||
"app.modal.install-to-play.report-shared-instance-header": {
|
||||
"message": "Geteilte Instanz melden"
|
||||
},
|
||||
"app.modal.install-to-play.report-submitted": {
|
||||
"message": "Meldung eingereicht"
|
||||
},
|
||||
"app.modal.install-to-play.report-support-and-bugs": {
|
||||
"message": "Wende dich bei Supportanfragen bitte an unser <support-link>Support-Team</support-link>. Um Fehler zu melden, öffne bitte ein <github-link>Issue auf GitHub</github-link>."
|
||||
},
|
||||
"app.modal.install-to-play.reviewed-files": {
|
||||
"message": "Eine Datei wird nur geprüft, wenn sie auf Modrinth veröffentlicht wird, unabhängig von ihrem Dateiformat (auch .mrpack)."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Geteilte Instanz"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance-content": {
|
||||
"message": "Inhalte der geteilten Instanz"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance-unknown-files-description": {
|
||||
"message": "Diese geteilte Instanz enthält Dateien, die nicht auf Modrinth veröffentlicht sind. Wir empfehlen dringend, nur Dateien aus vertrauenswürdigen Quellen zu installieren."
|
||||
},
|
||||
"app.modal.install-to-play.unknown-files-description": {
|
||||
"message": "Dieses Server-Modpack enthält Dateien, die nicht auf Modrinth veröffentlicht sind. Wir empfehlen dringend, nur Dateien aus vertrauenswürdigen Quellen zu installieren."
|
||||
},
|
||||
@@ -467,8 +665,23 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Entfernt"
|
||||
},
|
||||
"app.modal.update-to-play.server-modpack-unknown-files-description": {
|
||||
"message": "Dieses Update eines Server-Modpacks enthält Dateien, die nicht auf Modrinth veröffentlicht sind. Wir empfehlen dringend, nur Dateien aus vertrauenswürdigen Quellen zu installieren."
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-added-label": {
|
||||
"message": "Hinzugefügt"
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-removed-label": {
|
||||
"message": "Entfernt"
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-unknown-files-description": {
|
||||
"message": "Dieses Update einer geteilten Instanz enthält Dateien, die nicht auf Modrinth veröffentlicht sind. Wir empfehlen dringend, nur Dateien aus vertrauenswürdigen Quellen zu installieren."
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Aktualisierung erforderlich"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Eine aktualisierung zum spielen von {name} ist benötigt. Bitte aktualisiere auf die neuste Version um das Spiel zu starten."
|
||||
"message": "Zum Spielen von {name} ist eine Aktualisierung erforderlich. Bitte aktualisiere auf die neueste Version, um das Spiel zu starten."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Dieses Projekt ist bereits installiert"
|
||||
@@ -497,6 +710,9 @@
|
||||
"app.settings.downloading": {
|
||||
"message": "Lade v{version} herunter"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "Werbung ermöglicht Modrinth und finanziert die Auszahlungen an die Ersteller. Unsere Partner speichern möglicherweise Cookies in der App oder greifen auf diese zu, um Werbung zu personalisieren und die Leistung zu messen. Du kannst dies unten deaktivieren oder deine Einstellungen verwalten."
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "Erscheinungsbild"
|
||||
},
|
||||
@@ -539,6 +755,9 @@
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "Fehler bei der Dateiverarbeitung"
|
||||
},
|
||||
"app.skins.ears-feature-notice": {
|
||||
"message": "Dieser Skin nutzt Funktionen aus dem {ears}-Mod"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "Skin bearbeiten"
|
||||
},
|
||||
@@ -665,6 +884,12 @@
|
||||
"app.skins.title": {
|
||||
"message": "Skin-Auswahl"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "Deaktivieren"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "Aktivieren"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Modrinth App v{version} wurde heruntergeladen. Lade die App neu um jetzt zu aktualisieren, oder automatisch nach dem schliessen der Modrinth App."
|
||||
},
|
||||
@@ -713,6 +938,39 @@
|
||||
"app.world.world-item.players-online": {
|
||||
"message": "{count} online"
|
||||
},
|
||||
"content.shared-instance.change-version-body": {
|
||||
"message": "Das Ändern der Version wirkt sich nur auf deine lokale Kopie aus. Zukünftige Updates der geteilten Instanz können diese wiederherstellen oder erneut ändern."
|
||||
},
|
||||
"content.shared-instance.delete-bulk-body": {
|
||||
"message": "Einige ausgewählte Projekte sind Teil der geteilten Instanz. Wenn du diese löschst, wirkt sich dies nur auf deine lokale Kopie aus, und zukünftige Updates der geteilten Instanz können diese möglicherweise wiederherstellen oder erneut ändern."
|
||||
},
|
||||
"content.shared-instance.delete-button": {
|
||||
"message": "Trotzdem löschen"
|
||||
},
|
||||
"content.shared-instance.delete-many-button": {
|
||||
"message": "{count, plural, one {# Projekt} other {# Projekte}} trotzdem löschen"
|
||||
},
|
||||
"content.shared-instance.delete-single-body": {
|
||||
"message": "Das Löschen wirkt sich nur auf deine lokale Kopie aus. Zukünftige Updates der geteilten Instanz können dies wiederherstellen oder erneut ändern."
|
||||
},
|
||||
"content.shared-instance.disable-bulk-body": {
|
||||
"message": "Einige ausgewählte Projekte sind Teil der geteilten Instanz. Wenn du diese deaktivierst, wirkt sich dies nur auf deine lokale Kopie aus, und zukünftige Updates der geteilten Instanz können diese möglicherweise wieder aktivieren, wiederherstellen oder erneut ändern."
|
||||
},
|
||||
"content.shared-instance.disable-button": {
|
||||
"message": "Trotzdem deaktivieren"
|
||||
},
|
||||
"content.shared-instance.disable-many-button": {
|
||||
"message": "{count, plural, one {# Projekt} other {# Projekte}} trotzdem deaktivieren"
|
||||
},
|
||||
"content.shared-instance.disable-single-body": {
|
||||
"message": "Das Deaktivieren wirkt sich nur auf deine lokale Kopie aus. Zukünftige Updates der geteilten Instanz können dies wieder aktivieren, wiederherstellen oder erneut ändern."
|
||||
},
|
||||
"content.shared-instance.unlink-body": {
|
||||
"message": "Das Aufheben der Verknüpfung wirkt sich nur auf deine lokale Kopie aus. Zukünftige Updates der geteilten Instanz können diese wiederherstellen oder erneut ändern."
|
||||
},
|
||||
"content.shared-instance.warning-header": {
|
||||
"message": "Dies ist Teil der geteilten Instanz"
|
||||
},
|
||||
"friends.action.add-friend": {
|
||||
"message": "Freund hinzufügen"
|
||||
},
|
||||
@@ -776,6 +1034,75 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Logge dich in ein Modrinth Konto ein</link>, um Freunde hinzuzufügen und zu sehen, was sie spielen!"
|
||||
},
|
||||
"installation-settings.shared-instance.linked-title": {
|
||||
"message": "Verknüpfte geteilte Instanz"
|
||||
},
|
||||
"installation-settings.shared-instance.title": {
|
||||
"message": "Instanz zurückziehen"
|
||||
},
|
||||
"installation-settings.shared-instance.unlink-button": {
|
||||
"message": "Geteilte Instanz trennen"
|
||||
},
|
||||
"installation-settings.shared-instance.unlink-description": {
|
||||
"message": "Trenne diese lokale Instanz von zukünftigen geteilten Updates."
|
||||
},
|
||||
"installation-settings.shared-instance.unlinking-button": {
|
||||
"message": "Wird getrennt..."
|
||||
},
|
||||
"installation-settings.shared-instance.unpublish-button": {
|
||||
"message": "Geteilte Instanz zurückziehen"
|
||||
},
|
||||
"installation-settings.shared-instance.unpublish-description": {
|
||||
"message": "Entferne diese geteilte Instanz von Modrinth und sende keine Updates mehr an Personen, die sie nutzen. Deine lokale Instanz ist davon nicht betroffen."
|
||||
},
|
||||
"installation-settings.shared-instance.unpublishing-button": {
|
||||
"message": "Wird zurückgezogen..."
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.admonition-body": {
|
||||
"message": "Dies betrifft nur deine lokale Instanz. Deine installierten Inhalte bleiben auf diesem Gerät, und die freigegebene Instanz sowie andere Benutzer, die diese verwenden, sind davon nicht betroffen."
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.admonition-header": {
|
||||
"message": "Geteilte Instanz trennen"
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.header": {
|
||||
"message": "Geteilte Instanz trennen"
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.admonition-body": {
|
||||
"message": "Dadurch wird die geteilte Instanz von den Servern von Modrinth gelöscht. Personen, die diese in der Modrinth-App nutzen, erhalten keine Updates mehr, aber deine lokale Instanz und dessen Inhalte bleiben auf diesem Gerät erhalten."
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.admonition-header": {
|
||||
"message": "Geteilte Instanz zurückziehen"
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.header": {
|
||||
"message": "Geteilte Instanz zurückziehen"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "Verknüpfung erstellen"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "Modpack exportieren"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "Instanz starten"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "Weitere Aktionen"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "Ordner öffnen"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "Reparieren"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "Instanz-Einstellungen"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "Wird gestartet..."
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "Wird gestoppt..."
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "Ersteue u starte"
|
||||
},
|
||||
@@ -818,6 +1145,15 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "Speichern unter..."
|
||||
},
|
||||
"instance.locked.delete-button": {
|
||||
"message": "Instanz löschen"
|
||||
},
|
||||
"instance.locked.play-tooltip": {
|
||||
"message": "Diese Instanz wurde gesperrt"
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "Noch nie gespielt"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "Adresse"
|
||||
},
|
||||
@@ -953,6 +1289,9 @@
|
||||
"instance.settings.tabs.installation.loader-version": {
|
||||
"message": "{loader} Version"
|
||||
},
|
||||
"instance.settings.tabs.installation.locked": {
|
||||
"message": "Installationseinstellungen sind nicht verfügbar, solange diese Instanz gesperrt ist."
|
||||
},
|
||||
"instance.settings.tabs.java": {
|
||||
"message": "Java und Arbeitsspeicher"
|
||||
},
|
||||
@@ -992,6 +1331,9 @@
|
||||
"instance.settings.tabs.java.java-path-placeholder": {
|
||||
"message": "/pfad/zu/java"
|
||||
},
|
||||
"instance.settings.tabs.sharing": {
|
||||
"message": "Teilen"
|
||||
},
|
||||
"instance.settings.tabs.window": {
|
||||
"message": "Spielfenster"
|
||||
},
|
||||
@@ -1022,6 +1364,57 @@
|
||||
"instance.settings.tabs.window.width.enter": {
|
||||
"message": "Breite eingeben..."
|
||||
},
|
||||
"instance.shared-instance.error.title": {
|
||||
"message": "Etwas ist schiefgelaufen"
|
||||
},
|
||||
"instance.shared-instance.owner-tooltip": {
|
||||
"message": "Der Inhalt dieser Instanz wird mit anderen Benutzern geteilt."
|
||||
},
|
||||
"instance.shared-instance.publish-review.added-label": {
|
||||
"message": "Hinzugefügt"
|
||||
},
|
||||
"instance.shared-instance.publish-review.admonition-header": {
|
||||
"message": "Update an Spieler senden"
|
||||
},
|
||||
"instance.shared-instance.publish-review.config-title-v2": {
|
||||
"message": "Konfigurationsdateien auswählen"
|
||||
},
|
||||
"instance.shared-instance.publish-review.description": {
|
||||
"message": "Überprüfe die Inhaltsänderungen und wähle Konfigurationsdateien aus, die in diesem Update enthalten sein sollen."
|
||||
},
|
||||
"instance.shared-instance.publish-review.header": {
|
||||
"message": "Änderungen überprüfen"
|
||||
},
|
||||
"instance.shared-instance.publish-review.publish-button": {
|
||||
"message": "Update senden"
|
||||
},
|
||||
"instance.shared-instance.publish-review.removed-label": {
|
||||
"message": "Entfernt"
|
||||
},
|
||||
"instance.shared-instance.tooltip": {
|
||||
"message": "Der Inhalt dieser Instanz wird von jemand anderes verwaltet."
|
||||
},
|
||||
"instance.shared-instance.unavailable.access-revoked-text": {
|
||||
"message": "Dein Zugriff auf die geteilte Instanz wurde widerrufen. Diese Instanz ist weiterhin verfügbar, ist jedoch nicht mehr verknüpft und erhält keine Updates mehr."
|
||||
},
|
||||
"instance.shared-instance.unavailable.deleted-text": {
|
||||
"message": "Die primäre Instanz wurde gelöscht. Diese Instanz ist weiterhin verfügbar, ist jedoch nicht mehr verknüpft und erhält keine Updates mehr."
|
||||
},
|
||||
"instance.shared-instance.unavailable.locked-text": {
|
||||
"message": "Diese geteilte Instanz wurde vom Inhaltsmoderationsteam gesperrt. Sie erhält keine Updates von der primären Instanz mehr und kann nicht mehr gespielt werden."
|
||||
},
|
||||
"instance.shared-instance.unavailable.locked-title": {
|
||||
"message": "Instanz gesperrt"
|
||||
},
|
||||
"instance.shared-instance.unavailable.manager-fallback": {
|
||||
"message": "der Instanzmanager"
|
||||
},
|
||||
"instance.shared-instance.unavailable.text": {
|
||||
"message": "Deine lokale Instanz ist weiterhin verfügbar, ist jedoch nicht mehr verknüpft und erhält keine Updates mehr."
|
||||
},
|
||||
"instance.shared-instance.unavailable.title": {
|
||||
"message": "Geteilte Instanz nicht mehr verfügbar"
|
||||
},
|
||||
"instance.worlds.a_minecraft_server": {
|
||||
"message": "Ein Minecraft-Server"
|
||||
},
|
||||
@@ -1085,6 +1478,63 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "In Minecraft anmelden"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "Du benötigst ein Microsoft-Konto, welches Minecraft besitzt, bevor du das Spiel starten und spielen kannst."
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "Bei einem Microsoft-Konto anmelden"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "Du hast kein Konto?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "Minecraft holen"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "Hilfe erhalten"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "Minecraft erforderlich"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "Bei Microsoft anmelden"
|
||||
},
|
||||
"modal.modrinth-account-required.browser-description": {
|
||||
"message": "Ein neuer Tab zum Anmelden wurde geöffnet. Schließe die Anmeldung dort ab und kehren anschließend zur App zurück."
|
||||
},
|
||||
"modal.modrinth-account-required.cancel-button": {
|
||||
"message": "Abbrechen"
|
||||
},
|
||||
"modal.modrinth-account-required.continue-in-browser-heading": {
|
||||
"message": "Im Browser fortfahren"
|
||||
},
|
||||
"modal.modrinth-account-required.create-account-button": {
|
||||
"message": "Ein Konto erstellen"
|
||||
},
|
||||
"modal.modrinth-account-required.description": {
|
||||
"message": "Du musst dich bei deinem Modrinth-Konto anmelden, bevor du diese Funktion nutzen kannst."
|
||||
},
|
||||
"modal.modrinth-account-required.header": {
|
||||
"message": "Konto erforderlich"
|
||||
},
|
||||
"modal.modrinth-account-required.open-browser-again-button": {
|
||||
"message": "Browser erneut öffnen"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-button": {
|
||||
"message": "Bei Modrinth anmelden"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-heading": {
|
||||
"message": "Bei einem Modrinth-Konto anmelden"
|
||||
},
|
||||
"modal.modrinth-account-required.signing-in-header": {
|
||||
"message": "Anmelden"
|
||||
},
|
||||
"modal.modrinth-account-required.support-prompt": {
|
||||
"message": "Hast du Probleme bei der Anmeldung? <support>Hilfe erhalten</support>"
|
||||
},
|
||||
"modal.modrinth-account-required.waiting-for-browser": {
|
||||
"message": "Warte auf Bestätigung durch den Browser..."
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "Von der Instanz vorgegeben"
|
||||
},
|
||||
|
||||
@@ -39,7 +39,7 @@
|
||||
"message": "Bereinigung konnte nicht abgeschlossen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Dateien konnte nicht heruntergeladen werden"
|
||||
"message": "Dateien konnten nicht heruntergeladen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "Heruntergeladene Datei ist beschädigt"
|
||||
@@ -84,11 +84,14 @@
|
||||
"message": "Das Pack konnte nicht heruntergeladen werden"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "Irgendwas ist schiefgelaufen"
|
||||
"message": "Etwas ist schiefgelaufen"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Unbekannte Instanz"
|
||||
},
|
||||
"app.action-bar.install.updating-shared-content": {
|
||||
"message": "Geteilte Inhalte werden aktualisiert"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "Installationen"
|
||||
},
|
||||
@@ -125,6 +128,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Logs anzeigen"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "Alle akzeptieren"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "Werbung ermöglicht Modrinth und finanziert die Auszahlungen an die Ersteller. Unsere Partner speichern möglicherweise Cookies in der App oder greifen auf diese zu, um Werbung zu personalisieren und die Leistung zu messen."
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "Einstellungen verwalten"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "Alle ablehnen"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "Deine Privatsphäre und wie Werbung Modrinth unterstützt"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Aktiviert erweiterte Rendering-Funktionen wie Unschärfe-Effekte, welche ohne Hardware-beschleunigtes Rendering zu Leistungsproblemen führen können."
|
||||
},
|
||||
@@ -207,10 +225,10 @@
|
||||
"message": "Authentifizierungsserver sind nicht erreichbar"
|
||||
},
|
||||
"app.browse.add-servers-to-instance": {
|
||||
"message": "Server zu Instanz hinzufügen"
|
||||
"message": "Server zur Instanz hinzufügen"
|
||||
},
|
||||
"app.browse.add-to-an-instance": {
|
||||
"message": "Zu Instanz hinzufügen"
|
||||
"message": "Zu einer Instanz hinzufügen"
|
||||
},
|
||||
"app.browse.add-to-instance": {
|
||||
"message": "Zur Instanz hinzufügen"
|
||||
@@ -323,6 +341,36 @@
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Loader-Prozesse werden ausgeführt"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.added-label": {
|
||||
"message": "Hinzugefügt"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-body": {
|
||||
"message": "Deine lokale Instanz ist den Benutzern, mit denen du sie geteilt hast, voraus."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-header": {
|
||||
"message": "Deine Änderungen wurden noch nicht geteilt"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publish-button": {
|
||||
"message": "Update senden"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publishing-button": {
|
||||
"message": "Wird gesendet..."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.removed-label": {
|
||||
"message": "Entfernt"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-admonition-header": {
|
||||
"message": "Update senden"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-description": {
|
||||
"message": "Überprüfe die Inhaltsänderungen, die allen Nutzern dieser Instanz bereitgestellt werden."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-header": {
|
||||
"message": "Änderungen überprüfen"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.reviewing-button": {
|
||||
"message": "Wird überprüft..."
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "Alle Daten deiner Instanz werden permanent gelöscht, einschließlich deiner Welten, Konfigurationen und allen installierten Inhalten."
|
||||
},
|
||||
@@ -359,6 +407,9 @@
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "Projekt"
|
||||
},
|
||||
"app.instance.mods.locked-content": {
|
||||
"message": "Inhalte in gesperrten Instanzen können nicht geändert werden."
|
||||
},
|
||||
"app.instance.mods.project-was-added": {
|
||||
"message": "\"{name}\" wurde hinzugefügt"
|
||||
},
|
||||
@@ -374,6 +425,102 @@
|
||||
"app.instance.mods.successfully-uploaded": {
|
||||
"message": "Erfolgreich hochgeladen"
|
||||
},
|
||||
"app.instance.share.empty.description": {
|
||||
"message": "Du kannst diese Instanz mit deinen Freunden teilen!"
|
||||
},
|
||||
"app.instance.share.empty.heading": {
|
||||
"message": "Keine Freunde eingeladen"
|
||||
},
|
||||
"app.instance.share.empty.invite-friends-button": {
|
||||
"message": "Freunde einladen"
|
||||
},
|
||||
"app.instance.share.invite-modal.heading": {
|
||||
"message": "{name} teilen"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-prefix": {
|
||||
"message": "Du musst dich als"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-suffix": {
|
||||
"message": "anmelden um diese Seite aufzurufen."
|
||||
},
|
||||
"app.instance.share.locked.linked-account-fallback": {
|
||||
"message": "das verknüpfte Konto"
|
||||
},
|
||||
"app.instance.share.locked.signed-out-heading": {
|
||||
"message": "Nicht angemeldet"
|
||||
},
|
||||
"app.instance.share.locked.switch-account-button": {
|
||||
"message": "Konto wechseln"
|
||||
},
|
||||
"app.instance.share.locked.wrong-account-heading": {
|
||||
"message": "Falsches Konto"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-access": {
|
||||
"message": "Diese Person wird für diese geteilte Instanz erhalten keine Updates mehr erhalten"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-installed-copy": {
|
||||
"message": "Jede bereits installierte Kopie bleibt auf deren Gerät erhalten"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-invite-again": {
|
||||
"message": "Du kannst diese Person später erneut einladen"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-last-user": {
|
||||
"message": "Dies ist der letzte Benutzer, das Teilen wird für diese Instanz deaktiviert"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effects-label": {
|
||||
"message": "Was passiert?"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.header": {
|
||||
"message": "Zugriff widerrufen"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.remove-button": {
|
||||
"message": "Zugriff widerrufen"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.user-avatar-alt": {
|
||||
"message": "Avatar von {username}"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.warning-body": {
|
||||
"message": "Falls du den Zugriff von {username} auf diese geteilte Instanz widerrufst, musst du diese Person erneut einladen, bevor diese Updates erhalten kann."
|
||||
},
|
||||
"app.instance.share.sign-in.button": {
|
||||
"message": "Anmelden"
|
||||
},
|
||||
"app.instance.share.unlink.body": {
|
||||
"message": "Du musst die Verknüpfung zu diesem Modpack trennen, um deine Instanz zu teilen"
|
||||
},
|
||||
"app.instance.share.unlink.header": {
|
||||
"message": "Zum Teilen muss die Verknüpfung getrennt werden"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.body": {
|
||||
"message": "Diese geteilte Instanz ist bereits als <bold>{instanceName}</bold> installiert. Möchtest du wirklich eine weitere Kopie installieren?"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.header": {
|
||||
"message": "Geteilte Instanz bereits installiert"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.install-anyway": {
|
||||
"message": "Trotzdem Installieren"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.instance": {
|
||||
"message": "Instanz"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.fallback-username": {
|
||||
"message": "das verknüpfte Konto"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.owner-admonition-body-v2": {
|
||||
"message": "um diese geteilte Instanz zu verwalten. Du wirst keine Updates an Nutzer senden können."
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.sign-in-as-label": {
|
||||
"message": "Anmelden als"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.signed-out-header": {
|
||||
"message": "Du musst dich bei Modrinth anmelden"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.user-admonition-body-v2": {
|
||||
"message": "um Updates für diese geteilte Instanz zu erhalten."
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.warning-header": {
|
||||
"message": "Du nutzt das falsche Modrinth-Konto"
|
||||
},
|
||||
"app.instance.worlds.add-server": {
|
||||
"message": "Server hinzufügen"
|
||||
},
|
||||
@@ -425,7 +572,19 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Durchsuche {count} Welten..."
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"app.modal.install-to-play.additional-context": {
|
||||
"message": "Zusätzlicher Kontext"
|
||||
},
|
||||
"app.modal.install-to-play.additional-context-placeholder": {
|
||||
"message": "Füge gegebenenfalls relevante Links und Bilder hinzu"
|
||||
},
|
||||
"app.modal.install-to-play.content-you-are-reporting": {
|
||||
"message": "Die Instanz, die du meldest"
|
||||
},
|
||||
"app.modal.install-to-play.delete-instance": {
|
||||
"message": "Instanz löschen"
|
||||
},
|
||||
"app.modal.install-to-play.external-files-dont-install": {
|
||||
"message": "Nicht Installieren"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
@@ -443,12 +602,51 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# Mod} other {# Mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.report-description": {
|
||||
"message": "Nutze dieses Formular, um Instanzen zu melden, die möglicherweise gegen unsere <rules-link>Regeln</rules-link> oder <terms-link>Nutzungsbedingungen</terms-link> verstoßen."
|
||||
},
|
||||
"app.modal.install-to-play.report-image-invalid-type": {
|
||||
"message": "Datei ist kein zulässiger Bildtyp"
|
||||
},
|
||||
"app.modal.install-to-play.report-image-too-large": {
|
||||
"message": "Datei überschreitet die Größenbeschränkung von 1 MiB"
|
||||
},
|
||||
"app.modal.install-to-play.report-legal-claims": {
|
||||
"message": "Informationen zu DMCA-Meldungen oder anderen rechtlichen Forderungen findest du in unserer <copyright-link>Urheberrechtsrichtlinie</copyright-link>."
|
||||
},
|
||||
"app.modal.install-to-play.report-reason": {
|
||||
"message": "Gegen welche Regel verstößt diese Instanz?"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.inappropriate": {
|
||||
"message": "Unangemessen"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.malicious": {
|
||||
"message": "Bösartig"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.spam": {
|
||||
"message": "Spam"
|
||||
},
|
||||
"app.modal.install-to-play.report-shared-instance-header": {
|
||||
"message": "Geteilte Instanz melden"
|
||||
},
|
||||
"app.modal.install-to-play.report-submitted": {
|
||||
"message": "Meldung eingereicht"
|
||||
},
|
||||
"app.modal.install-to-play.report-support-and-bugs": {
|
||||
"message": "Wende dich bei Supportanfragen bitte an unser <support-link>Support-Team</support-link>. Um Fehler zu melden, öffne bitte ein <github-link>Issue auf GitHub</github-link>."
|
||||
},
|
||||
"app.modal.install-to-play.reviewed-files": {
|
||||
"message": "Eine Datei wird nur geprüft, wenn sie auf Modrinth veröffentlicht wird, unabhängig von ihrem Dateiformat (auch .mrpack)."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Geteilte Instanz"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance-content": {
|
||||
"message": "Inhalte der geteilten Instanz"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance-unknown-files-description": {
|
||||
"message": "Diese geteilte Instanz enthält Dateien, die nicht auf Modrinth veröffentlicht sind. Wir empfehlen dringend, nur Dateien aus vertrauenswürdigen Quellen zu installieren."
|
||||
},
|
||||
"app.modal.install-to-play.unknown-files-description": {
|
||||
"message": "Dieses Server-Modpack enthält Dateien, die nicht auf Modrinth veröffentlicht sind. Wir empfehlen dringend, nur Dateien aus vertrauenswürdigen Quellen zu installieren."
|
||||
},
|
||||
@@ -467,6 +665,21 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Entfernt"
|
||||
},
|
||||
"app.modal.update-to-play.server-modpack-unknown-files-description": {
|
||||
"message": "Dieses Update eines Server-Modpacks enthält Dateien, die nicht auf Modrinth veröffentlicht sind. Wir empfehlen dringend, nur Dateien aus vertrauenswürdigen Quellen zu installieren."
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-added-label": {
|
||||
"message": "Hinzugefügt"
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-removed-label": {
|
||||
"message": "Entfernt"
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-unknown-files-description": {
|
||||
"message": "Dieses Update einer geteilten Instanz enthält Dateien, die nicht auf Modrinth veröffentlicht sind. Wir empfehlen dringend, nur Dateien aus vertrauenswürdigen Quellen zu installieren."
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Aktualisierung erforderlich"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Zum Spielen von {name} ist eine Aktualisierung erforderlich. Bitte aktualisiere auf die neueste Version, um das Spiel zu starten."
|
||||
},
|
||||
@@ -497,6 +710,9 @@
|
||||
"app.settings.downloading": {
|
||||
"message": "Lade v{version} herunter"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "Werbung ermöglicht Modrinth und finanziert die Auszahlungen an die Ersteller. Unsere Partner speichern möglicherweise Cookies in der App oder greifen auf diese zu, um Werbung zu personalisieren und die Leistung zu messen. Du kannst dies unten deaktivieren oder deine Einstellungen verwalten."
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "Erscheinungsbild"
|
||||
},
|
||||
@@ -539,6 +755,9 @@
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "Fehler bei der Verarbeitung der Datei"
|
||||
},
|
||||
"app.skins.ears-feature-notice": {
|
||||
"message": "Dieser Skin nutzt Funktionen aus dem {ears}-Mod"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "Skin bearbeiten"
|
||||
},
|
||||
@@ -665,6 +884,12 @@
|
||||
"app.skins.title": {
|
||||
"message": "Skin-Auswahl"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "Deaktivieren"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "Aktivieren"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Modrinth App v{version} wurde heruntergeladen. Jetzt neu laden, um sofort zu aktualisieren, oder beim Schließen der Modrinth-App automatisch aktualisieren."
|
||||
},
|
||||
@@ -713,6 +938,39 @@
|
||||
"app.world.world-item.players-online": {
|
||||
"message": "{count} online"
|
||||
},
|
||||
"content.shared-instance.change-version-body": {
|
||||
"message": "Das Ändern der Version wirkt sich nur auf deine lokale Kopie aus. Zukünftige Updates der geteilten Instanz können diese wiederherstellen oder erneut ändern."
|
||||
},
|
||||
"content.shared-instance.delete-bulk-body": {
|
||||
"message": "Einige ausgewählte Projekte sind Teil der geteilten Instanz. Wenn du diese löschst, wirkt sich dies nur auf deine lokale Kopie aus, und zukünftige Updates der geteilten Instanz können diese möglicherweise wiederherstellen oder erneut ändern."
|
||||
},
|
||||
"content.shared-instance.delete-button": {
|
||||
"message": "Trotzdem löschen"
|
||||
},
|
||||
"content.shared-instance.delete-many-button": {
|
||||
"message": "{count, plural, one {# Projekt} other {# Projekte}} trotzdem löschen"
|
||||
},
|
||||
"content.shared-instance.delete-single-body": {
|
||||
"message": "Das Löschen wirkt sich nur auf deine lokale Kopie aus. Zukünftige Updates der geteilten Instanz können dies wiederherstellen oder erneut ändern."
|
||||
},
|
||||
"content.shared-instance.disable-bulk-body": {
|
||||
"message": "Einige ausgewählte Projekte sind Teil der geteilten Instanz. Wenn du diese deaktivierst, wirkt sich dies nur auf deine lokale Kopie aus, und zukünftige Updates der geteilten Instanz können diese möglicherweise wieder aktivieren, wiederherstellen oder erneut ändern."
|
||||
},
|
||||
"content.shared-instance.disable-button": {
|
||||
"message": "Trotzdem deaktivieren"
|
||||
},
|
||||
"content.shared-instance.disable-many-button": {
|
||||
"message": "{count, plural, one {# Projekt} other {# Projekte}} trotzdem deaktivieren"
|
||||
},
|
||||
"content.shared-instance.disable-single-body": {
|
||||
"message": "Das Deaktivieren wirkt sich nur auf deine lokale Kopie aus. Zukünftige Updates der geteilten Instanz können dies wieder aktivieren, wiederherstellen oder erneut ändern."
|
||||
},
|
||||
"content.shared-instance.unlink-body": {
|
||||
"message": "Das Aufheben der Verknüpfung wirkt sich nur auf deine lokale Kopie aus. Zukünftige Updates der geteilten Instanz können diese wiederherstellen oder erneut ändern."
|
||||
},
|
||||
"content.shared-instance.warning-header": {
|
||||
"message": "Dies ist Teil der geteilten Instanz"
|
||||
},
|
||||
"friends.action.add-friend": {
|
||||
"message": "Freund hinzufügen"
|
||||
},
|
||||
@@ -776,6 +1034,75 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Melde dich bei einem Modrinth-Konto an</link>, um Freunde hinzuzufügen und zu sehen, was sie gerade spielen!"
|
||||
},
|
||||
"installation-settings.shared-instance.linked-title": {
|
||||
"message": "Verknüpfte geteilte Instanz"
|
||||
},
|
||||
"installation-settings.shared-instance.title": {
|
||||
"message": "Instanz zurückziehen"
|
||||
},
|
||||
"installation-settings.shared-instance.unlink-button": {
|
||||
"message": "Geteilte Instanz trennen"
|
||||
},
|
||||
"installation-settings.shared-instance.unlink-description": {
|
||||
"message": "Trenne diese lokale Instanz von zukünftigen geteilten Updates."
|
||||
},
|
||||
"installation-settings.shared-instance.unlinking-button": {
|
||||
"message": "Wird getrennt..."
|
||||
},
|
||||
"installation-settings.shared-instance.unpublish-button": {
|
||||
"message": "Geteilte Instanz zurückziehen"
|
||||
},
|
||||
"installation-settings.shared-instance.unpublish-description": {
|
||||
"message": "Entferne diese geteilte Instanz von Modrinth und sende keine Updates mehr an Personen, die sie nutzen. Deine lokale Instanz ist davon nicht betroffen."
|
||||
},
|
||||
"installation-settings.shared-instance.unpublishing-button": {
|
||||
"message": "Wird zurückgezogen..."
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.admonition-body": {
|
||||
"message": "Dies betrifft nur deine lokale Instanz. Deine installierten Inhalte bleiben auf diesem Gerät, und die freigegebene Instanz sowie andere Benutzer, die diese verwenden, sind davon nicht betroffen."
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.admonition-header": {
|
||||
"message": "Geteilte Instanz trennen"
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.header": {
|
||||
"message": "Geteilte Instanz trennen"
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.admonition-body": {
|
||||
"message": "Dadurch wird die geteilte Instanz von den Servern von Modrinth gelöscht. Personen, die diese in der Modrinth-App nutzen, erhalten keine Updates mehr, aber deine lokale Instanz und dessen Inhalte bleiben auf diesem Gerät erhalten."
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.admonition-header": {
|
||||
"message": "Geteilte Instanz zurückziehen"
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.header": {
|
||||
"message": "Geteilte Instanz zurückziehen"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "Verknüpfung erstellen"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "Modpack exportieren"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "Instanz starten"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "Weitere Aktionen"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "Ordner öffnen"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "Reparieren"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "Instanz-Einstellungen"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "Wird gestartet..."
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "Wird gestoppt..."
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "Hinzufügen und spielen"
|
||||
},
|
||||
@@ -818,6 +1145,15 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "Speichern unter..."
|
||||
},
|
||||
"instance.locked.delete-button": {
|
||||
"message": "Instanz löschen"
|
||||
},
|
||||
"instance.locked.play-tooltip": {
|
||||
"message": "Diese Instanz wurde gesperrt"
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "Noch nie gespielt"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "Adresse"
|
||||
},
|
||||
@@ -953,6 +1289,9 @@
|
||||
"instance.settings.tabs.installation.loader-version": {
|
||||
"message": "{loader} Version"
|
||||
},
|
||||
"instance.settings.tabs.installation.locked": {
|
||||
"message": "Installationseinstellungen sind nicht verfügbar, solange diese Instanz gesperrt ist."
|
||||
},
|
||||
"instance.settings.tabs.java": {
|
||||
"message": "Java und Arbeitsspeicher"
|
||||
},
|
||||
@@ -992,6 +1331,9 @@
|
||||
"instance.settings.tabs.java.java-path-placeholder": {
|
||||
"message": "/pfad/zu/java"
|
||||
},
|
||||
"instance.settings.tabs.sharing": {
|
||||
"message": "Teilen"
|
||||
},
|
||||
"instance.settings.tabs.window": {
|
||||
"message": "Fenster"
|
||||
},
|
||||
@@ -1022,6 +1364,57 @@
|
||||
"instance.settings.tabs.window.width.enter": {
|
||||
"message": "Breite eingeben..."
|
||||
},
|
||||
"instance.shared-instance.error.title": {
|
||||
"message": "Etwas ist schiefgelaufen"
|
||||
},
|
||||
"instance.shared-instance.owner-tooltip": {
|
||||
"message": "Der Inhalt dieser Instanz wird mit anderen Benutzern geteilt."
|
||||
},
|
||||
"instance.shared-instance.publish-review.added-label": {
|
||||
"message": "Hinzugefügt"
|
||||
},
|
||||
"instance.shared-instance.publish-review.admonition-header": {
|
||||
"message": "Update an Spieler senden"
|
||||
},
|
||||
"instance.shared-instance.publish-review.config-title-v2": {
|
||||
"message": "Konfigurationsdateien auswählen"
|
||||
},
|
||||
"instance.shared-instance.publish-review.description": {
|
||||
"message": "Überprüfe die Inhaltsänderungen und wähle Konfigurationsdateien aus, die in diesem Update enthalten sein sollen."
|
||||
},
|
||||
"instance.shared-instance.publish-review.header": {
|
||||
"message": "Änderungen überprüfen"
|
||||
},
|
||||
"instance.shared-instance.publish-review.publish-button": {
|
||||
"message": "Update senden"
|
||||
},
|
||||
"instance.shared-instance.publish-review.removed-label": {
|
||||
"message": "Entfernt"
|
||||
},
|
||||
"instance.shared-instance.tooltip": {
|
||||
"message": "Der Inhalt dieser Instanz wird von jemand anderes verwaltet."
|
||||
},
|
||||
"instance.shared-instance.unavailable.access-revoked-text": {
|
||||
"message": "Dein Zugriff auf die geteilte Instanz wurde widerrufen. Diese Instanz ist weiterhin verfügbar, ist jedoch nicht mehr verknüpft und erhält keine Updates mehr."
|
||||
},
|
||||
"instance.shared-instance.unavailable.deleted-text": {
|
||||
"message": "Die primäre Instanz wurde gelöscht. Diese Instanz ist weiterhin verfügbar, ist jedoch nicht mehr verknüpft und erhält keine Updates mehr."
|
||||
},
|
||||
"instance.shared-instance.unavailable.locked-text": {
|
||||
"message": "Diese geteilte Instanz wurde vom Inhaltsmoderationsteam gesperrt. Sie erhält keine Updates von der primären Instanz mehr und kann nicht mehr gespielt werden."
|
||||
},
|
||||
"instance.shared-instance.unavailable.locked-title": {
|
||||
"message": "Instanz gesperrt"
|
||||
},
|
||||
"instance.shared-instance.unavailable.manager-fallback": {
|
||||
"message": "der Instanzmanager"
|
||||
},
|
||||
"instance.shared-instance.unavailable.text": {
|
||||
"message": "Deine lokale Instanz ist weiterhin verfügbar, ist jedoch nicht mehr verknüpft und erhält keine Updates mehr."
|
||||
},
|
||||
"instance.shared-instance.unavailable.title": {
|
||||
"message": "Geteilte Instanz nicht mehr verfügbar"
|
||||
},
|
||||
"instance.worlds.a_minecraft_server": {
|
||||
"message": "Ein Minecraft-Server"
|
||||
},
|
||||
@@ -1085,6 +1478,63 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "Bei Minecraft anmelden"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "Du benötigst ein Microsoft-Konto, welches Minecraft besitzt, bevor du das Spiel starten und spielen kannst."
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "Bei einem Microsoft-Konto anmelden"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "Du hast kein Konto?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "Minecraft holen"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "Hilfe erhalten"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "Minecraft erforderlich"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "Bei Microsoft anmelden"
|
||||
},
|
||||
"modal.modrinth-account-required.browser-description": {
|
||||
"message": "Ein neuer Tab zum Anmelden wurde geöffnet. Schließe die Anmeldung dort ab und kehren anschließend zur App zurück."
|
||||
},
|
||||
"modal.modrinth-account-required.cancel-button": {
|
||||
"message": "Abbrechen"
|
||||
},
|
||||
"modal.modrinth-account-required.continue-in-browser-heading": {
|
||||
"message": "Im Browser fortfahren"
|
||||
},
|
||||
"modal.modrinth-account-required.create-account-button": {
|
||||
"message": "Ein Konto erstellen"
|
||||
},
|
||||
"modal.modrinth-account-required.description": {
|
||||
"message": "Du musst dich bei deinem Modrinth-Konto anmelden, bevor du diese Funktion nutzen kannst."
|
||||
},
|
||||
"modal.modrinth-account-required.header": {
|
||||
"message": "Konto erforderlich"
|
||||
},
|
||||
"modal.modrinth-account-required.open-browser-again-button": {
|
||||
"message": "Browser erneut öffnen"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-button": {
|
||||
"message": "Bei Modrinth anmelden"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-heading": {
|
||||
"message": "Bei einem Modrinth-Konto anmelden"
|
||||
},
|
||||
"modal.modrinth-account-required.signing-in-header": {
|
||||
"message": "Anmelden"
|
||||
},
|
||||
"modal.modrinth-account-required.support-prompt": {
|
||||
"message": "Hast du Probleme bei der Anmeldung? <support>Hilfe erhalten</support>"
|
||||
},
|
||||
"modal.modrinth-account-required.waiting-for-browser": {
|
||||
"message": "Warte auf Bestätigung durch den Browser..."
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "Von der Instanz vorgegeben"
|
||||
},
|
||||
|
||||
@@ -89,6 +89,9 @@
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Unknown instance"
|
||||
},
|
||||
"app.action-bar.install.updating-shared-content": {
|
||||
"message": "Updating shared content"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "Installs"
|
||||
},
|
||||
@@ -338,6 +341,36 @@
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Running loader processors"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.added-label": {
|
||||
"message": "Added"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-body": {
|
||||
"message": "Your local instance is ahead of the users you've shared it with."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-header": {
|
||||
"message": "Your changes haven't been shared yet"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publish-button": {
|
||||
"message": "Push update"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publishing-button": {
|
||||
"message": "Pushing..."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.removed-label": {
|
||||
"message": "Removed"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-admonition-header": {
|
||||
"message": "Push update"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-description": {
|
||||
"message": "Review the content changes that will be shared with everyone using this instance."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-header": {
|
||||
"message": "Review changes"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.reviewing-button": {
|
||||
"message": "Reviewing..."
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "All data for your instance will be permanently deleted, including your worlds, configs, and all installed content."
|
||||
},
|
||||
@@ -374,6 +407,9 @@
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "project"
|
||||
},
|
||||
"app.instance.mods.locked-content": {
|
||||
"message": "Content in locked instances cannot be changed."
|
||||
},
|
||||
"app.instance.mods.project-was-added": {
|
||||
"message": "\"{name}\" was added"
|
||||
},
|
||||
@@ -389,6 +425,102 @@
|
||||
"app.instance.mods.successfully-uploaded": {
|
||||
"message": "Successfully uploaded"
|
||||
},
|
||||
"app.instance.share.empty.description": {
|
||||
"message": "You can share this instance with your friends!"
|
||||
},
|
||||
"app.instance.share.empty.heading": {
|
||||
"message": "No friends invited"
|
||||
},
|
||||
"app.instance.share.empty.invite-friends-button": {
|
||||
"message": "Invite friends"
|
||||
},
|
||||
"app.instance.share.invite-modal.heading": {
|
||||
"message": "Share {name}"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-prefix": {
|
||||
"message": "You need to sign in as"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-suffix": {
|
||||
"message": "to access this page."
|
||||
},
|
||||
"app.instance.share.locked.linked-account-fallback": {
|
||||
"message": "the linked account"
|
||||
},
|
||||
"app.instance.share.locked.signed-out-heading": {
|
||||
"message": "Not signed in"
|
||||
},
|
||||
"app.instance.share.locked.switch-account-button": {
|
||||
"message": "Switch account"
|
||||
},
|
||||
"app.instance.share.locked.wrong-account-heading": {
|
||||
"message": "Wrong account"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-access": {
|
||||
"message": "They will no longer receive updates for this shared instance"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-installed-copy": {
|
||||
"message": "Any copy they already installed will stay on their device"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-invite-again": {
|
||||
"message": "You can invite them again later"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-last-user": {
|
||||
"message": "This is the last user, sharing will be turned off for this instance"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effects-label": {
|
||||
"message": "What happens?"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.header": {
|
||||
"message": "Revoke access"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.remove-button": {
|
||||
"message": "Revoke access"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.user-avatar-alt": {
|
||||
"message": "{username}'s avatar"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.warning-body": {
|
||||
"message": "If you revoke {username}'s access to this shared instance, you'll need to invite them again before they can receive updates."
|
||||
},
|
||||
"app.instance.share.sign-in.button": {
|
||||
"message": "Sign in"
|
||||
},
|
||||
"app.instance.share.unlink.body": {
|
||||
"message": "You must unlink this modpack to share your instance"
|
||||
},
|
||||
"app.instance.share.unlink.header": {
|
||||
"message": "Sharing requires unlinking"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.body": {
|
||||
"message": "This shared instance is already installed as <bold>{instanceName}</bold>. Are you sure you want to install another copy?"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.header": {
|
||||
"message": "Shared instance already installed"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.install-anyway": {
|
||||
"message": "Install anyway"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.instance": {
|
||||
"message": "Instance"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.fallback-username": {
|
||||
"message": "the linked account"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.owner-admonition-body-v2": {
|
||||
"message": "to manage this shared instance. You won't be able to push updates to users."
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.sign-in-as-label": {
|
||||
"message": "Sign in as"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.signed-out-header": {
|
||||
"message": "You need to sign in to Modrinth"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.user-admonition-body-v2": {
|
||||
"message": "to receive updates for this shared instance."
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.warning-header": {
|
||||
"message": "You are using the wrong Modrinth account"
|
||||
},
|
||||
"app.instance.worlds.add-server": {
|
||||
"message": "Add server"
|
||||
},
|
||||
@@ -440,8 +572,20 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Search {count} worlds..."
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"message": "Dont install"
|
||||
"app.modal.install-to-play.additional-context": {
|
||||
"message": "Additional context"
|
||||
},
|
||||
"app.modal.install-to-play.additional-context-placeholder": {
|
||||
"message": "Include links and images if possible and relevant"
|
||||
},
|
||||
"app.modal.install-to-play.content-you-are-reporting": {
|
||||
"message": "Instance you’re reporting"
|
||||
},
|
||||
"app.modal.install-to-play.delete-instance": {
|
||||
"message": "Delete instance"
|
||||
},
|
||||
"app.modal.install-to-play.external-files-dont-install": {
|
||||
"message": "Don't install"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Install to play"
|
||||
@@ -458,12 +602,51 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# mod} other {# mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.report-description": {
|
||||
"message": "Use this form to report instances that may violate our <rules-link>Rules</rules-link> or <terms-link>Terms of Use</terms-link>."
|
||||
},
|
||||
"app.modal.install-to-play.report-image-invalid-type": {
|
||||
"message": "File is not an accepted image type"
|
||||
},
|
||||
"app.modal.install-to-play.report-image-too-large": {
|
||||
"message": "File exceeds the 1 MiB size limit"
|
||||
},
|
||||
"app.modal.install-to-play.report-legal-claims": {
|
||||
"message": "For DMCA notices or other legal claims, see our <copyright-link>Copyright Policy</copyright-link>."
|
||||
},
|
||||
"app.modal.install-to-play.report-reason": {
|
||||
"message": "Which rule does this instance violate?"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.inappropriate": {
|
||||
"message": "Inappropriate"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.malicious": {
|
||||
"message": "Malicious"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.spam": {
|
||||
"message": "Spam"
|
||||
},
|
||||
"app.modal.install-to-play.report-shared-instance-header": {
|
||||
"message": "Report shared instance"
|
||||
},
|
||||
"app.modal.install-to-play.report-submitted": {
|
||||
"message": "Report submitted"
|
||||
},
|
||||
"app.modal.install-to-play.report-support-and-bugs": {
|
||||
"message": "For support requests, contact our <support-link>support team</support-link>. For bug reports, open a <github-link>GitHub issue</github-link>."
|
||||
},
|
||||
"app.modal.install-to-play.reviewed-files": {
|
||||
"message": "A file is only reviewed if it’s published to Modrinth, regardless of its file format (including .mrpack)."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Shared instance"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance-content": {
|
||||
"message": "Shared instance content"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance-unknown-files-description": {
|
||||
"message": "This shared instance contains files that aren’t published on Modrinth. We strongly recommend only installing files from sources you trust."
|
||||
},
|
||||
"app.modal.install-to-play.unknown-files-description": {
|
||||
"message": "This server modpack contains files that aren’t published on Modrinth. We strongly recommend only installing files from sources you trust."
|
||||
},
|
||||
@@ -482,8 +665,23 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Removed"
|
||||
},
|
||||
"app.modal.update-to-play.server-modpack-unknown-files-description": {
|
||||
"message": "This server modpack update contains files that aren’t published on Modrinth. We strongly recommend only installing files from sources you trust."
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-added-label": {
|
||||
"message": "Added"
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-removed-label": {
|
||||
"message": "Removed"
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-unknown-files-description": {
|
||||
"message": "This shared instance update contains files that aren’t published on Modrinth. We strongly recommend only installing files from sources you trust."
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Update required"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "An update is required to play {name}. Please update to the latest version to launch the game."
|
||||
"message": "An update is required to play {name}. Please update to latest version to launch the game."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "This project is already installed"
|
||||
@@ -740,6 +938,39 @@
|
||||
"app.world.world-item.players-online": {
|
||||
"message": "{count} online"
|
||||
},
|
||||
"content.shared-instance.change-version-body": {
|
||||
"message": "Changing the version only changes your local copy. Future shared instance updates may restore or change it again."
|
||||
},
|
||||
"content.shared-instance.delete-bulk-body": {
|
||||
"message": "Some selected projects are part of the shared instance. Deleting them only changes your local copy, and future shared instance updates may restore or change them again."
|
||||
},
|
||||
"content.shared-instance.delete-button": {
|
||||
"message": "Delete anyway"
|
||||
},
|
||||
"content.shared-instance.delete-many-button": {
|
||||
"message": "Delete {count, number} projects anyway"
|
||||
},
|
||||
"content.shared-instance.delete-single-body": {
|
||||
"message": "Deleting it only changes your local copy. Future shared instance updates may restore or change it again."
|
||||
},
|
||||
"content.shared-instance.disable-bulk-body": {
|
||||
"message": "Some selected projects are part of the shared instance. Disabling them only changes your local copy, and future shared instance updates may re-enable, restore, or change them again."
|
||||
},
|
||||
"content.shared-instance.disable-button": {
|
||||
"message": "Disable anyway"
|
||||
},
|
||||
"content.shared-instance.disable-many-button": {
|
||||
"message": "Disable {count, number} projects anyway"
|
||||
},
|
||||
"content.shared-instance.disable-single-body": {
|
||||
"message": "Disabling it only changes your local copy. Future shared instance updates may re-enable, restore, or change it again."
|
||||
},
|
||||
"content.shared-instance.unlink-body": {
|
||||
"message": "Unlinking only changes your local copy. Future shared instance updates may restore or change it again."
|
||||
},
|
||||
"content.shared-instance.warning-header": {
|
||||
"message": "This is part of the shared instance"
|
||||
},
|
||||
"friends.action.add-friend": {
|
||||
"message": "Add a friend"
|
||||
},
|
||||
@@ -803,6 +1034,48 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Sign in to a Modrinth account</link> to add friends and see what they're playing!"
|
||||
},
|
||||
"installation-settings.shared-instance.linked-title": {
|
||||
"message": "Linked shared instance"
|
||||
},
|
||||
"installation-settings.shared-instance.title": {
|
||||
"message": "Unpublish instance"
|
||||
},
|
||||
"installation-settings.shared-instance.unlink-button": {
|
||||
"message": "Unlink shared instance"
|
||||
},
|
||||
"installation-settings.shared-instance.unlink-description": {
|
||||
"message": "Disconnect this local instance from future shared updates."
|
||||
},
|
||||
"installation-settings.shared-instance.unlinking-button": {
|
||||
"message": "Unlinking..."
|
||||
},
|
||||
"installation-settings.shared-instance.unpublish-button": {
|
||||
"message": "Unpublish shared instance"
|
||||
},
|
||||
"installation-settings.shared-instance.unpublish-description": {
|
||||
"message": "Remove this shared instance from Modrinth and stop sending updates to anyone using it. Your local instance will not be affected."
|
||||
},
|
||||
"installation-settings.shared-instance.unpublishing-button": {
|
||||
"message": "Unpublishing..."
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.admonition-body": {
|
||||
"message": "This only affects your local instance. Your installed content will stay on this device, and the shared instance and other people using it will not be affected."
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.admonition-header": {
|
||||
"message": "Unlinking shared instance"
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.header": {
|
||||
"message": "Unlink shared instance"
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.admonition-body": {
|
||||
"message": "This deletes the shared instance from Modrinth's servers. People using it in the Modrinth App will stop receiving updates, but your local instance and its content will stay on this device."
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.admonition-header": {
|
||||
"message": "Unpublishing shared instance"
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.header": {
|
||||
"message": "Unpublish shared instance"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "Create shortcut"
|
||||
},
|
||||
@@ -872,6 +1145,12 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "Save as..."
|
||||
},
|
||||
"instance.locked.delete-button": {
|
||||
"message": "Delete instance"
|
||||
},
|
||||
"instance.locked.play-tooltip": {
|
||||
"message": "This instance has been locked"
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "Never played"
|
||||
},
|
||||
@@ -1010,6 +1289,9 @@
|
||||
"instance.settings.tabs.installation.loader-version": {
|
||||
"message": "{loader} version"
|
||||
},
|
||||
"instance.settings.tabs.installation.locked": {
|
||||
"message": "Installation settings are unavailable while this instance is locked."
|
||||
},
|
||||
"instance.settings.tabs.java": {
|
||||
"message": "Java and memory"
|
||||
},
|
||||
@@ -1049,6 +1331,9 @@
|
||||
"instance.settings.tabs.java.java-path-placeholder": {
|
||||
"message": "/path/to/java"
|
||||
},
|
||||
"instance.settings.tabs.sharing": {
|
||||
"message": "Sharing"
|
||||
},
|
||||
"instance.settings.tabs.window": {
|
||||
"message": "Window"
|
||||
},
|
||||
@@ -1079,6 +1364,57 @@
|
||||
"instance.settings.tabs.window.width.enter": {
|
||||
"message": "Enter width..."
|
||||
},
|
||||
"instance.shared-instance.error.title": {
|
||||
"message": "Something has gone wrong"
|
||||
},
|
||||
"instance.shared-instance.owner-tooltip": {
|
||||
"message": "This instance's content is being shared to other users."
|
||||
},
|
||||
"instance.shared-instance.publish-review.added-label": {
|
||||
"message": "Added"
|
||||
},
|
||||
"instance.shared-instance.publish-review.admonition-header": {
|
||||
"message": "Push update to players"
|
||||
},
|
||||
"instance.shared-instance.publish-review.config-title-v2": {
|
||||
"message": "Select config files"
|
||||
},
|
||||
"instance.shared-instance.publish-review.description": {
|
||||
"message": "Review the content changes and choose any config files to include in this update."
|
||||
},
|
||||
"instance.shared-instance.publish-review.header": {
|
||||
"message": "Review changes"
|
||||
},
|
||||
"instance.shared-instance.publish-review.publish-button": {
|
||||
"message": "Push update"
|
||||
},
|
||||
"instance.shared-instance.publish-review.removed-label": {
|
||||
"message": "Removed"
|
||||
},
|
||||
"instance.shared-instance.tooltip": {
|
||||
"message": "This instance's content is being managed by someone else."
|
||||
},
|
||||
"instance.shared-instance.unavailable.access-revoked-text": {
|
||||
"message": "Your access to the shared instance was revoked. This instance is still available, but it is no longer linked and will no longer receive updates."
|
||||
},
|
||||
"instance.shared-instance.unavailable.deleted-text": {
|
||||
"message": "The primary instance was deleted. This instance is still available, but it is no longer linked and will no longer receive updates."
|
||||
},
|
||||
"instance.shared-instance.unavailable.locked-text": {
|
||||
"message": "This shared instance was locked by the Content Moderation team. It will no longer receive updates from the primary instance and cannot be played."
|
||||
},
|
||||
"instance.shared-instance.unavailable.locked-title": {
|
||||
"message": "Instance locked"
|
||||
},
|
||||
"instance.shared-instance.unavailable.manager-fallback": {
|
||||
"message": "the instance manager"
|
||||
},
|
||||
"instance.shared-instance.unavailable.text": {
|
||||
"message": "Your local instance is still available, but it is no longer linked and won't receive updates."
|
||||
},
|
||||
"instance.shared-instance.unavailable.title": {
|
||||
"message": "Shared instance no longer available"
|
||||
},
|
||||
"instance.worlds.a_minecraft_server": {
|
||||
"message": "A Minecraft Server"
|
||||
},
|
||||
@@ -1163,6 +1499,42 @@
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "Sign in to Microsoft"
|
||||
},
|
||||
"modal.modrinth-account-required.browser-description": {
|
||||
"message": "A new tab opened to sign in. Complete the sign in there, then return to the app."
|
||||
},
|
||||
"modal.modrinth-account-required.cancel-button": {
|
||||
"message": "Cancel"
|
||||
},
|
||||
"modal.modrinth-account-required.continue-in-browser-heading": {
|
||||
"message": "Continue in your browser"
|
||||
},
|
||||
"modal.modrinth-account-required.create-account-button": {
|
||||
"message": "Create an account"
|
||||
},
|
||||
"modal.modrinth-account-required.description": {
|
||||
"message": "You'll need to sign into your Modrinth account before you can use this feature."
|
||||
},
|
||||
"modal.modrinth-account-required.header": {
|
||||
"message": "Account required"
|
||||
},
|
||||
"modal.modrinth-account-required.open-browser-again-button": {
|
||||
"message": "Open browser again"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-button": {
|
||||
"message": "Sign in to Modrinth"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-heading": {
|
||||
"message": "Sign in to a Modrinth account"
|
||||
},
|
||||
"modal.modrinth-account-required.signing-in-header": {
|
||||
"message": "Signing in"
|
||||
},
|
||||
"modal.modrinth-account-required.support-prompt": {
|
||||
"message": "Having trouble signing in? <support>Get support</support>"
|
||||
},
|
||||
"modal.modrinth-account-required.waiting-for-browser": {
|
||||
"message": "Waiting for browser confirmation..."
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "Provided by the instance"
|
||||
},
|
||||
|
||||
@@ -425,9 +425,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Buscar en {count} mundos..."
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"message": "No instalar"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Instalar para jugar"
|
||||
},
|
||||
@@ -467,9 +464,6 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Eliminado"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Se requiere una actualización para jugar {name}. Por favor, actualiza a la versión más reciente para iniciar el juego."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Este proyecto ya está instalado"
|
||||
},
|
||||
|
||||
@@ -287,9 +287,6 @@
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Actualiza para jugar"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Una actualización es requerida para jugar {name}. Por favor actualízala a la versión más reciente para ejecutar el juego."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "El proyecto ya está instalado"
|
||||
},
|
||||
|
||||
@@ -20,6 +20,18 @@
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Yritä uudelleen"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Peruutettu"
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Ei voitu ladata tiedostoja"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "Ladattu tiedosto on vioittunut"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Ei voitu tallentaa tiedostoja"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Tuntematon instanssi"
|
||||
},
|
||||
@@ -353,6 +365,9 @@
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Asenna pelataksesi"
|
||||
},
|
||||
"app.modal.install-to-play.install-anyway": {
|
||||
"message": "Asenna silti"
|
||||
},
|
||||
"app.modal.install-to-play.install-button": {
|
||||
"message": "Asenna"
|
||||
},
|
||||
@@ -368,15 +383,18 @@
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Päivitä pelataksesi"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Pävitys vaaditaan pelataksesi {name}. Päivitä viimeisimpään versioon pelataksesi."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Tämä projekti on jo asennettu"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Takaisin sisällön löytöön"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Asennetaan"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "On jo asennettu"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Kehittäjätila käytössä."
|
||||
},
|
||||
@@ -548,6 +566,12 @@
|
||||
"app.skins.title": {
|
||||
"message": "Skinivalinta"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "Poista käytöstä"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "Ota käyttöön"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Modrinth App versio {version} on ladattu. Voit käynnistää sovelluksen uudelleen päivittääksesi heti tai antaa päivityksen asentua automaattisesti, kun suljet Modrinth Appin."
|
||||
},
|
||||
@@ -659,6 +683,9 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Kirjaudu Modrinth-tilille</link> lisätäksesi ystäviä ja nähdäksesi mitä he pelaavat!"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "Luo pikakuvake"
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "Lisää ja pelaa"
|
||||
},
|
||||
|
||||
@@ -260,9 +260,6 @@
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Mag-update upang malaro"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Kailangang mag-update upang malaro ang {name}. Mangyaring mag-update sa pinakabagong bersiyon upang ma-launch ang laro."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Naka-install na ang proyektong ito"
|
||||
},
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"app.action-bar.downloading-java": {
|
||||
"message": "Téléchargement de Java {version} en cours"
|
||||
"message": "Téléchargement de Java {version}"
|
||||
},
|
||||
"app.action-bar.downloading-update": {
|
||||
"message": "Téléchargement de la mise à jour"
|
||||
@@ -89,6 +89,9 @@
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Instance inconnue"
|
||||
},
|
||||
"app.action-bar.install.updating-shared-content": {
|
||||
"message": "Mise à jour du contenu partagé"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "Installations"
|
||||
},
|
||||
@@ -125,6 +128,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Voir les journaux"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "Tout accepter"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "Les publicités rendent Modrinth possible et financent les rémunérations des créateurs. Nos partenaires peuvent stocker des cookies ou y accéder au sein de l'application afin de personnaliser les publicités et de mesurer les performances."
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "Gérer les préférences"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "Tout refuser"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "Votre vie privée et comment les publicités soutiennent Modrinth"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Permet un rendu avancé tel que des effets de flou qui peuvent causer des problèmes de performance sans rendu accéléré par le matériel."
|
||||
},
|
||||
@@ -138,7 +156,7 @@
|
||||
"message": "Couleur du thème"
|
||||
},
|
||||
"app.appearance-settings.default-landing-page.description": {
|
||||
"message": "Modifier la page sur laquelle le lanceur s'ouvre."
|
||||
"message": "Modifier la page sur laquelle le launcher s'ouvre."
|
||||
},
|
||||
"app.appearance-settings.default-landing-page.home": {
|
||||
"message": "Accueil"
|
||||
@@ -276,7 +294,7 @@
|
||||
"message": "Téléchargement de Minecraft"
|
||||
},
|
||||
"app.install.phase.downloading_pack_file": {
|
||||
"message": "Téléchargement du fichier de pack"
|
||||
"message": "Téléchargement le fichier de pack"
|
||||
},
|
||||
"app.install.phase.extracting_overrides": {
|
||||
"message": "Extraction des fichiers personnalisés"
|
||||
@@ -323,6 +341,36 @@
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Exécution des processeurs du chargeur"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.added-label": {
|
||||
"message": "Ajouté"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-body": {
|
||||
"message": "Votre instance locale est en avance sur celles des utilisateurs avec lesquels vous l’avez partagée."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-header": {
|
||||
"message": "Vos modifications n’ont pas encore été partagées"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publish-button": {
|
||||
"message": "Publier la mise à jour"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publishing-button": {
|
||||
"message": "Publication..."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.removed-label": {
|
||||
"message": "Supprimé"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-admonition-header": {
|
||||
"message": "Publier la mise à jour"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-description": {
|
||||
"message": "Examiner les modifications de contenu qui seront partagées avec tous les utilisateurs de cette instance."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-header": {
|
||||
"message": "Examiner les modifications"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.reviewing-button": {
|
||||
"message": "Examination..."
|
||||
},
|
||||
"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é."
|
||||
},
|
||||
@@ -359,6 +407,9 @@
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "projet"
|
||||
},
|
||||
"app.instance.mods.locked-content": {
|
||||
"message": "Le contenu dans les instances verrouillées ne peut pas être modifié."
|
||||
},
|
||||
"app.instance.mods.project-was-added": {
|
||||
"message": "« {name} » a été ajouté"
|
||||
},
|
||||
@@ -374,6 +425,102 @@
|
||||
"app.instance.mods.successfully-uploaded": {
|
||||
"message": "Mis en ligne avec succès"
|
||||
},
|
||||
"app.instance.share.empty.description": {
|
||||
"message": "Vous pouvez partager cette instance avec vos amis !"
|
||||
},
|
||||
"app.instance.share.empty.heading": {
|
||||
"message": "Aucun ami invité"
|
||||
},
|
||||
"app.instance.share.empty.invite-friends-button": {
|
||||
"message": "Inviter des amis"
|
||||
},
|
||||
"app.instance.share.invite-modal.heading": {
|
||||
"message": "Partager {name}"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-prefix": {
|
||||
"message": "Vous devez vous connecter en tant que"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-suffix": {
|
||||
"message": "pour accéder à cette page."
|
||||
},
|
||||
"app.instance.share.locked.linked-account-fallback": {
|
||||
"message": "le compte lié"
|
||||
},
|
||||
"app.instance.share.locked.signed-out-heading": {
|
||||
"message": "Non connecté"
|
||||
},
|
||||
"app.instance.share.locked.switch-account-button": {
|
||||
"message": "Changer de compte"
|
||||
},
|
||||
"app.instance.share.locked.wrong-account-heading": {
|
||||
"message": "Mauvais compte"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-access": {
|
||||
"message": "Ils vont désormais cesser de recevoir des mises à jour pour cette instance partagée"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-installed-copy": {
|
||||
"message": "N'importe copie qu'ils ont installée va rester sur leur appareil"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-invite-again": {
|
||||
"message": "Vous pouvez les inviter plus tard"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-last-user": {
|
||||
"message": "C'est le dernier utilisateur, le partage va être désactivé pour cette instance"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effects-label": {
|
||||
"message": "Que se passe-t-il ?"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.header": {
|
||||
"message": "Révoquer l'accès"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.remove-button": {
|
||||
"message": "Révoquer l'accès"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.user-avatar-alt": {
|
||||
"message": "avatar de {username}"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.warning-body": {
|
||||
"message": "Si vous révoquez l'accès de {username} à cette instance partagée, vous aurez besoin de les inviter de nouveau avant qu'ils puissent recevoir des mises à jour."
|
||||
},
|
||||
"app.instance.share.sign-in.button": {
|
||||
"message": "Se connecter"
|
||||
},
|
||||
"app.instance.share.unlink.body": {
|
||||
"message": "Vous devez délier ce modpack pour partager votre instance"
|
||||
},
|
||||
"app.instance.share.unlink.header": {
|
||||
"message": "Partager nécessite de délier"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.body": {
|
||||
"message": "Cette instance partagée est déjà installée en tant que <bold>{instanceName}</bold>. Êtes-vous sûr de vouloir installer une autre copie ?"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.header": {
|
||||
"message": "L'instance partagée est déjà installée"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.install-anyway": {
|
||||
"message": "Installer quand même"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.instance": {
|
||||
"message": "Instance"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.fallback-username": {
|
||||
"message": "le compte lié"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.owner-admonition-body-v2": {
|
||||
"message": "pour gérer cette instance partagée. Vous ne pourrez pas déployer des mises à jour aux utilisateurs."
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.sign-in-as-label": {
|
||||
"message": "Se connecter en tant que"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.signed-out-header": {
|
||||
"message": "Vous devez vous connecter à Modrinth"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.user-admonition-body-v2": {
|
||||
"message": "pour recevoir des mises à jour pour cette instance partagée."
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.warning-header": {
|
||||
"message": "Vous utilisez le mauvais compte Modrinth"
|
||||
},
|
||||
"app.instance.worlds.add-server": {
|
||||
"message": "Ajouter le serveur"
|
||||
},
|
||||
@@ -425,7 +572,19 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Rechercher {count} mondes..."
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"app.modal.install-to-play.additional-context": {
|
||||
"message": "Contexte additionnel"
|
||||
},
|
||||
"app.modal.install-to-play.additional-context-placeholder": {
|
||||
"message": "Si possible, incluez des liens et des images pertinentes"
|
||||
},
|
||||
"app.modal.install-to-play.content-you-are-reporting": {
|
||||
"message": "L'instance que vous signalez"
|
||||
},
|
||||
"app.modal.install-to-play.delete-instance": {
|
||||
"message": "Supprimer l'instance"
|
||||
},
|
||||
"app.modal.install-to-play.external-files-dont-install": {
|
||||
"message": "Ne pas installer"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
@@ -443,12 +602,42 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# mod} other {# mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.report-description": {
|
||||
"message": "Utilisez ce formulaire pour signaler les instances qui peuvent enfreindre nos <rules-link>Règles</rules-link> ou <terms-link>les Conditions d'Utilisation</terms-link>."
|
||||
},
|
||||
"app.modal.install-to-play.report-image-invalid-type": {
|
||||
"message": "Le fichier n'est pas un type d'image accepté"
|
||||
},
|
||||
"app.modal.install-to-play.report-image-too-large": {
|
||||
"message": "Le fichier dépasse la limite de 1 MiB"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason": {
|
||||
"message": "Quelle règle cette instance enfreint-elle ?"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.inappropriate": {
|
||||
"message": "Inapproprié"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.malicious": {
|
||||
"message": "Malicieux"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.spam": {
|
||||
"message": "Spam"
|
||||
},
|
||||
"app.modal.install-to-play.report-shared-instance-header": {
|
||||
"message": "Signaler une instance partagée"
|
||||
},
|
||||
"app.modal.install-to-play.report-submitted": {
|
||||
"message": "Signalement soumis"
|
||||
},
|
||||
"app.modal.install-to-play.reviewed-files": {
|
||||
"message": "Un fichier est seulement examiné s'il est publié sur Modrinth, peu importe son extension (y compris .mrpack)."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Instance partagée"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance-content": {
|
||||
"message": "Contenu de l'instance partagée"
|
||||
},
|
||||
"app.modal.install-to-play.unknown-files-description": {
|
||||
"message": "Ce modpack de serveur contient des fichiers qui ne sont pas publiés sur Modrinth. Nous recommandons fortement de seulement installer des fichiers de sources en qui vous avez confiance."
|
||||
},
|
||||
@@ -467,8 +656,23 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Supprimé"
|
||||
},
|
||||
"app.modal.update-to-play.server-modpack-unknown-files-description": {
|
||||
"message": "Cette mise à jour du modpack de ce serveur contient des fichiers qui ne sont pas publiés sur Modrinth. Nous recommandons fortement de seulement installer des fichiers de sources en qui vous avez confiance."
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-added-label": {
|
||||
"message": "Ajouté"
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-removed-label": {
|
||||
"message": "Supprimé"
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-unknown-files-description": {
|
||||
"message": "Cette mise à jour d'instance partagée contient des fichiers qui ne sont pas publiés sur Modrinth. Nous recommandons fortement de seulement installer des fichiers de sources en qui vous avez confiance."
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Mise à jour requise"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Une mise à jour est requise pour jouer à {name}. Veuillez mettre à jour à la dernière version pour lancer le jeu."
|
||||
"message": "Une mise à jour est requise pour jouer à {name}. Veuillez mettre à jour vers la dernière version pour lancer le jeu."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Ce projet a déjà été installé"
|
||||
@@ -497,6 +701,9 @@
|
||||
"app.settings.downloading": {
|
||||
"message": "Téléchargement de la version {version}"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "Les publicités rendent Modrinth possible et financent les rémunérations des créateurs. Nos partenaires peuvent stocker des cookies ou y accéder au sein de l'application afin de personnaliser les publicités et de mesurer les performances. Vous pouvez refuser ou gérer vos préférences ci-dessous."
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "Apparence"
|
||||
},
|
||||
@@ -539,6 +746,9 @@
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "Erreur lors du traitement du fichier"
|
||||
},
|
||||
"app.skins.ears-feature-notice": {
|
||||
"message": "Ce skin utilise des fonctionnalités du mod {ears}"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "Modifier le skin"
|
||||
},
|
||||
@@ -588,7 +798,7 @@
|
||||
"message": "Texture"
|
||||
},
|
||||
"app.skins.modal.upload-skin-first-tooltip": {
|
||||
"message": "Importez d'abord une skin !"
|
||||
"message": "Importez d'abord un skin !"
|
||||
},
|
||||
"app.skins.preview.edit-button": {
|
||||
"message": "Modifier le skin"
|
||||
@@ -665,6 +875,12 @@
|
||||
"app.skins.title": {
|
||||
"message": "Sélecteur de skin"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "Désactiver"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "Activer"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Modrinth App v{version} a finie d'être téléchargée. Rechargez pour mettre à jour maintenant, ou automatiquement quand vous fermez Modrinth App."
|
||||
},
|
||||
@@ -710,6 +926,21 @@
|
||||
"app.world.world-item.offline": {
|
||||
"message": "Hors ligne"
|
||||
},
|
||||
"content.shared-instance.change-version-body": {
|
||||
"message": "Changer la version change seulement votre copie locale. Des futures mises à jour d'instance partagées peuvent restaurer ou changer la version."
|
||||
},
|
||||
"content.shared-instance.delete-button": {
|
||||
"message": "Supprimer quand même"
|
||||
},
|
||||
"content.shared-instance.delete-many-button": {
|
||||
"message": "Supprimer {count, number} projets quand même"
|
||||
},
|
||||
"content.shared-instance.disable-button": {
|
||||
"message": "Désactiver quand même"
|
||||
},
|
||||
"content.shared-instance.disable-many-button": {
|
||||
"message": "Désactiver {count, number} projets quand même"
|
||||
},
|
||||
"friends.action.add-friend": {
|
||||
"message": "Ajouter un ami"
|
||||
},
|
||||
@@ -773,6 +1004,33 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Créer un compte Modrinth</link> pour ajouter des amis et voir à quoi ils jouent !"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "Créer un raccourci"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "Exporter le modpack"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "Lancer l'instance"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "Plus d'actions"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "Ouvrir le dossier"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "Réparer"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "Paramètres d'instance"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "Démarrage..."
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "Arrêt..."
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "Ajouter et jouer"
|
||||
},
|
||||
@@ -815,6 +1073,15 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "Sauvegarder en tant que..."
|
||||
},
|
||||
"instance.locked.delete-button": {
|
||||
"message": "Supprimer l'instance"
|
||||
},
|
||||
"instance.locked.play-tooltip": {
|
||||
"message": "Cette instance a été verrouillée"
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "Jamais joué"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "Adresse"
|
||||
},
|
||||
@@ -989,6 +1256,9 @@
|
||||
"instance.settings.tabs.java.java-path-placeholder": {
|
||||
"message": "/chemin/vers/java"
|
||||
},
|
||||
"instance.settings.tabs.sharing": {
|
||||
"message": "Partage"
|
||||
},
|
||||
"instance.settings.tabs.window": {
|
||||
"message": "Fenêtre"
|
||||
},
|
||||
@@ -1019,6 +1289,51 @@
|
||||
"instance.settings.tabs.window.width.enter": {
|
||||
"message": "Entrer la largeur..."
|
||||
},
|
||||
"instance.shared-instance.error.title": {
|
||||
"message": "Quelque chose s'est mal passé"
|
||||
},
|
||||
"instance.shared-instance.owner-tooltip": {
|
||||
"message": "Le contenu de cette instance est partagé à d'autres utilisateurs."
|
||||
},
|
||||
"instance.shared-instance.publish-review.added-label": {
|
||||
"message": "Ajouté"
|
||||
},
|
||||
"instance.shared-instance.publish-review.admonition-header": {
|
||||
"message": "Déployer la mise à jour aux joueurs"
|
||||
},
|
||||
"instance.shared-instance.publish-review.config-title-v2": {
|
||||
"message": "Sélectionner les fichiers de configuration"
|
||||
},
|
||||
"instance.shared-instance.publish-review.description": {
|
||||
"message": "Examiner les changements de contenu et choisir n'importe quel fichier de configuration à inclure dans cette mise à jour."
|
||||
},
|
||||
"instance.shared-instance.publish-review.header": {
|
||||
"message": "Examiner les changements"
|
||||
},
|
||||
"instance.shared-instance.publish-review.publish-button": {
|
||||
"message": "Déployer la mise à jour"
|
||||
},
|
||||
"instance.shared-instance.publish-review.removed-label": {
|
||||
"message": "Supprimé"
|
||||
},
|
||||
"instance.shared-instance.tooltip": {
|
||||
"message": "Le contenu de cette instance est gérée par quelqu'un d'autre."
|
||||
},
|
||||
"instance.shared-instance.unavailable.deleted-text": {
|
||||
"message": "L'instance principale a été supprimée. Cette instance est encore disponible, mais n'est plus liée et va cesser de recevoir des mises à jour."
|
||||
},
|
||||
"instance.shared-instance.unavailable.locked-title": {
|
||||
"message": "Instance verrouillée"
|
||||
},
|
||||
"instance.shared-instance.unavailable.manager-fallback": {
|
||||
"message": "le gestionnaire d'instance"
|
||||
},
|
||||
"instance.shared-instance.unavailable.text": {
|
||||
"message": "L'instance principale a été supprimée. Cette instance est encore disponible, mais n'est plus liée et ne va plus recevoir de mises à jour."
|
||||
},
|
||||
"instance.shared-instance.unavailable.title": {
|
||||
"message": "Instance partagée n'est plus disponible"
|
||||
},
|
||||
"instance.worlds.a_minecraft_server": {
|
||||
"message": "Un Serveur Minecraft"
|
||||
},
|
||||
@@ -1082,6 +1397,63 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "Se connecter à Minecraft"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "Vous avez besoin d'un compte Microsoft qui possède Minecraft avant de jouer."
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "Se connecter à un compte Microsoft"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "Pas de compte ?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "Obtenir Minecraft"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "Obtenir de l'aide"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "Minecraft requis"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "Se connecter à Microsoft"
|
||||
},
|
||||
"modal.modrinth-account-required.browser-description": {
|
||||
"message": "A nouvel onglet a été ouvert pour vous connecter. Finissez la connexion, puis retournez dans l'application."
|
||||
},
|
||||
"modal.modrinth-account-required.cancel-button": {
|
||||
"message": "Annuler"
|
||||
},
|
||||
"modal.modrinth-account-required.continue-in-browser-heading": {
|
||||
"message": "Continuer dans votre navigateur"
|
||||
},
|
||||
"modal.modrinth-account-required.create-account-button": {
|
||||
"message": "Créer un compte"
|
||||
},
|
||||
"modal.modrinth-account-required.description": {
|
||||
"message": "Vous aurez besoin de vous connecter à votre compte Modrinth avant de pouvoir utiliser cette fonctionnalité."
|
||||
},
|
||||
"modal.modrinth-account-required.header": {
|
||||
"message": "Compte requis"
|
||||
},
|
||||
"modal.modrinth-account-required.open-browser-again-button": {
|
||||
"message": "Ouvrir de nouveau le navigateur"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-button": {
|
||||
"message": "Se connecter à Modrinth"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-heading": {
|
||||
"message": "Se connecter à un compte Modrinth"
|
||||
},
|
||||
"modal.modrinth-account-required.signing-in-header": {
|
||||
"message": "Connexion"
|
||||
},
|
||||
"modal.modrinth-account-required.support-prompt": {
|
||||
"message": "Vous avez des problèmes à vous connecter ? <support>Obtenez de l'aide</support>"
|
||||
},
|
||||
"modal.modrinth-account-required.waiting-for-browser": {
|
||||
"message": "En attente de la confirmation du navigateur..."
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "Procuré par l'instance"
|
||||
},
|
||||
|
||||
@@ -155,9 +155,6 @@
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "צריך לעדכן כדי לשחק"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "עדכון נדרש כדי לשחק ב{name}. ניתן להתחיל את המשחק רק לאחר עדכון לגרסה החדשה."
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "מצב מפתח מופעל."
|
||||
},
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
"message": "Letöltések"
|
||||
},
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "További futó példányok elrejtése"
|
||||
"message": "További futó játékpéldányok elrejtése"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Másolva"
|
||||
@@ -21,7 +21,7 @@
|
||||
"message": "Elutasítás"
|
||||
},
|
||||
"app.action-bar.install.open-instance": {
|
||||
"message": "Példány megnyitása"
|
||||
"message": "Játékpéldány megnyitása"
|
||||
},
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Újra"
|
||||
@@ -48,10 +48,10 @@
|
||||
"message": "Nem sikerült elmenteni a fájlokat"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "A letöltés nem sikerült"
|
||||
"message": "A letöltés nem fejeződött be"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "A játékprofil nem található"
|
||||
"message": "A játékpéldány nem található"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "A fájl elérési útja érvénytelen"
|
||||
@@ -63,7 +63,7 @@
|
||||
"message": "A modcsomag fájljainak metaadatai érvénytelenek"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "A Java telepítése nem sikerült"
|
||||
"message": "A Java telepítése nem tudott befejeződni"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "A betöltő beállítása sikertelen volt"
|
||||
@@ -72,13 +72,13 @@
|
||||
"message": "A helyi adatok frissítése nem sikerült"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "A Minecraft telepítése sikertelen volt"
|
||||
"message": "A Minecraft telepítése meghiúsult"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "Nem sikerült elérni Modrinthot"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "Nincs felülírási jogosultság"
|
||||
"message": "Nincs írási jogosultság"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "Nem sikerült letölteni a csomagot"
|
||||
@@ -87,22 +87,25 @@
|
||||
"message": "Valami hiba történt"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Ismeretlen játékprofil"
|
||||
"message": "Ismeretlen játékpéldány"
|
||||
},
|
||||
"app.action-bar.install.updating-shared-content": {
|
||||
"message": "Megosztott tartalom frissítése"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "Telepítések"
|
||||
},
|
||||
"app.action-bar.make-primary-instance": {
|
||||
"message": "Beállítás elsődleges példányként"
|
||||
"message": "Beállítás elsődleges játékpéldányként"
|
||||
},
|
||||
"app.action-bar.no-instances-running": {
|
||||
"message": "Nincsenek futó példányok"
|
||||
"message": "Nincsenek futó játékpéldányok"
|
||||
},
|
||||
"app.action-bar.offline": {
|
||||
"message": "Offline"
|
||||
},
|
||||
"app.action-bar.primary-instance": {
|
||||
"message": "Elsődleges példány"
|
||||
"message": "Elsődleges játékpéldány"
|
||||
},
|
||||
"app.action-bar.reload-to-update": {
|
||||
"message": "Töltsd újra a frissítéshez"
|
||||
@@ -111,7 +114,7 @@
|
||||
"message": "További futó pédányok megjelenítése"
|
||||
},
|
||||
"app.action-bar.stop-instance": {
|
||||
"message": "Példány leállítása"
|
||||
"message": "Játékpéldány leállítása"
|
||||
},
|
||||
"app.action-bar.update": {
|
||||
"message": "Frissítés"
|
||||
@@ -120,10 +123,25 @@
|
||||
"message": "Aktív letöltések megtekintése"
|
||||
},
|
||||
"app.action-bar.view-instance": {
|
||||
"message": "Példányok megtekintése"
|
||||
"message": "Játékpéldány megtekintése"
|
||||
},
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Naplózások megtekintése"
|
||||
"message": "Naplók megtekintése"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "Összes elfogadása"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "A hirdetések teszik lehetővé a Modrinth működését, és biztosítják a tartalomkészítők juttatásait. Partnereink sütiket tárolhatnak vagy érhetnek el az alkalmazásban a hirdetések személyre szabása és a teljesítmény mérése céljából."
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "Beállítások kezelése"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "Összes elutasítása"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "Adataid védelme és a hirdetések szerepe a Modrinth működésében"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Lehetővé teszi olyan speciális megjelenítési effektusok használatát, mint például az elmosódás, amelyek hardveres gyorsítás nélkül teljesítménycsökkenést okozhatnak."
|
||||
@@ -177,7 +195,7 @@
|
||||
"message": "Válassz egy lehetőséget"
|
||||
},
|
||||
"app.appearance-settings.show-play-time.description": {
|
||||
"message": "Megmutatja, mennyi időt töltöttél egy példányban."
|
||||
"message": "Megmutatja, mennyi időt töltöttél egy játékpéldányban."
|
||||
},
|
||||
"app.appearance-settings.show-play-time.title": {
|
||||
"message": "Játékidő megjelenítése"
|
||||
@@ -207,13 +225,13 @@
|
||||
"message": "Nem lehet elérni a hitelesítési kiszolgálókat"
|
||||
},
|
||||
"app.browse.add-servers-to-instance": {
|
||||
"message": "Szerver hozzáadása a példányhoz"
|
||||
"message": "Szerver hozzáadása a játékpéldányhoz"
|
||||
},
|
||||
"app.browse.add-to-an-instance": {
|
||||
"message": "Hozzáadás egy példányhoz"
|
||||
"message": "Hozzáadás egy játékpéldányhoz"
|
||||
},
|
||||
"app.browse.add-to-instance": {
|
||||
"message": "Példányhoz adás"
|
||||
"message": "Hozzáadás a játékpéldányhoz"
|
||||
},
|
||||
"app.browse.add-to-instance-name": {
|
||||
"message": "Hozzáadás ehhez: {instanceName}"
|
||||
@@ -225,7 +243,7 @@
|
||||
"message": "Már hozzá van adva"
|
||||
},
|
||||
"app.browse.back-to-instance": {
|
||||
"message": "Vissza a példányhoz"
|
||||
"message": "Vissza a játékpéldányhoz"
|
||||
},
|
||||
"app.browse.discover-content": {
|
||||
"message": "Tartalom böngészése"
|
||||
@@ -240,7 +258,7 @@
|
||||
"message": "Modcsomagok"
|
||||
},
|
||||
"app.browse.server-instance-content-warning": {
|
||||
"message": "A tartalom hozzáadása ronthatja a kompatibilitást a szerverhez való csatlakozáskor. A hozzáadott tartalom elveszik, ha frissíted a szerverprofil tartalmát."
|
||||
"message": "A tartalom hozzáadása ronthatja a kompatibilitást a szerverhez való csatlakozáskor. A hozzáadott tartalom elveszik, ha frissíted a szerverpéldány tartalmát."
|
||||
},
|
||||
"app.browse.server.installing": {
|
||||
"message": "Letöltés"
|
||||
@@ -270,25 +288,25 @@
|
||||
"message": "1.0.0"
|
||||
},
|
||||
"app.install.phase.downloading_content": {
|
||||
"message": "Tartalom letöltése"
|
||||
"message": "A tartalom letöltése..."
|
||||
},
|
||||
"app.install.phase.downloading_minecraft": {
|
||||
"message": "Minecraft letöltése"
|
||||
"message": "A Minecraft letöltése..."
|
||||
},
|
||||
"app.install.phase.downloading_pack_file": {
|
||||
"message": "Csomagfájlok letöltése"
|
||||
"message": "A csomagfájl letöltése..."
|
||||
},
|
||||
"app.install.phase.extracting_overrides": {
|
||||
"message": "Felülírások kibontása"
|
||||
"message": "Felülírások kibontása..."
|
||||
},
|
||||
"app.install.phase.finalizing": {
|
||||
"message": "Befejezés"
|
||||
"message": "Befejezés..."
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Telepítésre vár"
|
||||
"message": "Telepítésre vár..."
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Java előkészítése"
|
||||
"message": "A Java előkészítése..."
|
||||
},
|
||||
"app.install.phase.preparing_java.downloading": {
|
||||
"message": "A Java {version} letöltése..."
|
||||
@@ -303,14 +321,11 @@
|
||||
"message": "A Java {version} előkészítése..."
|
||||
},
|
||||
"app.install.phase.preparing_java.validating": {
|
||||
"message": "A Java {version} ellenőrzése"
|
||||
"message": "A Java {version} ellenőrzése..."
|
||||
},
|
||||
"app.install.phase.reading_pack_manifest": {
|
||||
"message": "Csomag adati kiolvasása"
|
||||
},
|
||||
"app.install.phase.resolving_loader": {
|
||||
"message": ""
|
||||
},
|
||||
"app.install.phase.resolving_minecraft": {
|
||||
"message": "Minecraft Betöltése"
|
||||
},
|
||||
@@ -323,20 +338,50 @@
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Betöltő folyamatok futtatása"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.added-label": {
|
||||
"message": "Hozzáadva"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-body": {
|
||||
"message": "A helyi példányod előrébb tart, mint azoké a felhasználóké, akikkel megosztottad."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-header": {
|
||||
"message": "A változtatásaid még nem lettek megosztva"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publish-button": {
|
||||
"message": "Frissítés közzététele"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publishing-button": {
|
||||
"message": "Közzététel..."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.removed-label": {
|
||||
"message": "Eltávolítva"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-admonition-header": {
|
||||
"message": "Frissítés közzététele"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-description": {
|
||||
"message": "A példányt használó összes résztvevővel megosztásra kerülő tartalomváltoztatások áttekintése."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-header": {
|
||||
"message": "Változtatások áttekintése"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.reviewing-button": {
|
||||
"message": "Áttekintés..."
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "A 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."
|
||||
"message": "A játékpéldányhoz tartozó összes adat véglegesen törlődik, beleértve a világokat, a beállításokat és az összes telepített tartalmat."
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-header": {
|
||||
"message": "Ezt a műveletet nem lehet visszavonni"
|
||||
},
|
||||
"app.instance.confirm-delete.delete-button": {
|
||||
"message": "Profil törlése"
|
||||
"message": "Játékpéldány törlése"
|
||||
},
|
||||
"app.instance.confirm-delete.header": {
|
||||
"message": "Profil törlése"
|
||||
"message": "Játékpéldány törlése"
|
||||
},
|
||||
"app.instance.modpack-already-installed.body": {
|
||||
"message": "Ez a modcsomag már telepítve van a(z) <bold>{instanceName}</bold> profilban. Biztosan duplikálni szeretnéd?"
|
||||
"message": "Ez a modcsomag már telepítve van a(z) <bold>{instanceName}</bold> játékpéldányban. Biztosan duplikálni szeretnéd?"
|
||||
},
|
||||
"app.instance.modpack-already-installed.create": {
|
||||
"message": "Létrehozás"
|
||||
@@ -345,7 +390,7 @@
|
||||
"message": "A modcsomag már telepítve van"
|
||||
},
|
||||
"app.instance.modpack-already-installed.instance": {
|
||||
"message": "Példány"
|
||||
"message": "Játékpéldány"
|
||||
},
|
||||
"app.instance.mods.bulk-update.downloading-projects": {
|
||||
"message": "{current, number}/{total, number} projekt letöltése..."
|
||||
@@ -359,8 +404,11 @@
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "projekt"
|
||||
},
|
||||
"app.instance.mods.locked-content": {
|
||||
"message": "Zárolt példányokban a tartalom nem változtatható meg."
|
||||
},
|
||||
"app.instance.mods.project-was-added": {
|
||||
"message": " „{name}” hozzá lett adva"
|
||||
"message": "„{name}” hozzá lett adva"
|
||||
},
|
||||
"app.instance.mods.projects-were-added": {
|
||||
"message": "{count} projekt került hozzáadásra"
|
||||
@@ -374,6 +422,51 @@
|
||||
"app.instance.mods.successfully-uploaded": {
|
||||
"message": "Sikeresen feltöltve"
|
||||
},
|
||||
"app.instance.share.empty.description": {
|
||||
"message": "Ezt a példányt megoszthatod a barátaiddal!"
|
||||
},
|
||||
"app.instance.share.empty.heading": {
|
||||
"message": "Nincsenek barátok meghívva"
|
||||
},
|
||||
"app.instance.share.empty.invite-friends-button": {
|
||||
"message": "Barátok meghívása"
|
||||
},
|
||||
"app.instance.share.invite-modal.heading": {
|
||||
"message": "{name} megosztása"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-prefix": {
|
||||
"message": "Be kell jelentkezned mint"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-suffix": {
|
||||
"message": ", hogy hozzáférj ehhez az oldalhoz."
|
||||
},
|
||||
"app.instance.share.locked.linked-account-fallback": {
|
||||
"message": "az összekapcsolt fiók"
|
||||
},
|
||||
"app.instance.share.locked.signed-out-heading": {
|
||||
"message": "Nem vagy bejelentkezve"
|
||||
},
|
||||
"app.instance.share.locked.switch-account-button": {
|
||||
"message": "Fiókváltás"
|
||||
},
|
||||
"app.instance.share.locked.wrong-account-heading": {
|
||||
"message": "Helytelen fiók"
|
||||
},
|
||||
"app.instance.share.sign-in.button": {
|
||||
"message": "Bejelentkezés"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.install-anyway": {
|
||||
"message": "Telepítés mindenképpen"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.instance": {
|
||||
"message": "Példány"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.sign-in-as-label": {
|
||||
"message": "Bejelentkezés mint"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.signed-out-header": {
|
||||
"message": "Be kell jelentkezned a Modrinth-ba"
|
||||
},
|
||||
"app.instance.worlds.add-server": {
|
||||
"message": "Szerver hozzáadása"
|
||||
},
|
||||
@@ -381,13 +474,13 @@
|
||||
"message": "Szerverek böngészése"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.delete-button": {
|
||||
"message": "Törlés"
|
||||
"message": "Világ törlése"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.title": {
|
||||
"message": "Világ törlése"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-body": {
|
||||
"message": "Ez a világ véglegesen törölve lesz ebből a példányból. Ezt NEM tudod visszavonni!"
|
||||
"message": "Ez a világ véglegesen törölve lesz ebből a játékpéldányból. Ezt NEM tudod visszavonni!"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-header": {
|
||||
"message": "{name} törlése"
|
||||
@@ -420,14 +513,11 @@
|
||||
"message": "Ez a szerver el lesz távolítva a szerverlistádból és a játékbeli szerverlistából is. Később újra hozzáadhatod, ha tudod a címet."
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.warning-header": {
|
||||
"message": "{name} eltávolítása"
|
||||
"message": "{name} törlése"
|
||||
},
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Keresés {count} világ között..."
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"message": "Ne töltse le"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Telepítés a játékhoz"
|
||||
},
|
||||
@@ -447,7 +537,7 @@
|
||||
"message": "Egy fájlt csak akkor vizsgálnak meg, ha azt a Modrinth-en közzétették, függetlenül a fájlformátumtól (beleértve a .mrpack formátumot is)."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Megosztott profil"
|
||||
"message": "Megosztott játékpéldány"
|
||||
},
|
||||
"app.modal.install-to-play.unknown-files-description": {
|
||||
"message": "Ez a szerver-modpack olyan fájlokat tartalmaz, amelyek nem szerepelnek a Modrinth oldalon. Határozottan javasoljuk, hogy kizárólag olyan forrásokból telepíts fájlokat, amelyekben megbízol."
|
||||
@@ -467,9 +557,6 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Törölve"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Frissítés szükséges ehhez: {name}. Kérlek, frissíts a legújabb verzióra a játék elindításához."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Ez a projekt már telepítve van"
|
||||
},
|
||||
@@ -497,6 +584,9 @@
|
||||
"app.settings.downloading": {
|
||||
"message": "v{version} letöltése"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "A hirdetések teszik lehetővé a Modrinth működését, és biztosítják a tartalomkészítők juttatásait. Partnereink sütiket tárolhatnak vagy érhetnek el az alkalmazásban a hirdetések személyre szabása és a teljesítmény mérése céljából. Az alábbiakban leiratkozhatsz erről, illetve beállíthatod a preferenciáidat."
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "Megjelenés"
|
||||
},
|
||||
@@ -539,6 +629,9 @@
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "Hiba a fájl feldolgozása közben"
|
||||
},
|
||||
"app.skins.ears-feature-notice": {
|
||||
"message": "Ez a kinézet az {ears} mod funkcióit használja"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "Kinézet szerkesztése"
|
||||
},
|
||||
@@ -665,6 +758,12 @@
|
||||
"app.skins.title": {
|
||||
"message": "Kinézetváltó"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "Kikapcsolás"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "Bekapcsolás"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "A Modrinth App v{version} letöltése befejeződött. Frissítéshez válaszd ki a Frissítés opciót, vagy az alkalmazás a bezárásakor automatikusan frissül."
|
||||
},
|
||||
@@ -776,6 +875,33 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Lépj be Modrinth fiókodba</link>, hogy felvehess barátokat és lásd mivel játszanak!"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "Parancsikon létrehozása"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "Modcsomag exportálása"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "Játékpéldány elindítása"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "További műveletek"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "Mappa megnyitása"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "Javítás"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "Játékpéldány-beállítások"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "Indítás..."
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "Leállítás..."
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "Hozzáadás és csatlakozás"
|
||||
},
|
||||
@@ -783,7 +909,7 @@
|
||||
"message": "Szerver hozzáadása"
|
||||
},
|
||||
"instance.add-server.resource-pack.disabled": {
|
||||
"message": "Kikapcsolva"
|
||||
"message": "Letiltva"
|
||||
},
|
||||
"instance.add-server.resource-pack.enabled": {
|
||||
"message": "Engedélyezve"
|
||||
@@ -792,13 +918,13 @@
|
||||
"message": "Mindig kérdezzen rá"
|
||||
},
|
||||
"instance.add-server.title": {
|
||||
"message": "Adjon hozzá egy szervert"
|
||||
"message": "Szerver hozzáadása"
|
||||
},
|
||||
"instance.edit-server.title": {
|
||||
"message": "Szerver módosítása"
|
||||
},
|
||||
"instance.edit-world.hide-from-home": {
|
||||
"message": "Elrejtés a Főoldalról"
|
||||
"message": "Elrejtés a kezdőlapról"
|
||||
},
|
||||
"instance.edit-world.name": {
|
||||
"message": "Név"
|
||||
@@ -813,11 +939,14 @@
|
||||
"message": "Világ szerkesztése"
|
||||
},
|
||||
"instance.files.adding-files": {
|
||||
"message": "Fájlok hozzáadása ({completed}/{total})"
|
||||
"message": "Fájlok hozzáadása... ({completed}/{total})"
|
||||
},
|
||||
"instance.files.save-as": {
|
||||
"message": "Mentés másként..."
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "Még nem játszott"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "Cím"
|
||||
},
|
||||
@@ -828,19 +957,19 @@
|
||||
"message": "Egy Minecraft szerver"
|
||||
},
|
||||
"instance.server-modal.resource-pack": {
|
||||
"message": "Erőforráscsomag"
|
||||
"message": "Forráscsomag"
|
||||
},
|
||||
"instance.settings.tabs.general": {
|
||||
"message": "Általános"
|
||||
},
|
||||
"instance.settings.tabs.general.delete": {
|
||||
"message": "Profil törlése"
|
||||
"message": "Játékpéldány törlése"
|
||||
},
|
||||
"instance.settings.tabs.general.delete.button": {
|
||||
"message": "Profil törlése"
|
||||
"message": "Játékpéldány törlése"
|
||||
},
|
||||
"instance.settings.tabs.general.delete.description": {
|
||||
"message": "Örökké eltávolít egy profilt az eszközről, beleértve a világait, beállításait és minden telepített tartalmat. Legyen óvatos, mert ha egyszer kitöröl egy profilt, azt többé nem lehet visszaállítani."
|
||||
"message": "Örökké eltávolít egy játékpéldányt az eszközről, beleértve a világait, beállításait és minden telepített tartalmat. Legyél óvatos, mert ha egyszer kitörölsz egy játékpéldányt, azt többé nem lehet visszaállítani."
|
||||
},
|
||||
"instance.settings.tabs.general.deleting.button": {
|
||||
"message": "Törlés..."
|
||||
@@ -852,10 +981,10 @@
|
||||
"message": "Telepítés közben nem lehet duplikálni."
|
||||
},
|
||||
"instance.settings.tabs.general.duplicate-instance": {
|
||||
"message": "Profil duplikálása"
|
||||
"message": "Játékpéldány duplikálása"
|
||||
},
|
||||
"instance.settings.tabs.general.duplicate-instance.description": {
|
||||
"message": "Készít egy másolatot erről a profilról, beleértve a világokat, beállításokat, modokat, stb."
|
||||
"message": "Készít egy másolatot erről a játékpéldányról, beleértve a világokat, beállításokat, modokat stb."
|
||||
},
|
||||
"instance.settings.tabs.general.edit-icon": {
|
||||
"message": "Ikon szerkesztése"
|
||||
@@ -870,16 +999,16 @@
|
||||
"message": "Ikon kiválasztása"
|
||||
},
|
||||
"instance.settings.tabs.general.library-groups": {
|
||||
"message": "Könyvtár gyűjtemények"
|
||||
"message": "Könyvtárgyűjtemények"
|
||||
},
|
||||
"instance.settings.tabs.general.library-groups.create": {
|
||||
"message": "Új csoport létrehozása"
|
||||
"message": "Új gyűjtemény létrehozása"
|
||||
},
|
||||
"instance.settings.tabs.general.library-groups.description": {
|
||||
"message": "A könyvtárgyűjtemények segítenek külön kategóriákba rendszerezni a profiljait."
|
||||
"message": "A könyvtárgyűjtemények segítenek külön kategóriákba rendszerezni a játékpéldányokat."
|
||||
},
|
||||
"instance.settings.tabs.general.library-groups.enter-name": {
|
||||
"message": "Adja meg a gyűjtemény nevét"
|
||||
"message": "Add meg a gyűjtemény nevét"
|
||||
},
|
||||
"instance.settings.tabs.general.name": {
|
||||
"message": "Név"
|
||||
@@ -903,10 +1032,10 @@
|
||||
"message": "Kiadás"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.release.description": {
|
||||
"message": "Csak a 'kiadás' verziók fognak megjelenni az elérhető frissítések között."
|
||||
"message": "Csak a kiadás verziók fognak megjelenni az elérhető frissítések között."
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.select": {
|
||||
"message": "Válaszd ki a frissítési csatornát"
|
||||
"message": "Frissítési csatorna kiválasztása"
|
||||
},
|
||||
"instance.settings.tabs.hooks": {
|
||||
"message": "Indítási horgok"
|
||||
@@ -930,7 +1059,7 @@
|
||||
"message": "Indítás előtt"
|
||||
},
|
||||
"instance.settings.tabs.hooks.pre-launch.description": {
|
||||
"message": "Futtatás a profil futtatása előtt."
|
||||
"message": "Futtatás a játékpéldány futtatása előtt."
|
||||
},
|
||||
"instance.settings.tabs.hooks.pre-launch.enter": {
|
||||
"message": "Írjon be indítás előtti parancsokat..."
|
||||
@@ -945,7 +1074,7 @@
|
||||
"message": "Indítóparancs a Minecraft elindításához."
|
||||
},
|
||||
"instance.settings.tabs.hooks.wrapper.enter": {
|
||||
"message": "Írjon ide indítóparancsot..."
|
||||
"message": "Add meg az indítóparancsot..."
|
||||
},
|
||||
"instance.settings.tabs.installation": {
|
||||
"message": "Telepítés"
|
||||
@@ -1002,7 +1131,7 @@
|
||||
"message": "Teljes képernyő"
|
||||
},
|
||||
"instance.settings.tabs.window.fullscreen.description": {
|
||||
"message": "A játék indításakor teljes képernyős módban indítsa el (az options.txt fájl segítségével)."
|
||||
"message": "A játék az indításakor teljes képernyős módban indul el (az options.txt fájl segítségével)."
|
||||
},
|
||||
"instance.settings.tabs.window.height": {
|
||||
"message": "Magasság"
|
||||
@@ -1011,7 +1140,7 @@
|
||||
"message": "A játék ablakának magassága indításkor."
|
||||
},
|
||||
"instance.settings.tabs.window.height.enter": {
|
||||
"message": "Magaság megadása..."
|
||||
"message": "Magasság megadása..."
|
||||
},
|
||||
"instance.settings.tabs.window.width": {
|
||||
"message": "Szélesség"
|
||||
@@ -1032,13 +1161,13 @@
|
||||
"message": "Cím másolása"
|
||||
},
|
||||
"instance.worlds.create_shortcut": {
|
||||
"message": "Gyorshivatkozás létrehozása"
|
||||
"message": "Parancsikon létrehozása"
|
||||
},
|
||||
"instance.worlds.dont_show_on_home": {
|
||||
"message": "Ne mutasd a kezdőlapon"
|
||||
},
|
||||
"instance.worlds.game_already_open": {
|
||||
"message": "A profil már el van indítva"
|
||||
"message": "A játékpéldány már el van indítva"
|
||||
},
|
||||
"instance.worlds.hardcore": {
|
||||
"message": "Hardcore mód"
|
||||
@@ -1056,13 +1185,13 @@
|
||||
"message": "Csak Minecraft Alpha 1.0.5+-tól tudsz egyből szerverhez csatlakozni"
|
||||
},
|
||||
"instance.worlds.no_singleplayer_quick_play": {
|
||||
"message": "Használj 1.20+ verziót az azonnali egyjátékos módba lépéshez"
|
||||
"message": "Csak Minecraft 1.20+-tól tudsz egyből egyjátékos világba belépni"
|
||||
},
|
||||
"instance.worlds.play_instance": {
|
||||
"message": "Játék a profillal"
|
||||
"message": "Játékpéldány indítása"
|
||||
},
|
||||
"instance.worlds.view_instance": {
|
||||
"message": "Példány megtekintése"
|
||||
"message": "Játékpéldány megtekintése"
|
||||
},
|
||||
"instance.worlds.world_in_use": {
|
||||
"message": "A világ használatban van"
|
||||
@@ -1085,28 +1214,49 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "Bejelentkezés a Minecraftba"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "A játék elindításához és játszásához szükséged van egy olyan Microsoft-fiókra, amelyhez a Minecraft tartozik."
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "Bejelentkezés egy Microsoft-fiókba"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "Még nincs fiókod?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "Szerezd be a Minecraftot!"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "Támogatás"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "Minecraft szükséges"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "Bejelentkezés a Microsft-ba"
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "Pédány által megadva"
|
||||
"message": "A játékpéldány által van megadva"
|
||||
},
|
||||
"search.filter.locked.instance-game-version.title": {
|
||||
"message": "A játékverziót az adott példány biztosítja"
|
||||
"message": "A játékverziót az adott játékpéldány biztosítja"
|
||||
},
|
||||
"search.filter.locked.instance-loader.title": {
|
||||
"message": "A betöltőt az adott példány biztosítja"
|
||||
"message": "A betöltőt az adott játékpéldány biztosítja"
|
||||
},
|
||||
"search.filter.locked.instance.sync": {
|
||||
"message": "Profil szinkronizálása"
|
||||
"message": "Szinkronizálás a játékpéldánnyal"
|
||||
},
|
||||
"search.filter.locked.server": {
|
||||
"message": "A szerver által van megadva"
|
||||
},
|
||||
"search.filter.locked.server-environment.title": {
|
||||
"message": "Csak kliensoldali modok adhatók hozzá a szerverprofilhoz"
|
||||
"message": "Csak kliensoldali modok adhatók hozzá a szerverpéldányhoz"
|
||||
},
|
||||
"search.filter.locked.server-game-version.title": {
|
||||
"message": "A játékverzió a szerver által van megadva"
|
||||
"message": "A játékverziót az adott szerver biztosítja"
|
||||
},
|
||||
"search.filter.locked.server-loader.title": {
|
||||
"message": "A betöltő a szerver által van megadva"
|
||||
"message": "A betöltőt az adott szerver biztosítja"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,9 +263,6 @@
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Perbarui untuk memainkan"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "{name} perlu diperbarui sebelum dimainkan. Mohon perbarui ke versi terkini untuk meluncurkan permainan."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Proyek ini sudah terpasang"
|
||||
},
|
||||
|
||||
@@ -89,6 +89,9 @@
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Istanza sconosciuta"
|
||||
},
|
||||
"app.action-bar.install.updating-shared-content": {
|
||||
"message": "Aggiornando i contenuti condivisi"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "Installazioni"
|
||||
},
|
||||
@@ -105,13 +108,13 @@
|
||||
"message": "Primaria"
|
||||
},
|
||||
"app.action-bar.reload-to-update": {
|
||||
"message": "Ricarica per aggiornare"
|
||||
"message": "Riavvia"
|
||||
},
|
||||
"app.action-bar.show-more-running-instances": {
|
||||
"message": "Mostra più istanze in esecuzione"
|
||||
},
|
||||
"app.action-bar.stop-instance": {
|
||||
"message": "Ferma l'istanza"
|
||||
"message": "Arresta l'istanza"
|
||||
},
|
||||
"app.action-bar.update": {
|
||||
"message": "Aggiorna"
|
||||
@@ -125,6 +128,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Mostra i log"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "Accetta tutto"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "Le pubblicità aiutano Modrinth a crescere e a finanziare i creatori. I nostri partner potrebbero memorizzare o accedere ai cookie nell'app per personalizzare e misurarne le prestazioni."
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "Gestisci le opzioni"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "Rifiuta tutto"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "La tua privacy e come le pubblicità supportano Modrinth"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Abilita alcuni effetti come la sfocatura, ma può causare problemi di prestazioni senza accelerazione hardware."
|
||||
},
|
||||
@@ -186,7 +204,7 @@
|
||||
"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"
|
||||
"message": "Salta le conferme meno importanti"
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.description": {
|
||||
"message": "Mostra o nascondi la barra laterale."
|
||||
@@ -198,7 +216,7 @@
|
||||
"message": "Mostrerà un avviso prima di installare un file Modrinth Pack (.mrpack) non proveniente da Modrinth, a causa dei possibili rischi."
|
||||
},
|
||||
"app.appearance-settings.unknown-pack-warning.title": {
|
||||
"message": "Avvisami se installo pacchetti sconosciuti"
|
||||
"message": "Avvisami quando installo pacchetti sconosciuti"
|
||||
},
|
||||
"app.auth-servers.unreachable.body": {
|
||||
"message": "I server di autenticazione di Minecraft stanno riscontrando problemi. Controlla la tua connessione a Internet e riprova più tardi."
|
||||
@@ -231,7 +249,7 @@
|
||||
"message": "Esplora i contenuti"
|
||||
},
|
||||
"app.browse.discover-servers": {
|
||||
"message": "Esplora i server"
|
||||
"message": "Sfoglia i server"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Nascondi server già aggiunti"
|
||||
@@ -323,6 +341,36 @@
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Esecuzione dei processori del loader"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.added-label": {
|
||||
"message": "Aggiunto"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-body": {
|
||||
"message": "L'istanza locale è più avanti di quella degli utenti che hai invitato."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-header": {
|
||||
"message": "Le modifiche non sono ancora state condivise"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publish-button": {
|
||||
"message": "Invia"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publishing-button": {
|
||||
"message": "Invio..."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.removed-label": {
|
||||
"message": "Rimosso"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-admonition-header": {
|
||||
"message": "Invia aggiornamento"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-description": {
|
||||
"message": "Revisiona i contenuti modificati che verranno condivisi con l'intera istanza."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-header": {
|
||||
"message": "Revisiona modifiche"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.reviewing-button": {
|
||||
"message": "Revisione..."
|
||||
},
|
||||
"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."
|
||||
},
|
||||
@@ -359,6 +407,9 @@
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "progetto"
|
||||
},
|
||||
"app.instance.mods.locked-content": {
|
||||
"message": "I contenuti nelle istanze bloccate non possono essere modificati."
|
||||
},
|
||||
"app.instance.mods.project-was-added": {
|
||||
"message": "\"{name}\" è stato aggiunto"
|
||||
},
|
||||
@@ -371,11 +422,107 @@
|
||||
"app.instance.mods.successfully-uploaded": {
|
||||
"message": "Caricato con successo"
|
||||
},
|
||||
"app.instance.share.empty.description": {
|
||||
"message": "Invita chi vuoi a questa istanza!"
|
||||
},
|
||||
"app.instance.share.empty.heading": {
|
||||
"message": "Nessun invito inviato"
|
||||
},
|
||||
"app.instance.share.empty.invite-friends-button": {
|
||||
"message": "Invia un invito"
|
||||
},
|
||||
"app.instance.share.invite-modal.heading": {
|
||||
"message": "Condividi {name}"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-prefix": {
|
||||
"message": "Devi effettuare l'accesso come"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-suffix": {
|
||||
"message": "per accedere a questa pagina."
|
||||
},
|
||||
"app.instance.share.locked.linked-account-fallback": {
|
||||
"message": "l'account collegato"
|
||||
},
|
||||
"app.instance.share.locked.signed-out-heading": {
|
||||
"message": "Accesso non effettuato"
|
||||
},
|
||||
"app.instance.share.locked.switch-account-button": {
|
||||
"message": "Cambia account"
|
||||
},
|
||||
"app.instance.share.locked.wrong-account-heading": {
|
||||
"message": "Account sbagliato"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-access": {
|
||||
"message": "Non riceveranno più gli aggiornamenti di questa istanza condivisa"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-installed-copy": {
|
||||
"message": "La copia che hanno già nei loro dispositivi rimarrà"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-invite-again": {
|
||||
"message": "Puoi reinvitarli più tardi"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-last-user": {
|
||||
"message": "Questo è l'ultimo utente, la condivisione verrà spenta per questa istanza"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effects-label": {
|
||||
"message": "Cosa succede?"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.header": {
|
||||
"message": "Revoca accesso"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.remove-button": {
|
||||
"message": "Revoca accesso"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.user-avatar-alt": {
|
||||
"message": "Foto profilo di {username}"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.warning-body": {
|
||||
"message": "Se revochi l'accesso di {username} a questa istanza condivisa, dovrai reinvitarli prima che ricevano gli aggiornamenti."
|
||||
},
|
||||
"app.instance.share.sign-in.button": {
|
||||
"message": "Accedi"
|
||||
},
|
||||
"app.instance.share.unlink.body": {
|
||||
"message": "Devi scollegare questo pacchetto per condividere l'istanza"
|
||||
},
|
||||
"app.instance.share.unlink.header": {
|
||||
"message": "Scollega prima di condividere"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.body": {
|
||||
"message": "Questa istanza condivisa è già installata come <bold>{instanceName}</bold>. Vuoi installarne un'altra copia?"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.header": {
|
||||
"message": "Istanza condivisa già installata"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.install-anyway": {
|
||||
"message": "Installa comunque"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.instance": {
|
||||
"message": "Istanza"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.fallback-username": {
|
||||
"message": "l'account collegato"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.owner-admonition-body-v2": {
|
||||
"message": "per gestire l'istanza condivisa. Non potrai inviare gli aggiornamenti agli utenti."
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.sign-in-as-label": {
|
||||
"message": "Accedi come"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.signed-out-header": {
|
||||
"message": "Devi aver effettuato l'accesso a Modrinth"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.user-admonition-body-v2": {
|
||||
"message": "per ricevere gli aggiornamenti dell'istanza condivisa."
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.warning-header": {
|
||||
"message": "Stai usando l'account Modrinth sbagliato"
|
||||
},
|
||||
"app.instance.worlds.add-server": {
|
||||
"message": "Aggiungi server"
|
||||
},
|
||||
"app.instance.worlds.browse-servers": {
|
||||
"message": "Esplora i server"
|
||||
"message": "Sfoglia i server"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.delete-button": {
|
||||
"message": "Elimina mondo"
|
||||
@@ -384,7 +531,7 @@
|
||||
"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."
|
||||
"message": "Questo mondo verrà eliminato permanentemente dall'istanza. Questa azione non può essere annullata."
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-header": {
|
||||
"message": "Eliminare {name}"
|
||||
@@ -402,7 +549,7 @@
|
||||
"message": "Vanilla"
|
||||
},
|
||||
"app.instance.worlds.no-worlds-description": {
|
||||
"message": "Inizia esplorando o aggiungendo un server"
|
||||
"message": "Inizia sfogliando o aggiungendo un server"
|
||||
},
|
||||
"app.instance.worlds.no-worlds-heading": {
|
||||
"message": "Nessun server o mondo aggiunto"
|
||||
@@ -422,7 +569,19 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Cerca tra {count} mondi..."
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"app.modal.install-to-play.additional-context": {
|
||||
"message": "Contesto aggiuntivo"
|
||||
},
|
||||
"app.modal.install-to-play.additional-context-placeholder": {
|
||||
"message": "Se possibile, includi link e immagini pertinenti"
|
||||
},
|
||||
"app.modal.install-to-play.content-you-are-reporting": {
|
||||
"message": "L'istanza che stai segnalando"
|
||||
},
|
||||
"app.modal.install-to-play.delete-instance": {
|
||||
"message": "Elimina istanza"
|
||||
},
|
||||
"app.modal.install-to-play.external-files-dont-install": {
|
||||
"message": "Non installare"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
@@ -440,14 +599,53 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count} mod"
|
||||
},
|
||||
"app.modal.install-to-play.report-description": {
|
||||
"message": "Usa questo modulo per segnalare le istanze che violano le nostre <rules-link>Regole</rules-link> o <terms-link>Termini d'uso</terms-link>."
|
||||
},
|
||||
"app.modal.install-to-play.report-image-invalid-type": {
|
||||
"message": "Il file non è un'immagine supportata"
|
||||
},
|
||||
"app.modal.install-to-play.report-image-too-large": {
|
||||
"message": "Il file supera il limite di 1 MiB"
|
||||
},
|
||||
"app.modal.install-to-play.report-legal-claims": {
|
||||
"message": "Per DMCA o altre rivendicazioni legali, controlla la nostra <copyright-link>Politica copyright</copyright-link>."
|
||||
},
|
||||
"app.modal.install-to-play.report-reason": {
|
||||
"message": "Quale regola è violata da quest'istanza?"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.inappropriate": {
|
||||
"message": "Inappropriato"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.malicious": {
|
||||
"message": "Dannoso"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.spam": {
|
||||
"message": "Spam"
|
||||
},
|
||||
"app.modal.install-to-play.report-shared-instance-header": {
|
||||
"message": "Segnala istanza condivisa"
|
||||
},
|
||||
"app.modal.install-to-play.report-submitted": {
|
||||
"message": "Segnalazione inviata"
|
||||
},
|
||||
"app.modal.install-to-play.report-support-and-bugs": {
|
||||
"message": "Per assistenza, contatta il nostro <support-link>team di assistenza</support-link>. Per segnalare bug, apri un <github-link>Issue su GitHub</github-link>."
|
||||
},
|
||||
"app.modal.install-to-play.reviewed-files": {
|
||||
"message": "Solo i file pubblicati su Modrinth vengono esaminati, qualunque sia il loro formato (.mrpack inclusi)."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Istanza condivisa"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance-content": {
|
||||
"message": "Contenuti istanza condivisa"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance-unknown-files-description": {
|
||||
"message": "L'istanza condivisa contiene dei file che non sono su Modrinth. Consigliamo di installare file solo da fonti attendibili."
|
||||
},
|
||||
"app.modal.install-to-play.unknown-files-description": {
|
||||
"message": "Questo pacchetto contiene dei file che non sono su Modrinth. Consigliamo di installare file solo da fonti attendibili."
|
||||
"message": "Il pacchetto contiene dei file che non sono su Modrinth. Consigliamo di installare file solo da fonti attendibili."
|
||||
},
|
||||
"app.modal.install-to-play.unknown-files-warning": {
|
||||
"message": "File sconosciuti"
|
||||
@@ -464,6 +662,21 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Rimosso"
|
||||
},
|
||||
"app.modal.update-to-play.server-modpack-unknown-files-description": {
|
||||
"message": "L'aggiornamento del pacchetto contiene dei file che non sono su Modrinth. Consigliamo di installare file solo da fonti attendibili."
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-added-label": {
|
||||
"message": "Aggiunto"
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-removed-label": {
|
||||
"message": "Rimosso"
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-unknown-files-description": {
|
||||
"message": "L'aggiornamento dell'istanza condivisa contiene dei file che non sono su Modrinth. Consigliamo di installare file solo da fonti attendibili."
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Aggiornamento richiesto"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "{name} richiede degli aggiornamenti. Installa l'ultima versione per poter giocare."
|
||||
},
|
||||
@@ -480,13 +693,13 @@
|
||||
"message": "Tutte le versioni"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Scarica col browser"
|
||||
"message": "Scarica dal browser"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Installazione"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Già installate"
|
||||
"message": "Già installata"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Modalità sviluppatore attiva."
|
||||
@@ -494,6 +707,9 @@
|
||||
"app.settings.downloading": {
|
||||
"message": "Scaricando v{version}"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "Le pubblicità aiutano Modrinth a crescere e a finanziare i creatori. I nostri partner potrebbero memorizzare o accedere ai cookie nell'app per personalizzare e misurarne le prestazioni. Di seguito puoi scegliere di disdire o di gestire le opzioni."
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "Aspetto"
|
||||
},
|
||||
@@ -536,6 +752,9 @@
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "Impossibile processare il file"
|
||||
},
|
||||
"app.skins.ears-feature-notice": {
|
||||
"message": "Questa skin usa caratteristiche della mod {ears}"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "Modifica"
|
||||
},
|
||||
@@ -579,7 +798,7 @@
|
||||
"message": "Salva"
|
||||
},
|
||||
"app.skins.modal.saving-tooltip": {
|
||||
"message": "Salvando..."
|
||||
"message": "Salvataggio..."
|
||||
},
|
||||
"app.skins.modal.texture-section": {
|
||||
"message": "Aspetto"
|
||||
@@ -662,8 +881,14 @@
|
||||
"app.skins.title": {
|
||||
"message": "Seleziona una skin"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "Disattiva"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "Attiva"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Modrinth App v{version} è stata scaricata. Ricarica per aggiornare ora, o avverrà in automatico alla chiusura dell'app."
|
||||
"message": "Modrinth App v{version} è stata scaricata. Riavvia per aggiornare ora, o avverrà in automatico alla chiusura dell'app."
|
||||
},
|
||||
"app.update-popup.body.linux": {
|
||||
"message": "Modrinth App v{version} è disponibile. Usa il tuo gestore di pacchetti per aggiornare e ricevere le novità più recenti!"
|
||||
@@ -681,7 +906,7 @@
|
||||
"message": "Download completato"
|
||||
},
|
||||
"app.update-popup.reload": {
|
||||
"message": "Ricarica"
|
||||
"message": "Riavvia"
|
||||
},
|
||||
"app.update-popup.title": {
|
||||
"message": "Aggiornamento disponibile"
|
||||
@@ -710,6 +935,39 @@
|
||||
"app.world.world-item.players-online": {
|
||||
"message": "{count} online"
|
||||
},
|
||||
"content.shared-instance.change-version-body": {
|
||||
"message": "Modificare la versione cambia solo la copia locale. Gli aggiornamenti condivisi futuri potrebbero rimodificarla."
|
||||
},
|
||||
"content.shared-instance.delete-bulk-body": {
|
||||
"message": "Alcuni progetti selezionati fanno parte dell'istanza condivisa. Eliminarli cambia solo la copia locale, e gli aggiornamenti condivisi futuri potrebbero ripristinarli."
|
||||
},
|
||||
"content.shared-instance.delete-button": {
|
||||
"message": "Elimina comunque"
|
||||
},
|
||||
"content.shared-instance.delete-many-button": {
|
||||
"message": "Elimina {count, number} progetti comunque"
|
||||
},
|
||||
"content.shared-instance.delete-single-body": {
|
||||
"message": "Eliminarlo cambia solo la copia locale. Gli aggiornamenti condivisi futuri potrebbero ripristinarlo."
|
||||
},
|
||||
"content.shared-instance.disable-bulk-body": {
|
||||
"message": "Alcuni progetti selezionati fanno parte dell'istanza condivisa. Disabilitarli cambia solo la copia locale, e gli aggiornamenti condivisi futuri potrebbero riabilitarli."
|
||||
},
|
||||
"content.shared-instance.disable-button": {
|
||||
"message": "Disabilita comunque"
|
||||
},
|
||||
"content.shared-instance.disable-many-button": {
|
||||
"message": "Disabilita {count, number} progetti comunque"
|
||||
},
|
||||
"content.shared-instance.disable-single-body": {
|
||||
"message": "Disabilitarlo cambia solo la copia locale. Gli aggiornamenti condivisi futuri potrebbero riabilitarlo."
|
||||
},
|
||||
"content.shared-instance.unlink-body": {
|
||||
"message": "Scollegarlo cambia solo la copia locale. Gli aggiornamenti condivisi futuri potrebbero ricollegarlo."
|
||||
},
|
||||
"content.shared-instance.warning-header": {
|
||||
"message": "Questo fa parte dell'istanza condivisa"
|
||||
},
|
||||
"friends.action.add-friend": {
|
||||
"message": "Stringi un'amicizia"
|
||||
},
|
||||
@@ -726,10 +984,10 @@
|
||||
"message": "Potrebbe essere diverso dal nome utente di Minecraft!"
|
||||
},
|
||||
"friends.add-friend.username.placeholder": {
|
||||
"message": "Inserisci il nome utente Modrinth..."
|
||||
"message": "Nome utente di Modrinth..."
|
||||
},
|
||||
"friends.add-friend.username.title": {
|
||||
"message": "Con quale utente Modrinth vuoi stringere l'amicizia?"
|
||||
"message": "Con quale utente di Modrinth vuoi stringere amicizia?"
|
||||
},
|
||||
"friends.add-friends-to-share": {
|
||||
"message": "<link>Stringi un''amicizia</link> per sapere a cosa stanno giocando!"
|
||||
@@ -773,6 +1031,75 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Accedi a un account Modrinth</link> per stringere amicizie e sapere a cosa stanno giocando!"
|
||||
},
|
||||
"installation-settings.shared-instance.linked-title": {
|
||||
"message": "Istanza condivisa collegata"
|
||||
},
|
||||
"installation-settings.shared-instance.title": {
|
||||
"message": "Rimuovi l'istanza dai server"
|
||||
},
|
||||
"installation-settings.shared-instance.unlink-button": {
|
||||
"message": "Scollega l'istanza condivisa"
|
||||
},
|
||||
"installation-settings.shared-instance.unlink-description": {
|
||||
"message": "Sconnetti l'istanza locale dai prossimi aggiornamenti condivisi."
|
||||
},
|
||||
"installation-settings.shared-instance.unlinking-button": {
|
||||
"message": "Scollegamento..."
|
||||
},
|
||||
"installation-settings.shared-instance.unpublish-button": {
|
||||
"message": "Rimuovi l'istanza condivisa dai server"
|
||||
},
|
||||
"installation-settings.shared-instance.unpublish-description": {
|
||||
"message": "Rimuovi l'istanza condivisa da Modrinth e non inviare più aggiornamenti a chi la usa. L'istanza locale non sarà toccata."
|
||||
},
|
||||
"installation-settings.shared-instance.unpublishing-button": {
|
||||
"message": "Rimozione..."
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.admonition-body": {
|
||||
"message": "Ciò influirà solo sull'istanza locale. I contenuti installati rimarranno sul dispositivo e l'istanza condivisa e gli utenti che la usano non verranno toccati."
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.admonition-header": {
|
||||
"message": "Scollegare l'istanza condivisa"
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.header": {
|
||||
"message": "Scollega l'istanza condivisa"
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.admonition-body": {
|
||||
"message": "Ciò eliminerà l'istanza condivisa dai server di Modrinth. Gli utenti che la usavano non riceveranno più aggiornamenti, ma l'istanza locale e i contenuti rimarranno su questo dispositivo."
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.admonition-header": {
|
||||
"message": "Rimuovere l'istanza condivisa dai server"
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.header": {
|
||||
"message": "Rimuovi l'istanza condivisa dai server"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "Crea collegamento"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "Esporta pacchetto"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "Avvia istanza"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "Altre azioni"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "Apri cartella"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "Ripara"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "Impostazioni istanza"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "Avvio..."
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "Arresto..."
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "Aggiungi e avvia"
|
||||
},
|
||||
@@ -815,6 +1142,15 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "Salva come..."
|
||||
},
|
||||
"instance.locked.delete-button": {
|
||||
"message": "Elimina istanza"
|
||||
},
|
||||
"instance.locked.play-tooltip": {
|
||||
"message": "Questa istanza è stata bloccata"
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "Mai avviata"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "Indirizzo"
|
||||
},
|
||||
@@ -840,7 +1176,7 @@
|
||||
"message": "Elimina permanentemente un'istanza dal tuo dispositivo, compresi i tuoi mondi, file di configurazione e tutto il contenuto installato. Fai attenzione: eliminata un'istanza non c'è modo di recuperarla."
|
||||
},
|
||||
"instance.settings.tabs.general.deleting.button": {
|
||||
"message": "Eliminando..."
|
||||
"message": "Eliminazione..."
|
||||
},
|
||||
"instance.settings.tabs.general.duplicate-button": {
|
||||
"message": "Duplica"
|
||||
@@ -861,7 +1197,7 @@
|
||||
"message": "Rimuovi icona"
|
||||
},
|
||||
"instance.settings.tabs.general.edit-icon.replace": {
|
||||
"message": "Cambia icona"
|
||||
"message": "Sfoglia"
|
||||
},
|
||||
"instance.settings.tabs.general.edit-icon.select": {
|
||||
"message": "Scegli un'icona"
|
||||
@@ -950,6 +1286,9 @@
|
||||
"instance.settings.tabs.installation.loader-version": {
|
||||
"message": "Versione di {loader}"
|
||||
},
|
||||
"instance.settings.tabs.installation.locked": {
|
||||
"message": "Le impostazioni non sono disponibili mentre l'istanza è bloccata."
|
||||
},
|
||||
"instance.settings.tabs.java": {
|
||||
"message": "Java e memoria"
|
||||
},
|
||||
@@ -989,6 +1328,9 @@
|
||||
"instance.settings.tabs.java.java-path-placeholder": {
|
||||
"message": "/percorso/di/java"
|
||||
},
|
||||
"instance.settings.tabs.sharing": {
|
||||
"message": "Condivisione"
|
||||
},
|
||||
"instance.settings.tabs.window": {
|
||||
"message": "Finestra"
|
||||
},
|
||||
@@ -1019,6 +1361,57 @@
|
||||
"instance.settings.tabs.window.width.enter": {
|
||||
"message": "Inserisci larghezza..."
|
||||
},
|
||||
"instance.shared-instance.error.title": {
|
||||
"message": "Qualcosa è andato storto"
|
||||
},
|
||||
"instance.shared-instance.owner-tooltip": {
|
||||
"message": "I contenuti dell'istanza stanno venendo condivisi agli utenti."
|
||||
},
|
||||
"instance.shared-instance.publish-review.added-label": {
|
||||
"message": "Aggiunto"
|
||||
},
|
||||
"instance.shared-instance.publish-review.admonition-header": {
|
||||
"message": "Invia l'aggiornamento ai giocatori"
|
||||
},
|
||||
"instance.shared-instance.publish-review.config-title-v2": {
|
||||
"message": "Seleziona i file di configurazione"
|
||||
},
|
||||
"instance.shared-instance.publish-review.description": {
|
||||
"message": "Revisiona i contenuti modificati e scegli i file di configurazione da includere nell'aggiornamento."
|
||||
},
|
||||
"instance.shared-instance.publish-review.header": {
|
||||
"message": "Revisiona modifiche"
|
||||
},
|
||||
"instance.shared-instance.publish-review.publish-button": {
|
||||
"message": "Invia"
|
||||
},
|
||||
"instance.shared-instance.publish-review.removed-label": {
|
||||
"message": "Rimosso"
|
||||
},
|
||||
"instance.shared-instance.tooltip": {
|
||||
"message": "I contenuti dell'istanza stanno venendo gestiti da qualcun altro."
|
||||
},
|
||||
"instance.shared-instance.unavailable.access-revoked-text": {
|
||||
"message": "L'accesso all'istanza condivisa è stato revocato. È ancora disponibile localmente, ma non è più collegata e non riceverà aggiornamenti."
|
||||
},
|
||||
"instance.shared-instance.unavailable.deleted-text": {
|
||||
"message": "L'istanza primaria è stata eliminata. È ancora disponibile localmente, ma non è più collegata e non riceverà aggiornamenti."
|
||||
},
|
||||
"instance.shared-instance.unavailable.locked-text": {
|
||||
"message": "L'istanza condivisa è stata bloccata dal team di moderazione dei contenuti. Non riceverà più aggiornamenti dall'istanza primara e non potrà essere avviata."
|
||||
},
|
||||
"instance.shared-instance.unavailable.locked-title": {
|
||||
"message": "Istanza bloccata"
|
||||
},
|
||||
"instance.shared-instance.unavailable.manager-fallback": {
|
||||
"message": "il gestore dell'istanza"
|
||||
},
|
||||
"instance.shared-instance.unavailable.text": {
|
||||
"message": "L'istanza locale è ancora disponibile, ma non è più collegata e non riceverà aggiornamenti."
|
||||
},
|
||||
"instance.shared-instance.unavailable.title": {
|
||||
"message": "Istanza condivisa non più disponibile"
|
||||
},
|
||||
"instance.worlds.a_minecraft_server": {
|
||||
"message": "Un server Minecraft"
|
||||
},
|
||||
@@ -1082,6 +1475,63 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "Accedi a Minecraft"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "Devi disporre di una copia di Minecraft da un account Microsoft prima di poter giocare."
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "Accedi a un account Microsoft"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "Non hai un account?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "Ottieni Minecraft"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "Assistenza"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "Minecraft richiesto"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "Accedi a Microsoft"
|
||||
},
|
||||
"modal.modrinth-account-required.browser-description": {
|
||||
"message": "Si è aperta una nuova scheda per effettuare l'accesso. Poi torna all'app."
|
||||
},
|
||||
"modal.modrinth-account-required.cancel-button": {
|
||||
"message": "Annulla"
|
||||
},
|
||||
"modal.modrinth-account-required.continue-in-browser-heading": {
|
||||
"message": "Continua nel browser"
|
||||
},
|
||||
"modal.modrinth-account-required.create-account-button": {
|
||||
"message": "Crea un account"
|
||||
},
|
||||
"modal.modrinth-account-required.description": {
|
||||
"message": "Devi aver effettuato l'accesso a Modrinth per usare questa funzione."
|
||||
},
|
||||
"modal.modrinth-account-required.header": {
|
||||
"message": "Account richiesto"
|
||||
},
|
||||
"modal.modrinth-account-required.open-browser-again-button": {
|
||||
"message": "Apri di nuovo il browser"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-button": {
|
||||
"message": "Accedi a Modrinth"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-heading": {
|
||||
"message": "Accedi a un account Modrinth"
|
||||
},
|
||||
"modal.modrinth-account-required.signing-in-header": {
|
||||
"message": "Accesso"
|
||||
},
|
||||
"modal.modrinth-account-required.support-prompt": {
|
||||
"message": "Hai problemi ad accedere? Scrivi al <support>supporto</support>"
|
||||
},
|
||||
"modal.modrinth-account-required.waiting-for-browser": {
|
||||
"message": "Aspettando la conferma del browser..."
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "Determinato dall'istanza"
|
||||
},
|
||||
|
||||
@@ -50,6 +50,42 @@
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "ダウンロードを完了することができませんでした"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "インスタンスが見つかりませんでした"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "ファイルパスが無効です"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "Modパックのデータが無効です"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "Modパックのファイルのメタデータに不正な部分があります"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "Javaのセットアップに失敗しました"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "ローダーのセットアップに失敗しました"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "ローカルデータを更新できませんでした"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "マインクラフトのセットアップに失敗しました"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "Modrinthに接続できませんでした"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "書き込み権限がありません"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "パックをダウンロードできませんでした"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "問題が発生しました"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "不明なインスタンス"
|
||||
},
|
||||
@@ -68,6 +104,9 @@
|
||||
"app.action-bar.primary-instance": {
|
||||
"message": "デフォルトのインスタンス"
|
||||
},
|
||||
"app.action-bar.reload-to-update": {
|
||||
"message": "再読み込みしてアップデート"
|
||||
},
|
||||
"app.action-bar.show-more-running-instances": {
|
||||
"message": "実行中のインスタンスをさらに表示"
|
||||
},
|
||||
@@ -86,6 +125,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "ログを表示"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "すべて受け入れる"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "Modrinthは広告収益によって運営され、クリエイターへの報酬も広告収益から支払われています。当社のパートナーは、広告のパーソナライズや効果測定のために、アプリ内でCookieを保存・利用する場合があります。"
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "設定の管理"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "すべて拒否する"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "プライバシーと広告がModrinthを支える仕組み"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "ぼかし効果などの高度なレンダリングを有効にします。グラフィックアクセラレーションが使用できない場合は、パフォーマンスが低下する可能性があります。"
|
||||
},
|
||||
@@ -99,7 +153,7 @@
|
||||
"message": "テーマ"
|
||||
},
|
||||
"app.appearance-settings.default-landing-page.description": {
|
||||
"message": "ランチャー起動時に表示するページを変更します"
|
||||
"message": "ランチャー起動時に表示するページを変更します。"
|
||||
},
|
||||
"app.appearance-settings.default-landing-page.home": {
|
||||
"message": "ホーム"
|
||||
@@ -129,7 +183,7 @@
|
||||
"message": "ランチャーを最小化"
|
||||
},
|
||||
"app.appearance-settings.native-decorations.description": {
|
||||
"message": "OSデフォルトのウィンドウUIを使用します。(アプリの再起動が必要です)"
|
||||
"message": "OsのウィンドウUIを使用します(アプリの再起動が必要です)。"
|
||||
},
|
||||
"app.appearance-settings.native-decorations.title": {
|
||||
"message": "OSのウィンドウUIを使用"
|
||||
@@ -167,6 +221,12 @@
|
||||
"app.auth-servers.unreachable.header": {
|
||||
"message": "認証サーバーにアクセスできません"
|
||||
},
|
||||
"app.browse.add-servers-to-instance": {
|
||||
"message": "インスタンスにサーバーを追加中"
|
||||
},
|
||||
"app.browse.add-to-an-instance": {
|
||||
"message": "インスタンスに追加"
|
||||
},
|
||||
"app.browse.add-to-instance": {
|
||||
"message": "インスタンスに追加"
|
||||
},
|
||||
@@ -194,9 +254,15 @@
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modパック"
|
||||
},
|
||||
"app.browse.server-instance-content-warning": {
|
||||
"message": "コンテンツを追加すると、サーバーに参加する際に互換性が失われる可能性があります。また、追加されたコンテンツはインスタンスのコンテンツをアップデートした際に失われます。"
|
||||
},
|
||||
"app.browse.server.installing": {
|
||||
"message": "インストール中"
|
||||
},
|
||||
"app.content-install.no-compatible-versions": {
|
||||
"message": "{compatibilityLabel} に一致する利用可能なバージョンがありません。このままインストールしますか?依存関係は自動的にインストールされません。"
|
||||
},
|
||||
"app.export-modal.description-placeholder": {
|
||||
"message": "Modパックの説明を入力…"
|
||||
},
|
||||
@@ -206,6 +272,9 @@
|
||||
"app.export-modal.header": {
|
||||
"message": "Modパックを書き出す"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Modパック名"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Modパック名"
|
||||
},
|
||||
@@ -215,9 +284,60 @@
|
||||
"app.export-modal.version-number-placeholder": {
|
||||
"message": "1.0.0"
|
||||
},
|
||||
"app.install.phase.downloading_content": {
|
||||
"message": "コンテンツをダウンロード中"
|
||||
},
|
||||
"app.install.phase.downloading_minecraft": {
|
||||
"message": "マインクラフトをダウンロード中"
|
||||
},
|
||||
"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": "マインクラフトを解析中"
|
||||
},
|
||||
"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": "インスタンス内のすべてのデータは、ワールド、設定、インストール済みのコンテンツを含め、完全に削除されます。"
|
||||
},
|
||||
@@ -231,7 +351,7 @@
|
||||
"message": "インスタンスを削除"
|
||||
},
|
||||
"app.instance.modpack-already-installed.body": {
|
||||
"message": "このModpackは既に <bold>{instanceName}</bold> インスタンスにインストール済みです。本当に複製しますか?"
|
||||
"message": "このModパックは既に <bold>{instanceName}</bold> インスタンスにインストール済みです。本当に複製しますか?"
|
||||
},
|
||||
"app.instance.modpack-already-installed.create": {
|
||||
"message": "新規作成"
|
||||
@@ -242,6 +362,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": "プロジェクト"
|
||||
},
|
||||
@@ -266,6 +395,15 @@
|
||||
"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} を削除します"
|
||||
},
|
||||
@@ -287,39 +425,90 @@
|
||||
"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} 個のワールドを検索…"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "インストールしてプレイ"
|
||||
},
|
||||
"app.modal.install-to-play.install-anyway": {
|
||||
"message": "このままインストール"
|
||||
},
|
||||
"app.modal.install-to-play.install-button": {
|
||||
"message": "インストール"
|
||||
},
|
||||
"app.modal.install-to-play.invite-warning": {
|
||||
"message": "この招待は他のModrinthユーザーによって作成されたものであり、Modrinth公式のものではありません。信頼できる人からの招待のみ承諾してください。"
|
||||
},
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, other {#個のMod}}"
|
||||
},
|
||||
"app.modal.install-to-play.reviewed-files": {
|
||||
"message": "ファイル形式(.mrpackを含む)に関わらず、Modrinthに公開されているファイルのみが審査の対象となります。"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "共有インスタンス"
|
||||
},
|
||||
"app.modal.install-to-play.unknown-files-description": {
|
||||
"message": "このサーバーModパックには、Modrinthに公開されていないファイルが含まれています。信頼できるソースからのファイルのみをインストールすることを強く推奨します。"
|
||||
},
|
||||
"app.modal.install-to-play.unknown-files-warning": {
|
||||
"message": "不明なファイルの警告"
|
||||
},
|
||||
"app.modal.install-to-play.unrecognized-files": {
|
||||
"message": "認識されないファイル"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "コンテンツを見る"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "更新してプレイ"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "{name}をプレイするには更新が必要です。ゲームを起動するには最新版に更新してください。"
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "削除されました"
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "このプロジェクトは既にインストールされています"
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "バージョンを切り替える"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "ディスカバーに戻る"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "すべてのバージョン"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "ブラウザでダウンロード"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "インストール中"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "既にインストールされています"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "開発者モードがオンになっています。"
|
||||
},
|
||||
"app.settings.downloading": {
|
||||
"message": "v{version}をダウンロード中"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "Modrinthは広告収益によって運営され、クリエイターへの報酬も広告収益から支払われています。当社のパートナーは、広告のパーソナライズや効果測定のために、アプリ内でCookieを保存・利用する場合があります。この機能は下のボタンから個別に拒否や許可または変更することができます。"
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "表示設定"
|
||||
},
|
||||
@@ -338,6 +527,45 @@
|
||||
"app.settings.tabs.resource-management": {
|
||||
"message": "リソース管理"
|
||||
},
|
||||
"app.skins.add-button": {
|
||||
"message": "スキンを追加"
|
||||
},
|
||||
"app.skins.add-button.drag-and-drop": {
|
||||
"message": "ドラッグ&ドロップ"
|
||||
},
|
||||
"app.skins.apply-button": {
|
||||
"message": "適用"
|
||||
},
|
||||
"app.skins.delete-button": {
|
||||
"message": "スキンを削除"
|
||||
},
|
||||
"app.skins.delete-modal.description": {
|
||||
"message": "選択したスキンは永久に削除されます。この操作は取り消せません。"
|
||||
},
|
||||
"app.skins.delete-modal.title": {
|
||||
"message": "本当にこのスキンを削除しますか?"
|
||||
},
|
||||
"app.skins.dropped-file-error.text": {
|
||||
"message": "ドロップされたファイルの読み込みに失敗しました。"
|
||||
},
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "ファイルの処理中にエラーが発生しました"
|
||||
},
|
||||
"app.skins.ears-feature-notice": {
|
||||
"message": "このスキンに{ears} modの機能を使用する"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "スキンを編集"
|
||||
},
|
||||
"app.skins.modal.add-skin-button": {
|
||||
"message": "スキンを追加"
|
||||
},
|
||||
"app.skins.modal.add-title": {
|
||||
"message": "スキンを追加中"
|
||||
},
|
||||
"app.skins.modal.arm-style-section": {
|
||||
"message": "腕のスタイル"
|
||||
},
|
||||
"app.skins.modal.arm-style-slim": {
|
||||
"message": "スリム"
|
||||
},
|
||||
@@ -350,6 +578,12 @@
|
||||
"app.skins.modal.cape-section": {
|
||||
"message": "マント"
|
||||
},
|
||||
"app.skins.modal.edit-title": {
|
||||
"message": "スキンを編集中"
|
||||
},
|
||||
"app.skins.modal.make-edit-first-tooltip": {
|
||||
"message": "まずスキンを編集してください!"
|
||||
},
|
||||
"app.skins.modal.no-cape-tooltip": {
|
||||
"message": "マントなし"
|
||||
},
|
||||
@@ -368,15 +602,39 @@
|
||||
"app.skins.modal.texture-section": {
|
||||
"message": "テクスチャ"
|
||||
},
|
||||
"app.skins.modal.upload-skin-first-tooltip": {
|
||||
"message": "まずスキンをアップロードしてください!"
|
||||
},
|
||||
"app.skins.preview.edit-button": {
|
||||
"message": "編集"
|
||||
},
|
||||
"app.skins.previewing-badge": {
|
||||
"message": "プレビュー中"
|
||||
},
|
||||
"app.skins.rate-limit.text": {
|
||||
"message": "スキンの変更頻度が高すぎます。Mojangのサーバーが一時的にリクエストをブロックしました。しばらく待ってからもう一度お試しください。"
|
||||
},
|
||||
"app.skins.rate-limit.title": {
|
||||
"message": "落ち着いてください!"
|
||||
},
|
||||
"app.skins.reorder-error.text": {
|
||||
"message": "スキンの順序を保存できませんでした。"
|
||||
},
|
||||
"app.skins.reorder-error.title": {
|
||||
"message": "スキンの並び替えに失敗しました"
|
||||
},
|
||||
"app.skins.section.builders-and-biomes": {
|
||||
"message": "ビルダーズ&バイオーム"
|
||||
},
|
||||
"app.skins.section.chaos-cubed": {
|
||||
"message": "Chaos Cubed"
|
||||
},
|
||||
"app.skins.section.chase-the-skies": {
|
||||
"message": "チェイス・ザ・スカイ"
|
||||
},
|
||||
"app.skins.section.default-skins": {
|
||||
"message": "デフォルトのスキンたち"
|
||||
},
|
||||
"app.skins.section.minecon-earth-2017": {
|
||||
"message": "MINECON Earth 2017"
|
||||
},
|
||||
@@ -386,6 +644,9 @@
|
||||
"app.skins.section.modrinth-pride": {
|
||||
"message": "Modrinth プライド"
|
||||
},
|
||||
"app.skins.section.modrinth-pride.tooltip": {
|
||||
"message": "これらのスキンは、プライド月間中にModrinthのプライド募金活動に寄付したことで獲得したものです。"
|
||||
},
|
||||
"app.skins.section.mounts-of-mayhem": {
|
||||
"message": "マウント・オブ・メイヘム"
|
||||
},
|
||||
@@ -404,9 +665,27 @@
|
||||
"app.skins.section.tiny-takeover": {
|
||||
"message": "タイニー・テイクオーバー"
|
||||
},
|
||||
"app.skins.sign-in.button": {
|
||||
"message": "サイン審"
|
||||
},
|
||||
"app.skins.sign-in.description": {
|
||||
"message": "Modrinthアプリのスキン管理機能を使用するには、マインクラフトアカウントにサインインしてください。"
|
||||
},
|
||||
"app.skins.sign-in.rinthbot-alt": {
|
||||
"message": "ワクワクしている Modrinth ボット"
|
||||
},
|
||||
"app.skins.sign-in.title": {
|
||||
"message": "サインインしてください"
|
||||
},
|
||||
"app.skins.title": {
|
||||
"message": "スキンセレクター"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "オフに切り替え"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "オンに切り替え"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Modrinth App v{version} のダウンロードが完了しました。今すぐ更新するには再読み込みするか、Modrinth Appを閉じる際に自動更新されます。"
|
||||
},
|
||||
@@ -425,6 +704,9 @@
|
||||
"app.update-popup.download-complete": {
|
||||
"message": "ダウンロード完了"
|
||||
},
|
||||
"app.update-popup.reload": {
|
||||
"message": "再度読み込みして更新"
|
||||
},
|
||||
"app.update-popup.title": {
|
||||
"message": "アップデートが利用可能です"
|
||||
},
|
||||
@@ -515,6 +797,33 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Modrinthアカウントにサインイン</link>して友達を追加し、彼らがプレイしているゲームをチェックしよう!"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "ショートカット作成"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "Modパックとしてエクスポート"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "インスタンスを起動"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "その他"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "フォルダーを開く"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "修復"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "インスタンスの設定"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "起動中…"
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "停止中…"
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "追加してプレイ"
|
||||
},
|
||||
@@ -557,6 +866,9 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "名前をつけて保存…"
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "未プレイ"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "アドレス"
|
||||
},
|
||||
@@ -623,12 +935,30 @@
|
||||
"instance.settings.tabs.general.name": {
|
||||
"message": "名前"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel": {
|
||||
"message": "アップデートチャンネル"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.alpha": {
|
||||
"message": "アルファ"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.alpha.description": {
|
||||
"message": "リリース、ベータ、およびアルファバージョンが利用可能なアップデートとして表示されます。"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.beta": {
|
||||
"message": "ベータ"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.beta.description": {
|
||||
"message": "リリースおよびベータバージョンが利用可能なアップデートとして表示されます。"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.release": {
|
||||
"message": "リリース"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.release.description": {
|
||||
"message": "リリースバージョンのみが利用可能なアップデートとして表示されます。"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.select": {
|
||||
"message": "アップデートチャンネルを選択"
|
||||
},
|
||||
"instance.settings.tabs.hooks": {
|
||||
"message": "起動フック"
|
||||
},
|
||||
@@ -677,6 +1007,24 @@
|
||||
"instance.settings.tabs.java": {
|
||||
"message": "Javaとメモリ"
|
||||
},
|
||||
"instance.settings.tabs.java.custom-environment-variables": {
|
||||
"message": "カスタム環境変数"
|
||||
},
|
||||
"instance.settings.tabs.java.custom-java-arguments": {
|
||||
"message": "カスタムJava引数"
|
||||
},
|
||||
"instance.settings.tabs.java.custom-java-installation": {
|
||||
"message": "カスタムJavaインストール"
|
||||
},
|
||||
"instance.settings.tabs.java.custom-memory-allocation": {
|
||||
"message": "カスタムメモリ割り当て"
|
||||
},
|
||||
"instance.settings.tabs.java.enter-environment-variables": {
|
||||
"message": "環境変数を入力…"
|
||||
},
|
||||
"instance.settings.tabs.java.enter-java-arguments": {
|
||||
"message": "Java引数を入力…"
|
||||
},
|
||||
"instance.settings.tabs.java.environment-variables": {
|
||||
"message": "環境変数"
|
||||
},
|
||||
@@ -734,6 +1082,9 @@
|
||||
"instance.worlds.copy_address": {
|
||||
"message": "アドレスをコピー"
|
||||
},
|
||||
"instance.worlds.create_shortcut": {
|
||||
"message": "ショートカット作成"
|
||||
},
|
||||
"instance.worlds.dont_show_on_home": {
|
||||
"message": "ホームに表示しない"
|
||||
},
|
||||
@@ -785,6 +1136,27 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "Minecraftにサインイン"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "Minecraft を起動してプレイするには、Minecraft を所有している Microsoft アカウントが必要です。"
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "Microsoft アカウントにサインインしてください"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "まだアカウントを持っていませんか?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "Minecraft を入手する"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "サポートを受ける"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "Minecraft が必要です"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "Microsoft にサインイン"
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "インスタンスによる条件"
|
||||
},
|
||||
|
||||
@@ -125,6 +125,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "로그 보기"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "모두 수락"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "광고는 Modrinth가 운영될 수 있도록 하며, 크리에이터에게 지급되는 보상을 지원합니다. 우리의 파트너는 앱에서 광고를 개인화하고 성과를 측정하기 위해 쿠키를 저장하거나 접근할 수 있습니다."
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "환경 설정 관리"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "모두 거절"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "개인정보와 광고가 Modrinth를 지원하는 방식"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "블러 효과와 같은 고급 렌더링 기능을 활성화합니다. 하드웨어 가속 없이는 성능 저하가 발생할 수 있습니다."
|
||||
},
|
||||
@@ -425,9 +440,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "{count}개의 세계 검색..."
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"message": "설치하지 않음"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "설치하고 플레이"
|
||||
},
|
||||
@@ -467,9 +479,6 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "제거됨"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "{name}을(를) 플레이하려면 업데이트가 필요합니다. 게임을 실행하려면 최신 버전으로 업데이트해 주세요."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "이미 설치되어 있음"
|
||||
},
|
||||
@@ -479,12 +488,27 @@
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "탐색으로 돌아가기"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "모든 버전"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "브라우저에서 다운로드"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "설치 중"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "이미 설치됨"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "개발자 모드가 활성화되었습니다."
|
||||
},
|
||||
"app.settings.downloading": {
|
||||
"message": "v{version} 다운로드 중"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "광고는 Modrinth가 운영될 수 있도록 하며, 크리에이터에게 지급되는 보상을 지원합니다. 우리의 파트너는 앱에서 광고를 개인화하고 성과를 측정하기 위해 쿠키를 저장하거나 접근할 수 있습니다. 아래에서 거부하거나 환경 설정을 관리할 수 있습니다."
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "모양"
|
||||
},
|
||||
@@ -527,6 +551,9 @@
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "파일 처리 중 오류가 발생했습니다."
|
||||
},
|
||||
"app.skins.ears-feature-notice": {
|
||||
"message": "이 스킨은 {ears} 모드의 기능을 사용합니다"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "스킨 편집"
|
||||
},
|
||||
@@ -653,6 +680,12 @@
|
||||
"app.skins.title": {
|
||||
"message": "스킨 선택"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "끄기"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "켜기"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Modrinth App v{version} 다운로드가 완료되었습니다. 새로고침하거나 Modrinth App을 종료하면 자동으로 업데이트됩니다."
|
||||
},
|
||||
@@ -764,6 +797,33 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Modrinth 계정으로 로그인</link>하여 친구를 추가하고 무엇을 플레이 중인지 확인하세요!"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "바로가기 만들기"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "모드팩 내보내기"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "인스턴스 실행"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "더보기"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "폴더 열기"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "복구하기"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "인스턴스 설정"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "시작중..."
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "정지중..."
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "추가 후 플레이"
|
||||
},
|
||||
@@ -806,6 +866,9 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "다른 이름으로 저장..."
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "아직 플레이 하지 않음"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "주소"
|
||||
},
|
||||
@@ -1073,6 +1136,27 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "마인크래프트 계정으로 로그인"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "게임을 실행하고 플레이하려면 마인크래프트를 보유한 Microsoft 계정이 필요합니다."
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "Microsoft 계정 로그인"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "계정이 없으신가요?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "마인크래프트 얻기"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "지원 받기"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "마인크래프트 필요"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "Microsoft 계정 로그인"
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "인스턴스에서 관리"
|
||||
},
|
||||
|
||||
@@ -278,9 +278,6 @@
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Kemas kini untuk mainkan"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Kemas kini diperlukan untuk memainkan {name}. Sila kemas kini kepada versi terkini untuk melancarkan permainan."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Projek ini sudah dipasang"
|
||||
},
|
||||
|
||||
@@ -125,6 +125,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Bekijk logs"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "Alles accepteren"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "Advertenties maken Modrinth mogelijk en financieren de uitbetalingen aan makers. Onze partners kunnen cookies in de app opslaan of gebruiken om advertenties te personaliseren en de prestaties te meten."
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "Voorkeuren beheren"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "Alles afwijzen"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "Je privacy en hoe advertenties Modrinth ondersteunen"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Activeert geavanceerde weergaves zoals blur effecten die mogelijke prestatieproblemen opleveren zonder hardware-versnelde weergeving."
|
||||
},
|
||||
@@ -425,9 +440,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Zoek werelden"
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"message": "Niet installeren"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Installeer om te spelen"
|
||||
},
|
||||
@@ -467,9 +479,6 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Verwijderde"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Een update is vereist om {name} te spelen. Update naar de laatste versie om het spel te starten."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Dit project is al geïnstalleerd"
|
||||
},
|
||||
@@ -479,12 +488,27 @@
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Terug naar Ontdekken"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Alle versies"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Downloaden in de browser"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Wordt geïnstalleerd"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Al geïnstalleerd"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Ontwikkelaarsmodus ingeschakeld."
|
||||
},
|
||||
"app.settings.downloading": {
|
||||
"message": "v{version} wordt gedownload"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "Advertenties maken Modrinth mogelijk en financieren de uitbetalingen aan makers. Onze partners kunnen cookies in de app opslaan of gebruiken om advertenties te personaliseren en de prestaties te meten. Je kunt je hieronder afmelden of je voorkeuren beheren."
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "Uiterlijk"
|
||||
},
|
||||
@@ -527,6 +551,9 @@
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "Fout bij het verwerken van het bestand"
|
||||
},
|
||||
"app.skins.ears-feature-notice": {
|
||||
"message": "Deze skin maakt gebruik van functies uit de {ears} mod"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "Skin aanpassen"
|
||||
},
|
||||
@@ -653,11 +680,17 @@
|
||||
"app.skins.title": {
|
||||
"message": "Skinkiezer"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "Uitschakelen"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "Inschakelen"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Modrinth App v{version} is klaar met downloaden. Herlaad om nu te updaten, of automatisch wanneer je de Modrinth App afsluit."
|
||||
},
|
||||
"app.update-popup.body.linux": {
|
||||
"message": "Modrinth App v{version} is beschikbaar. Gebruik je pakketbeheerder om te updaten voor de laatste functies en oplossingen!"
|
||||
"message": "De Modrinth-app v{version} is beschikbaar. Gebruik je pakketbeheerder om bij te werken en zo de nieuwste functies en verbeteringen te krijgen!"
|
||||
},
|
||||
"app.update-popup.body.metered": {
|
||||
"message": "Modrinth App v{version} is nu beschikbaar! Omdat je nu op een netwerk met datalimiet zit, is de download niet automatisch gestart."
|
||||
@@ -764,6 +797,33 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Log in op een Modrinth account</link> om vrienden toe te voegen en zien wat zij spelen!"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "Snelkoppeling maken"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "Modpack exporteren"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "Instantie starten"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "Meer acties"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "Map openen"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "Herstellen"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "Instellingen voor instantie"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "Aan het opstarten..."
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "Aan het stoppen..."
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "Toevoegen en spelen"
|
||||
},
|
||||
@@ -806,6 +866,9 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "Opslaan als..."
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "Nog nooit gespeeld"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "Adres"
|
||||
},
|
||||
@@ -1073,6 +1136,27 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "Log in bij Minecraft"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "Je hebt een Microsoft-account nodig waarop Minecraft is geregistreerd voordat je het spel kunt starten en spelen."
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "Meld je aan bij een Microsoft-account"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "Heb je nog geen account?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "Minecraft kopen"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "Hulp krijgen"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "Minecraft vereist"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "Aanmelden bij Microsoft"
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "Aangeboden door de instantie"
|
||||
},
|
||||
|
||||
@@ -230,9 +230,6 @@
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Oppdater for å spille"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Ei oppdatering er påkrevd for å spille {name}. Vær så snill å oppdater til den siste versjonen av spillet for å spille det."
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Utviklermodus aktivert."
|
||||
},
|
||||
|
||||
@@ -89,6 +89,9 @@
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Nieznana instancja"
|
||||
},
|
||||
"app.action-bar.install.updating-shared-content": {
|
||||
"message": "Aktualizowanie udostępnionych zasobów"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "Instalacje"
|
||||
},
|
||||
@@ -125,6 +128,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Pokaż logi"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "Zaakceptuj wszystko"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "Reklamy pozwalają Modrinth oraz fundują wypłaty twórców. Nasi partnerzy mogą zachować lub uzyskać dostęp ciasteczek w aplikacji, żeby spersonalizować reklamy i zmierzyć wydajność."
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "Zarządzaj preferencjami"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "Odrzuć wszystkie"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "Twoja prywatność i jak reklamy wspierają Modrinth"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Włącza zaawansowane renderowanie, takie jak efekty rozmycia, które może powodować problemy z wydajnością bez sprzętowej akceleracji renderowania."
|
||||
},
|
||||
@@ -323,6 +341,24 @@
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Uruchamianie procesorów loadera"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.added-label": {
|
||||
"message": "Dodano"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-header": {
|
||||
"message": "Twoje zmiany nie zostały jeszcze udostępnione"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publish-button": {
|
||||
"message": "Opublikuj aktualizację"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publishing-button": {
|
||||
"message": "Publikowanie..."
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.removed-label": {
|
||||
"message": "Usunięto"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-admonition-header": {
|
||||
"message": "Opublikuj aktualizację"
|
||||
},
|
||||
"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ść."
|
||||
},
|
||||
@@ -422,9 +458,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Szukaj wśród {count} światów..."
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"message": "Nie instaluj"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Zainstaluj, aby grać"
|
||||
},
|
||||
@@ -464,9 +497,6 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Usunięto"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Aktualizacja jest wymagana, aby grać w {name}. Proszę zaktualizować do najnowszej wersji, aby uruchomić grę."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Ten projekt jest już zainstalowany"
|
||||
},
|
||||
@@ -494,6 +524,9 @@
|
||||
"app.settings.downloading": {
|
||||
"message": "Pobieranie v{version}"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "Reklamy pozwalają Modrinth oraz fundują wypłaty twórców. Nasi partnerzy mogą zachować lub uzyskać dostęp ciasteczek w aplikacji, żeby spersonalizować reklamy i zmierzyć wydajność. Możesz optować lub zarządzać preferencjami poniżej."
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "Wygląd"
|
||||
},
|
||||
@@ -536,6 +569,9 @@
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "Błąd podczas przetwarzania pliku"
|
||||
},
|
||||
"app.skins.ears-feature-notice": {
|
||||
"message": "Ta skórka używa funkcjonalności modyfikacji {ears}"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "Edytuj skórkę"
|
||||
},
|
||||
@@ -662,6 +698,12 @@
|
||||
"app.skins.title": {
|
||||
"message": "Wybór skórki"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "Wyłącz"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "Włącz"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Wersja Modrinth App v{version} została pobrana. Załaduj ponownie, żeby zaktualizować teraz, albo automatycznie, gdy zamkniesz Modrinth App."
|
||||
},
|
||||
@@ -773,6 +815,33 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Zaloguj się na konto Modrinth</link> by dodać znajomych i widzieć, w co grają!"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "Utwórz skrót"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "Eksportuj paczkę modów"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "Uruchom instancję"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "Więcej akcji"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "Otwórz folder"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "Napraw"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "Ustawienia instancji"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "Uruchamianie..."
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "Zatrzymywanie..."
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "Dodaj i graj"
|
||||
},
|
||||
@@ -815,6 +884,9 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "Zapisz jako..."
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "Nigdy nie grano"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "Adres"
|
||||
},
|
||||
@@ -1019,6 +1091,12 @@
|
||||
"instance.settings.tabs.window.width.enter": {
|
||||
"message": "Wprowadź szerokość..."
|
||||
},
|
||||
"instance.shared-instance.publish-review.admonition-header": {
|
||||
"message": "Opublikuj aktualizację graczom"
|
||||
},
|
||||
"instance.shared-instance.publish-review.publish-button": {
|
||||
"message": "Opublikuj aktualizację"
|
||||
},
|
||||
"instance.worlds.a_minecraft_server": {
|
||||
"message": "Serwer Minecraft"
|
||||
},
|
||||
@@ -1082,6 +1160,27 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "Zaloguj się do Minecraft"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "Potrzebujesz konto Microsoft, które posiada Minecraft, zanim będziesz mógł włączyć i zacząć grać."
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "Zaloguj się do konta Microsoft"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "Nie masz konta?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "Zdobądź Minecraft"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "Zdobądź pomoc techniczną"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "Minecraft wymagany"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "Zaloguj się do Microsoft"
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "Podane przez instancję"
|
||||
},
|
||||
|
||||
@@ -42,7 +42,7 @@
|
||||
"message": "Não foi possível baixar os arquivos"
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "O arquivo baixado é corrupto"
|
||||
"message": "O arquivo baixado está corrompido"
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Não foi possível salvar os arquivos"
|
||||
@@ -125,6 +125,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Ver registros"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "Aceitar tudo"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "Anúncios tornam o Modrinth possível e financiam os pagamentos dos criadores. Nossos parceiros talvez armazenem ou acessem os cookies no aplicativo para personalizar anúncios e medir o desempenho."
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "Gerenciar preferências"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "Rejeitar tudo"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "Sua privacidade e como anúncios apoiam o Modrinth"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Ativa a renderização avançada, como desfoque que talvez afete o desempenho sem renderização acelerada do hardware."
|
||||
},
|
||||
@@ -425,9 +440,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Buscar {count} mundos..."
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"message": "Não instalar"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Instale para jogar"
|
||||
},
|
||||
@@ -467,9 +479,6 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Removido"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Uma atualização é necessária para jogar {name}. Atualize para a versão mais recente para iniciar o jogo."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Este projeto já foi instalado"
|
||||
},
|
||||
@@ -497,6 +506,9 @@
|
||||
"app.settings.downloading": {
|
||||
"message": "Baixando v{version}"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "Anúncios tornam o Modrinth possível e financiam os pagamentos dos criadores. Nossos parceiros talvez armazenem ou acessem os cookies no aplicativo para personalizar anúncios e medir o desempenho. Você pode recusar ou gerenciar suas preferências abaixo."
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "Aparência"
|
||||
},
|
||||
@@ -539,6 +551,9 @@
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "Erro ao processar arquivo"
|
||||
},
|
||||
"app.skins.ears-feature-notice": {
|
||||
"message": "Esta skin usa recursos do mod {ears}"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "Editar skin"
|
||||
},
|
||||
@@ -660,11 +675,17 @@
|
||||
"message": "Modrinth Bot animado"
|
||||
},
|
||||
"app.skins.sign-in.title": {
|
||||
"message": "Por favor, inicie sessão"
|
||||
"message": "Inicie a sessão"
|
||||
},
|
||||
"app.skins.title": {
|
||||
"message": "Seletor de skins"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "Desativar"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "Ativar"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "O Modrinth App v{version} já foi instalado. Recarregue para atualizar agora ou ela será feita automaticamente ao fechar o Modrinth App."
|
||||
},
|
||||
@@ -776,6 +797,33 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Inicie uma sessão com o Modrinth</link> para adicionar amigos e ver o que eles estão jogando!"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "Criar atalho"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "Exportar pacote de mods"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "Iniciar instância"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "Mais ações"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "Abrir pasta"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "Reparar"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "Configurações da instância"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "Iniciando..."
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "Interrompendo..."
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "Adicionar e jogar"
|
||||
},
|
||||
@@ -818,6 +866,9 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "Salvar como..."
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "Nunca jogou"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "Endereço"
|
||||
},
|
||||
@@ -1083,7 +1134,28 @@
|
||||
"message": "Selecionar conta"
|
||||
},
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "Inicie sessão no Minecraft"
|
||||
"message": "Iniciar sessão no Minecraft"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "Você precisa de uma conta Microsoft que possui o Minecraft antes de iniciar e jogar."
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "Entrar em uma conta Microsoft"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "Não possui uma conta?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "Obter Minecraft"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "Obter suporte"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "Minecraft necessário"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "Entrar na Microsoft"
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "Fornecido pela instância"
|
||||
|
||||
@@ -11,6 +11,87 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Esconder mais instâncias a correr"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Copiado"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Copiar detalhes"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Dispensar"
|
||||
},
|
||||
"app.action-bar.install.open-instance": {
|
||||
"message": "Abrir instância"
|
||||
},
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Tentar novamente"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Cancelado devido ao encerramento da aplicação."
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "Não foi possível ler o Modpack"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Cancelado"
|
||||
},
|
||||
"app.action-bar.install.summary.cleanup-incomplete": {
|
||||
"message": "A limpeza não foi concluída."
|
||||
},
|
||||
"app.action-bar.install.summary.content-download-failed": {
|
||||
"message": "Não foi possível descarregar os ficheiros."
|
||||
},
|
||||
"app.action-bar.install.summary.corrupt-download": {
|
||||
"message": "O ficheiro descarregado está corrompido."
|
||||
},
|
||||
"app.action-bar.install.summary.could-not-save-files": {
|
||||
"message": "Não foi possível guardar os ficheiros."
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "O download não pôde ser concluído."
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "Não foi possível encontrar a instância."
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "Não foi possível encontrar a instância."
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "Dados do Modpack inválidos"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "Os ficheiros do Modpack possuem metadata inválidos"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "C"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "A configuração do loader falhou"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "Não foi possível atualizar os dados locais."
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "A instalação do Minecraft falhou"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "Não foi possível carregar o Modrinth."
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "Sem autorização para editar."
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "Não foi possível descarregar o pack"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "Algo correu mal"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Instância desconhecida"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "Instalações"
|
||||
},
|
||||
"app.action-bar.make-primary-instance": {
|
||||
"message": "Transformar na instância principal"
|
||||
},
|
||||
@@ -44,6 +125,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Ver logs"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "Aceitar tudo"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "Os anúncios tornam o Modrinth possível e financiam os pagamentos aos criadores. Os nossos parceiros podem armazenar ou aceder a cookies na aplicação para personalizar anúncios e medir o desempenho."
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "Gerir preferências"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "Rejeitar tudo"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "A sua privacidade e como os anúncios são financiados pela Modrinth"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Ativa a renderização avançada, como efeitos de desfoque, que podem causar problemas de desempenho sem o uso de renderização acelerada por hardware."
|
||||
},
|
||||
@@ -68,18 +164,69 @@
|
||||
"app.appearance-settings.default-landing-page.title": {
|
||||
"message": "Página de carregamento principal"
|
||||
},
|
||||
"app.appearance-settings.hide-nametag.description": {
|
||||
"message": "Desativa o nametag acima do seu player na página de skins."
|
||||
},
|
||||
"app.appearance-settings.hide-nametag.title": {
|
||||
"message": "Ocultar nametag"
|
||||
},
|
||||
"app.appearance-settings.jump-back-into-worlds.description": {
|
||||
"message": "Inclui mundos recentes na secção \"Voltar à ação\" na página inicial."
|
||||
},
|
||||
"app.appearance-settings.jump-back-into-worlds.title": {
|
||||
"message": "Volte aos mundos"
|
||||
},
|
||||
"app.appearance-settings.minimize-launcher.description": {
|
||||
"message": "Minimiza o inicializador quando um processo Minecraft é iniciado."
|
||||
},
|
||||
"app.appearance-settings.minimize-launcher.title": {
|
||||
"message": "Minimizar launcher"
|
||||
},
|
||||
"app.appearance-settings.native-decorations.description": {
|
||||
"message": "Utilizar a moldura da janela do sistema (é necessário reiniciar a aplicação)."
|
||||
},
|
||||
"app.appearance-settings.native-decorations.title": {
|
||||
"message": "Decorações nativas"
|
||||
},
|
||||
"app.appearance-settings.select-option": {
|
||||
"message": "Seleciona uma opção"
|
||||
},
|
||||
"app.appearance-settings.show-play-time.description": {
|
||||
"message": "Apresenta quanto tempo passou a jogar uma instância."
|
||||
},
|
||||
"app.appearance-settings.show-play-time.title": {
|
||||
"message": "Mostrar tempo de jogo"
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.description": {
|
||||
"message": "Ignora automaticamente confirmações de baixo risco, como instalações duplicadas de pacotes de mods, eliminação normal de conteúdo, atualizações em massa, desvinculação de pacotes de mods e pedidos de reparação. Os avisos de perigo ainda serão exibidos."
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.title": {
|
||||
"message": "Ignorar avisos não essenciais"
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.description": {
|
||||
"message": "Permite ativar/desativar a barra lateral."
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.title": {
|
||||
"message": "Ativar/desativar Barra lateral"
|
||||
},
|
||||
"app.appearance-settings.unknown-pack-warning.description": {
|
||||
"message": "Se tentar instalar um ficheiro Modrinth Pack (.mrpack) que não esteja alojado no Modrinth, iremos garantir que compreende os riscos antes de o instalar."
|
||||
},
|
||||
"app.appearance-settings.unknown-pack-warning.title": {
|
||||
"message": "Avise-me antes de instalar pacotes de mods desconhecidos."
|
||||
},
|
||||
"app.auth-servers.unreachable.body": {
|
||||
"message": "Os servidores de autenticação do Minecraft poderão estar em baixo de momento. Verifica a tua ligação à internet e tenta novamente mais tarde."
|
||||
},
|
||||
"app.auth-servers.unreachable.header": {
|
||||
"message": "Não foi possível alcançar os servidores de autenticação"
|
||||
},
|
||||
"app.browse.add-servers-to-instance": {
|
||||
"message": "Adicionar servidor à instância"
|
||||
},
|
||||
"app.browse.add-to-an-instance": {
|
||||
"message": "Adicionar a uma instância"
|
||||
},
|
||||
"app.browse.add-to-instance": {
|
||||
"message": "Adicionar à instância"
|
||||
},
|
||||
@@ -92,15 +239,30 @@
|
||||
"app.browse.already-added": {
|
||||
"message": "Já adicionado"
|
||||
},
|
||||
"app.browse.back-to-instance": {
|
||||
"message": "Voltar à instância"
|
||||
},
|
||||
"app.browse.discover-content": {
|
||||
"message": "Descobrir conteúdo"
|
||||
},
|
||||
"app.browse.discover-servers": {
|
||||
"message": "Descobrir servidores"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Ocultar servidores já adicionados"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modpacks"
|
||||
},
|
||||
"app.browse.server-instance-content-warning": {
|
||||
"message": "Adicionar conteúdo pode quebrar a compatibilidade ao entrar no servidor. Qualquer conteúdo adicionado também será perdido ao atualizar o conteúdo da instância do servidor."
|
||||
},
|
||||
"app.browse.server.installing": {
|
||||
"message": "Instalando.."
|
||||
},
|
||||
"app.content-install.no-compatible-versions": {
|
||||
"message": "Nenhuma versão disponível corresponde a {compatibilityLabel}. Selecione uma versão para instalar mesmo assim. As dependências não serão instaladas automaticamente."
|
||||
},
|
||||
"app.export-modal.description-placeholder": {
|
||||
"message": "Insere a descrição do modpack..."
|
||||
},
|
||||
@@ -110,6 +272,9 @@
|
||||
"app.export-modal.header": {
|
||||
"message": "Exportar modpack"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Nome do pacote"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Nome do Modpack"
|
||||
},
|
||||
@@ -119,6 +284,60 @@
|
||||
"app.export-modal.version-number-placeholder": {
|
||||
"message": "1.0.0"
|
||||
},
|
||||
"app.install.phase.downloading_content": {
|
||||
"message": "Baixando conteúdo"
|
||||
},
|
||||
"app.install.phase.downloading_minecraft": {
|
||||
"message": "Descarregar Minecraft"
|
||||
},
|
||||
"app.install.phase.downloading_pack_file": {
|
||||
"message": "Descarregando o ficheiro "
|
||||
},
|
||||
"app.install.phase.extracting_overrides": {
|
||||
"message": "Extraindo overrides"
|
||||
},
|
||||
"app.install.phase.finalizing": {
|
||||
"message": "Finalizando"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Instalado na fila"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Preparando Java"
|
||||
},
|
||||
"app.install.phase.preparing_java.downloading": {
|
||||
"message": "Descarregar Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.extracting": {
|
||||
"message": "Extrair Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.fetching-metadata": {
|
||||
"message": "Obtenção de Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.resolving": {
|
||||
"message": "Preparar Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.validating": {
|
||||
"message": "Validando o Java {version}"
|
||||
},
|
||||
"app.install.phase.reading_pack_manifest": {
|
||||
"message": "Lendo Manifesto"
|
||||
},
|
||||
"app.install.phase.resolving_loader": {
|
||||
"message": "Resolvendo o carregador"
|
||||
},
|
||||
"app.install.phase.resolving_minecraft": {
|
||||
"message": "Resolução de problemas no Minecraft"
|
||||
},
|
||||
"app.install.phase.resolving_pack": {
|
||||
"message": "Resolvendo conteúdo"
|
||||
},
|
||||
"app.install.phase.rolling_back": {
|
||||
"message": "Revertendo"
|
||||
},
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Executar processadores de carregamento"
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "Todos os dados da tua instância vão ser permanentemente apagados, incluídos os teus mundos, definições, e todos os conteúdos instalados."
|
||||
},
|
||||
@@ -143,6 +362,15 @@
|
||||
"app.instance.modpack-already-installed.instance": {
|
||||
"message": "Instância"
|
||||
},
|
||||
"app.instance.mods.bulk-update.downloading-projects": {
|
||||
"message": "A descarregar projetos {current, number}/{total, number}..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.finishing": {
|
||||
"message": "A terminar a atualização..."
|
||||
},
|
||||
"app.instance.mods.bulk-update.resolving-versions": {
|
||||
"message": "Resolvendo versões..."
|
||||
},
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "projeto"
|
||||
},
|
||||
@@ -167,6 +395,18 @@
|
||||
"app.instance.worlds.browse-servers": {
|
||||
"message": "Procurar servidores"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.delete-button": {
|
||||
"message": "Apagar mundo"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.title": {
|
||||
"message": "Apagar 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 anulada."
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-header": {
|
||||
"message": "A eliminar {name}"
|
||||
},
|
||||
"app.instance.worlds.filter-modded": {
|
||||
"message": "Com Mods"
|
||||
},
|
||||
@@ -185,29 +425,77 @@
|
||||
"app.instance.worlds.no-worlds-heading": {
|
||||
"message": "Sem servidores ou mundos adicionados"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.remove-button": {
|
||||
"message": "Remover server"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.title": {
|
||||
"message": "Remover server"
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.warning-body": {
|
||||
"message": "Este mundo será permanentemente excluído desta instância. Esta ação não pode ser anulada."
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.warning-header": {
|
||||
"message": "Removendo {name}"
|
||||
},
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Pesquisar {count} mundos..."
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Instala para jogar"
|
||||
},
|
||||
"app.modal.install-to-play.install-anyway": {
|
||||
"message": "Instalar mesmo assim"
|
||||
},
|
||||
"app.modal.install-to-play.install-button": {
|
||||
"message": "Instalar"
|
||||
},
|
||||
"app.modal.install-to-play.invite-warning": {
|
||||
"message": "Este convite foi criado por outro utilizador do Modrinth, não pelo Modrinth. Aceite convites apenas de pessoas em quem confia."
|
||||
},
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {mod} other {mods}}"
|
||||
},
|
||||
"app.modal.install-to-play.reviewed-files": {
|
||||
"message": "Um ficheiro só é analisado se for publicado no Modrinth, independentemente do seu formato (incluindo .mrpack)."
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Instância partilhada"
|
||||
},
|
||||
"app.modal.install-to-play.unknown-files-description": {
|
||||
"message": "Este pacote de mods para o servidor contém ficheiros que não estão publicados no Modrinth. Recomendamos vivamente que instale apenas ficheiros de fontes fidedignas."
|
||||
},
|
||||
"app.modal.install-to-play.unknown-files-warning": {
|
||||
"message": "Aviso de ficheiros desconhecidos"
|
||||
},
|
||||
"app.modal.install-to-play.unrecognized-files": {
|
||||
"message": "Arquivos não reconhecidos"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Ver conteúdo"
|
||||
},
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Atualiza para jogar"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Uma atualização é necessária para jogar {name}. Por favor atualiza para a versão mais recente para iniciar o jogo."
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Removido"
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Este projeto já está instalado."
|
||||
},
|
||||
"app.project.install-button.switch-version": {
|
||||
"message": "Mudar Versão"
|
||||
},
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "De volta à descoberta"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Todas as versões"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Download no navegador"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Instalando.."
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Modo de desenvolvedor ativado."
|
||||
@@ -215,6 +503,9 @@
|
||||
"app.settings.downloading": {
|
||||
"message": "A transferir v{version}"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "Os anúncios tornam o Modrinth possível e financiam os pagamentos aos criadores. Os nossos parceiros podem armazenar ou aceder a cookies na aplicação para personalizar anúncios e medir o desempenho."
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "Aparência"
|
||||
},
|
||||
@@ -233,12 +524,39 @@
|
||||
"app.settings.tabs.resource-management": {
|
||||
"message": "Gestão de recursos"
|
||||
},
|
||||
"app.skins.delete-button": {
|
||||
"message": "Apagar skin"
|
||||
},
|
||||
"app.skins.delete-modal.description": {
|
||||
"message": "Isto irá eliminar permanentemente esta coleção. Esta ação não pode ser desfeita."
|
||||
},
|
||||
"app.skins.delete-modal.title": {
|
||||
"message": "Tens a certeza que queres apagar esta skin?"
|
||||
},
|
||||
"app.skins.dropped-file-error.text": {
|
||||
"message": "Não foi possível ler o ficheiro largado."
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "Editar skin"
|
||||
},
|
||||
"app.skins.modal.add-title": {
|
||||
"message": "Adicionar uma skin"
|
||||
},
|
||||
"app.skins.modal.none-cape-option": {
|
||||
"message": "Nada"
|
||||
},
|
||||
"app.skins.modal.saving-tooltip": {
|
||||
"message": "A guardar..."
|
||||
},
|
||||
"app.skins.preview.edit-button": {
|
||||
"message": "Editar skin"
|
||||
},
|
||||
"app.skins.previewing-badge": {
|
||||
"message": "Pré-visualizar"
|
||||
},
|
||||
"app.skins.reorder-error.text": {
|
||||
"message": "O seu pedido de skin não pôde ser guardado."
|
||||
},
|
||||
"app.skins.section.modrinth": {
|
||||
"message": "Modrinth"
|
||||
},
|
||||
|
||||
@@ -23,9 +23,6 @@
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "Actualizați pentru a juca"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Este necesară o actualizare pentru a juca {name}. Vă rugăm să actualizați la cea mai recentă versiune pentru a lansa jocul."
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Modul dezvoltator activat."
|
||||
},
|
||||
|
||||
@@ -125,6 +125,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Посмотреть журнал"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "Принять всё"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "Реклама обеспечивает работу Modrinth и финансирует выплаты авторам. Наши партнёры могут хранить или получать доступ к файлам cookie в приложении для персонализации рекламы и измерения производительности."
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "Настроить предпочтения"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "Отклонить всё"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "Конфиденциальность и как реклама помогает Modrinth"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Включает продвинутые эффекты вроде размытия, но может снизить производительность на устройствах без аппаратного ускорения."
|
||||
},
|
||||
@@ -323,6 +338,12 @@
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "Запуск процессоров загрузчика"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-header": {
|
||||
"message": "Проверьте изменения"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.reviewing-button": {
|
||||
"message": "Проверка..."
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "Все данные сборки будут удалены навсегда, в том числе миры, настройки и весь установленный контент."
|
||||
},
|
||||
@@ -371,6 +392,45 @@
|
||||
"app.instance.mods.successfully-uploaded": {
|
||||
"message": "Успешно загружено"
|
||||
},
|
||||
"app.instance.share.empty.heading": {
|
||||
"message": "Друзья не приглашены"
|
||||
},
|
||||
"app.instance.share.empty.invite-friends-button": {
|
||||
"message": "Пригласить друзей"
|
||||
},
|
||||
"app.instance.share.locked.switch-account-button": {
|
||||
"message": "Сменить аккаунт"
|
||||
},
|
||||
"app.instance.share.locked.wrong-account-heading": {
|
||||
"message": "Неверный аккаунт"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effects-label": {
|
||||
"message": "Что произойдёт?"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.header": {
|
||||
"message": "Отзыв доступа"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.remove-button": {
|
||||
"message": "Отозвать доступ"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.user-avatar-alt": {
|
||||
"message": "Аватар {username}"
|
||||
},
|
||||
"app.instance.share.sign-in.button": {
|
||||
"message": "Войти"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.instance": {
|
||||
"message": "Сборка"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.sign-in-as-label": {
|
||||
"message": "Войти как"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.signed-out-header": {
|
||||
"message": "Необходимо войти в Modrinth"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.user-admonition-body-v2": {
|
||||
"message": "для получения обновлений сборки."
|
||||
},
|
||||
"app.instance.worlds.add-server": {
|
||||
"message": "Добавить сервер"
|
||||
},
|
||||
@@ -419,7 +479,10 @@
|
||||
"app.instance.worlds.remove-server-modal.warning-header": {
|
||||
"message": "Удаление {name}"
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"app.modal.install-to-play.delete-instance": {
|
||||
"message": "Удалить сборку"
|
||||
},
|
||||
"app.modal.install-to-play.external-files-dont-install": {
|
||||
"message": "Не устанавливать"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
@@ -437,6 +500,9 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# мод} few {# мода} other {# модов}}"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.spam": {
|
||||
"message": "Спам"
|
||||
},
|
||||
"app.modal.install-to-play.reviewed-files": {
|
||||
"message": "Файл проверяется только если он опубликован на Modrinth, независимо от его формата (включая .mrpack)."
|
||||
},
|
||||
@@ -461,6 +527,9 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Удалён"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "Требуется обновление"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Обновите {name} до последней версии, чтобы запустить игру."
|
||||
},
|
||||
@@ -491,6 +560,9 @@
|
||||
"app.settings.downloading": {
|
||||
"message": "Скачивание версии {version}"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "Реклама обеспечивает работу Modrinth и финансирует выплаты авторам. Наши партнёры могут хранить или получать доступ к файлам cookie в приложении для персонализации рекламы и измерения производительности. Вы можете отказаться или настроить предпочтения ниже."
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "Внешний вид"
|
||||
},
|
||||
@@ -533,6 +605,9 @@
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "Ошибка обработки файла"
|
||||
},
|
||||
"app.skins.ears-feature-notice": {
|
||||
"message": "В этом скине используются функционал мода {ears}"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "Изменить скин"
|
||||
},
|
||||
@@ -659,6 +734,12 @@
|
||||
"app.skins.title": {
|
||||
"message": "Выбор скина"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "Выключить"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "Включить"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Скачивание версии Modrinth App {version} завершено. Перезапустите приложение, чтобы обновить его, или оно обновится автоматически после закрытия."
|
||||
},
|
||||
@@ -707,6 +788,15 @@
|
||||
"app.world.world-item.players-online": {
|
||||
"message": "{count} в игре"
|
||||
},
|
||||
"content.shared-instance.delete-button": {
|
||||
"message": "Всё равно удалить"
|
||||
},
|
||||
"content.shared-instance.delete-many-button": {
|
||||
"message": "Всё равно удалить {count, plural, one {# проект} few {# проекта} other {# проектов}}"
|
||||
},
|
||||
"content.shared-instance.disable-button": {
|
||||
"message": "Всё равно отключить"
|
||||
},
|
||||
"friends.action.add-friend": {
|
||||
"message": "Добавить в друзья"
|
||||
},
|
||||
@@ -770,6 +860,33 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Войдите в аккаунт Modrinth</link>, чтобы добавлять друзей и следить за ними!"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "Создать ярлык"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "Экспортировать сборку"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "Запустить сборку"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "Дополнительно"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "Открыть папку"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "Исправить"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "Настройки сборки"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "Запуск..."
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "Остановка..."
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "Добавить и играть"
|
||||
},
|
||||
@@ -809,6 +926,12 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "Сохранить как..."
|
||||
},
|
||||
"instance.locked.delete-button": {
|
||||
"message": "Удалить сборку"
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "Не запускалась"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "Адрес"
|
||||
},
|
||||
@@ -1013,6 +1136,12 @@
|
||||
"instance.settings.tabs.window.width.enter": {
|
||||
"message": "Введите ширину..."
|
||||
},
|
||||
"instance.shared-instance.publish-review.added-label": {
|
||||
"message": "Добавлен"
|
||||
},
|
||||
"instance.shared-instance.publish-review.header": {
|
||||
"message": "Проверьте изменения"
|
||||
},
|
||||
"instance.worlds.a_minecraft_server": {
|
||||
"message": "Сервер Minecraft"
|
||||
},
|
||||
@@ -1076,6 +1205,54 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "Войти в Minecraft"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "Для запуска и игры требуется аккаунт Microsoft с приобретённым Minecraft."
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "Войдите в аккаунт Microsoft"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "Нет аккаунта?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "Приобрести Minecraft"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "Поддержка"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "Требуется Minecraft"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "Войти в Microsoft"
|
||||
},
|
||||
"modal.modrinth-account-required.cancel-button": {
|
||||
"message": "Отменить"
|
||||
},
|
||||
"modal.modrinth-account-required.continue-in-browser-heading": {
|
||||
"message": "Продолжите в браузере"
|
||||
},
|
||||
"modal.modrinth-account-required.create-account-button": {
|
||||
"message": "Создать аккаунт"
|
||||
},
|
||||
"modal.modrinth-account-required.header": {
|
||||
"message": "Требуется аккаунт"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-button": {
|
||||
"message": "Войти в Modrinth"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-heading": {
|
||||
"message": "Войдите в аккаунт Modrinth"
|
||||
},
|
||||
"modal.modrinth-account-required.signing-in-header": {
|
||||
"message": "Вход"
|
||||
},
|
||||
"modal.modrinth-account-required.support-prompt": {
|
||||
"message": "Проблемы с входом? <support>Обратитесь в поддержку</support>"
|
||||
},
|
||||
"modal.modrinth-account-required.waiting-for-browser": {
|
||||
"message": "Ожидание подтверждения браузера..."
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "Управляется сборкой"
|
||||
},
|
||||
|
||||
@@ -425,9 +425,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Pretraži {count} svetova..."
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"message": "Ne instaliraj"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Instaliraj da bi igrao"
|
||||
},
|
||||
@@ -467,9 +464,6 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Smaknuto"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Potrebno je ažuriranje da biste igrali {name}. Molimo te da ažuriraš na najnoviju verziju da bi pokrenuo igru."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Ovaj projekat je već instaliran"
|
||||
},
|
||||
|
||||
@@ -107,6 +107,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Visa loggar"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "Godkänn alla"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "Reklam gör Modrinth möjligt och finansierar utbetalningar till skapare. Våra partners kan lagra eller komma åt cookies i appen för att Personalisera reklam och mäta statistik."
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "Hantera inställningar"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "Neka alla"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "Din integritet och hur reklam stödjer Modrinth"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Aktiverar avancerad rendering som till exempel oskärpa vilket kan leda till prestandaproblem utan hårdvaruaccelererad rendering."
|
||||
},
|
||||
@@ -309,7 +324,7 @@
|
||||
"message": "All data från din instans kommer permanent raderas, däribland dina världar, konfigurationer samt allt installerat innehåll."
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-header": {
|
||||
"message": "Detta kan inte ångras"
|
||||
"message": "Denna åtgärd kan inte ångras"
|
||||
},
|
||||
"app.instance.confirm-delete.delete-button": {
|
||||
"message": "Radera instans"
|
||||
@@ -360,13 +375,13 @@
|
||||
"message": "Lägg till server"
|
||||
},
|
||||
"app.instance.worlds.browse-servers": {
|
||||
"message": "Utforska servrar"
|
||||
"message": "Bläddra servrar"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.delete-button": {
|
||||
"message": "Ta bort värld"
|
||||
"message": "Radera värld"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.title": {
|
||||
"message": "Ta bort värld"
|
||||
"message": "Radera värld"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-body": {
|
||||
"message": "Denna värld kommer permanent raderas från instansen. Detta kan inte ångras."
|
||||
@@ -402,14 +417,11 @@
|
||||
"message": "Denna server kommer att tas bort från din serverlista och serverlistan i spelet. Du kan lägga till den igen senare om du känner till adressen."
|
||||
},
|
||||
"app.instance.worlds.remove-server-modal.warning-header": {
|
||||
"message": "Raderar {name}"
|
||||
"message": "Tar bort {name}"
|
||||
},
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Sök {count} världar..."
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"message": "Installera inte"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Installera för att spela"
|
||||
},
|
||||
@@ -419,12 +431,21 @@
|
||||
"app.modal.install-to-play.install-button": {
|
||||
"message": "Installera"
|
||||
},
|
||||
"app.modal.install-to-play.invite-warning": {
|
||||
"message": "Denna inbjudan skapades av en annan Modrinth-användare, inte Modrinth. Acceptera endast inbjudningar från personer du litar på."
|
||||
},
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, one {# mod} other {# moddar}}"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "Delad instans"
|
||||
},
|
||||
"app.modal.install-to-play.unknown-files-description": {
|
||||
"message": "Detta server-modpaket innehåller filer som inte är utgivna på Modrinth. Vi rekommenderar att endast installera filer från källor du litar på."
|
||||
},
|
||||
"app.modal.install-to-play.unknown-files-warning": {
|
||||
"message": "Okända filvarningar"
|
||||
},
|
||||
"app.modal.install-to-play.view-contents": {
|
||||
"message": "Visa innehåll"
|
||||
},
|
||||
@@ -434,9 +455,6 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Tog bort"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "En uppdatering krävs för att spela {name}. Vänligen uppdatera till senaste version för att starta spelet."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Detta projekt är redan installerat"
|
||||
},
|
||||
@@ -464,6 +482,9 @@
|
||||
"app.settings.downloading": {
|
||||
"message": "Ladda ner v{version}"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "Reklam gör Modrinth möjligt och finansierar utbetalningar till skapare. Våra partners kan lagra eller komma åt cookies i appen för att Personalisera reklam och mäta statistik."
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "Utseende"
|
||||
},
|
||||
@@ -743,6 +764,33 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Logga in på ett Modrinth-konto</link> för att lägga till vänner och se vad de spelar!"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "Skapa genväg"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "Exportera modpaket"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "Kör instans"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "Fler åtgärder"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "Öppna mapp"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "Reparera"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "Instans-inställningar"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "Startar..."
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "Stoppar..."
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "Lägg till och spela"
|
||||
},
|
||||
@@ -785,6 +833,9 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "Spara som..."
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "Aldrig spelad"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "Adress"
|
||||
},
|
||||
@@ -1052,6 +1103,27 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "Logga in till Minecraft"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "Du behöver ett Microsoft-konto som äger Minecraft innan du kan köra och spela."
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "Logga in till ett Microsoft-konto"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "Har du inget konto?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "Skaffa Minecraft"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "Få stöd"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "Minecraft behövs"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "Logga in på Microsoft"
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "Tillhandahållet av instansen"
|
||||
},
|
||||
|
||||
@@ -263,9 +263,6 @@
|
||||
"app.modal.update-to-play.header": {
|
||||
"message": "อัปเดตเพื่อเล่น"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "จำเป็นต้องอัปเดตเพื่อเล่น {name} กรุณาอัปเดตเป็นเวอร์ชันล่าสุดเพื่อเปิดเกม"
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "โปรเจคนี้ถูกติดตั้งแล้ว"
|
||||
},
|
||||
|
||||
@@ -125,6 +125,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Günlükleri görüntüle"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "Hepsini kabul et"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "Reklamlar, Modrinth'i mümkün kılıyor ve içerik üreticilerine yapılan ödemeleri finanse ediyor. Partnerlerimiz, reklamları kişiselleştirmek ve performansı ölçmek amacıyla uygulama içinde çerez depolayabilir veya bunlara erişebilir."
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "Tercihleri yönet"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "Hepsini redder"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "Sizin mahremiyetiniz ve reklamlar Modrinth'i nasıl destekler"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Donanım hızlandırmalı işleme kapalıyken, performans sorunlarına yol açabilecek bulanıklık efektleri gibi gelişmiş işlemeleri aktif eder."
|
||||
},
|
||||
@@ -425,9 +440,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "{count} dünya ara..."
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"message": "İndirme"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Oynamak için yükleyin"
|
||||
},
|
||||
@@ -467,9 +479,6 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Silindi"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "{name} oyununu oynamak için güncelleme gereklidir. Oyunu başlatmak için lütfen en son sürüme güncelleyin."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Bu proje zaten kurulu"
|
||||
},
|
||||
@@ -497,6 +506,9 @@
|
||||
"app.settings.downloading": {
|
||||
"message": "v{version} indiriliyor"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "Reklamlar, Modrinth'i mümkün kılıyor ve içerik üreticilerine yapılan ödemeleri finanse ediyor. Partnerlerimiz, reklamları kişiselleştirmek ve performansı ölçmek amacıyla uygulama içinde çerez depolayabilir veya bunlara erişebilir. Aşağıdan tercihinizi yönetebilir veya vazgeçebilirsiniz."
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "Görünüm"
|
||||
},
|
||||
@@ -539,6 +551,9 @@
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "Dosya işlenirken hata oluştu"
|
||||
},
|
||||
"app.skins.ears-feature-notice": {
|
||||
"message": "Bu skin {ears} modundan özellikler içeriyor"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "Skin'i düzenle"
|
||||
},
|
||||
@@ -665,6 +680,12 @@
|
||||
"app.skins.title": {
|
||||
"message": "Skin seçici"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "Kapat"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "Aç"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Modrinth App v{version} indirildi. Güncellemek için yeniden başlatın veya Modrinth App’i kapattığınızda otomatik olarak güncellenecektir."
|
||||
},
|
||||
@@ -776,6 +797,33 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "Arkadaş eklemek ve ne oynadıklarını görmek için bir <link>Modrinth hesabına giriş yap</link>!"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "Kısayol oluştur"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "Mod paketini dışa aktar"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "Kurulumu başlat"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "Daha fazla seçenek"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "Klasörü aç"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "Onar"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "Kurulum ayarları"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "Başlatılıyor..."
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "Durduruluyor..."
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "Ekle ve oyna"
|
||||
},
|
||||
@@ -818,6 +866,9 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "Farklı kaydet..."
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "Hiç oynanmadı"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "Adres"
|
||||
},
|
||||
@@ -1085,6 +1136,27 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "Minecraft'a giriş yapın"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "Oyunu başlatmak ve oynamak için Minecraft'a sahip olan bir Microsoft hesabına ihtiyaç vardır."
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "Bir Microsoft hesabına giriş yap"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "Hesabınız yok mu?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "Minecraft al"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "Destek al"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "Minecraft gereklidir"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "Microsoft'a giriş yap"
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "Kurulum tarafından sağlanan"
|
||||
},
|
||||
|
||||
@@ -24,13 +24,13 @@
|
||||
"message": "Відкрити екземпляр"
|
||||
},
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Спробувати знову"
|
||||
"message": "Повторити"
|
||||
},
|
||||
"app.action-bar.install.summary.app-closing": {
|
||||
"message": "Скасовано через закриття додатку"
|
||||
"message": "Скасовано через закриття застосунку"
|
||||
},
|
||||
"app.action-bar.install.summary.bad-modpack-file": {
|
||||
"message": "Не вдалось прочитати збірку модифікацій"
|
||||
"message": "Не вдалося прочитати збірку"
|
||||
},
|
||||
"app.action-bar.install.summary.canceled": {
|
||||
"message": "Скасовано"
|
||||
@@ -48,25 +48,25 @@
|
||||
"message": "Не вдалося зберегти файли"
|
||||
},
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "Завантаження не вдалося завершити"
|
||||
"message": "Не вдалося завантажити"
|
||||
},
|
||||
"app.action-bar.install.summary.instance-not-found": {
|
||||
"message": "Екземпляр не знайдено"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "Шлях до файлу недійсний"
|
||||
"message": "Недійсний шлях до файлу"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "Дані збірки модів недійсні"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "Файли збірки модифікацій містять не дійсні метадані"
|
||||
"message": "Файли збірки містять недійсні метадані"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "Не вдалося завершити встановлення Java"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "Помилка встановлення завантажувача"
|
||||
"message": "Не вдалося встановити завантажувач"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "Не вдалося оновити локальні дані"
|
||||
@@ -87,7 +87,7 @@
|
||||
"message": "Щось пішло не так"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Невідомий екземпляр"
|
||||
"message": "Невідомий профіль"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "Установки"
|
||||
@@ -105,7 +105,7 @@
|
||||
"message": "Основний профіль"
|
||||
},
|
||||
"app.action-bar.reload-to-update": {
|
||||
"message": "Перезавантаження для оновлення"
|
||||
"message": "Перезавантажте, щоб оновити"
|
||||
},
|
||||
"app.action-bar.show-more-running-instances": {
|
||||
"message": "Показати більше запущених профілів"
|
||||
@@ -114,7 +114,7 @@
|
||||
"message": "Зупинити профіль"
|
||||
},
|
||||
"app.action-bar.update": {
|
||||
"message": "Оновлення"
|
||||
"message": "Оновити"
|
||||
},
|
||||
"app.action-bar.view-active-downloads": {
|
||||
"message": "Переглянути активні завантаження"
|
||||
@@ -125,14 +125,29 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Переглянути журнали"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "Прийняти всі"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "Реклама підтримує існування Modrinth та фінансує виплати творцям. Наші партнери можуть зберігати та отримувати доступ до cookie в застосунку, аби персоналізувати рекламу та збирати метрики."
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "Налаштувати"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "Відхилити всі"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "Ваша приватність та як реклама підтримує Modrinth"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Дозволяє розширене промальовування, як-от ефекти розмиття, які можуть спричиняти проблеми з продуктивністю без апаратно-прискореного промальовування."
|
||||
"message": "Умикає розширене промальовування, як-от ефекти розмиття. Вони можуть спричиняти проблеми з продуктивністю без апаратного прискорення."
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.title": {
|
||||
"message": "Розширене промальовування"
|
||||
},
|
||||
"app.appearance-settings.color-theme.description": {
|
||||
"message": "Виберіть бажану колірну тему для Modrinth App."
|
||||
"message": "Оберіть бажану колірну тему для Modrinth App."
|
||||
},
|
||||
"app.appearance-settings.color-theme.title": {
|
||||
"message": "Колірна тема"
|
||||
@@ -159,16 +174,16 @@
|
||||
"message": "Уключає нещодавні світи в розділі «Повернутися» на головній сторінці."
|
||||
},
|
||||
"app.appearance-settings.jump-back-into-worlds.title": {
|
||||
"message": "Повернутися у світи"
|
||||
"message": "Повернутися до світів"
|
||||
},
|
||||
"app.appearance-settings.minimize-launcher.description": {
|
||||
"message": "Згортає запускач під час запуску процесу Minecraft."
|
||||
},
|
||||
"app.appearance-settings.minimize-launcher.title": {
|
||||
"message": "Мінімізувати запускач"
|
||||
"message": "Згортати запускач"
|
||||
},
|
||||
"app.appearance-settings.native-decorations.description": {
|
||||
"message": "Використовувати рамку системного вікна (потрібно перезапустити програму)."
|
||||
"message": "Використовує рамку системного вікна (необхідно перезапустити застосунок)."
|
||||
},
|
||||
"app.appearance-settings.native-decorations.title": {
|
||||
"message": "Системне оформлення"
|
||||
@@ -183,7 +198,7 @@
|
||||
"message": "Час гри"
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.description": {
|
||||
"message": "Автоматично пропускає підтвердження з низьким рівнем ризику, такі як встановлення дублікатів інсталяцій, звичайне видалення вмісту, масові оновлення, від’єднання інсталяцій та запити на відновлення. Попередження про небезпеку й надалі будуть показуватися."
|
||||
"message": "Автоматично пропускає низькоризикові підтвердження: установки дубльованих збірок, звичайні видалення вмісту, масові оновлення та запити на відновлення. Попередження з вищим рівнем ризику залишаться."
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.title": {
|
||||
"message": "Пропустити несуттєві попередження"
|
||||
@@ -231,7 +246,7 @@
|
||||
"message": "Дослідити вміст"
|
||||
},
|
||||
"app.browse.discover-servers": {
|
||||
"message": "Дослідити сервера"
|
||||
"message": "Дослідити сервери"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Приховати вже додані сервери"
|
||||
@@ -348,7 +363,7 @@
|
||||
"message": "Профіль"
|
||||
},
|
||||
"app.instance.mods.bulk-update.downloading-projects": {
|
||||
"message": "Завантаження проєктів: {current, number}/{total, number}..."
|
||||
"message": "Завантаження проєктів: {current, number}/{total, number}…"
|
||||
},
|
||||
"app.instance.mods.bulk-update.finishing": {
|
||||
"message": "Завершуємо оновлення…"
|
||||
@@ -359,11 +374,14 @@
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "проєкт"
|
||||
},
|
||||
"app.instance.mods.locked-content": {
|
||||
"message": "Уміст у заблокованих профілях не можна змінювати."
|
||||
},
|
||||
"app.instance.mods.project-was-added": {
|
||||
"message": "«{name}» було додано"
|
||||
"message": "«{name}» додано"
|
||||
},
|
||||
"app.instance.mods.projects-were-added": {
|
||||
"message": "{count} проєктів було додано"
|
||||
"message": "{count} проєктів додано"
|
||||
},
|
||||
"app.instance.mods.share-text": {
|
||||
"message": "Погляньте на проєкти, які я використовую у своїй збірці!"
|
||||
@@ -374,6 +392,39 @@
|
||||
"app.instance.mods.successfully-uploaded": {
|
||||
"message": "Успішно вивантажено"
|
||||
},
|
||||
"app.instance.share.empty.description": {
|
||||
"message": "Ви можете поділитися цим профілем із друзями!"
|
||||
},
|
||||
"app.instance.share.empty.heading": {
|
||||
"message": "Немає запрошених друзів"
|
||||
},
|
||||
"app.instance.share.empty.invite-friends-button": {
|
||||
"message": "Запросити друзів"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-prefix": {
|
||||
"message": "Ви повинні ввійти як"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.user-avatar-alt": {
|
||||
"message": "Аватар {username}"
|
||||
},
|
||||
"app.instance.share.unlink.body": {
|
||||
"message": "Ви повинні від'єднати цю збірку, аби поділитися своїм профілем"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.body": {
|
||||
"message": "Цей спільний профіль уже встановлено як <bold>{instanceName}</bold>. Дійсно встановити ще одну копію?"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.header": {
|
||||
"message": "Спільний профіль уже встановлено"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.install-anyway": {
|
||||
"message": "Усе одно встановити"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.sign-in-as-label": {
|
||||
"message": "Увійти як"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.signed-out-header": {
|
||||
"message": "Ви повинні ввійти в Modrinth"
|
||||
},
|
||||
"app.instance.worlds.add-server": {
|
||||
"message": "Додати сервер"
|
||||
},
|
||||
@@ -425,9 +476,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Пошук {count} світів…"
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"message": "Не встановлювати"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Установлення для гри"
|
||||
},
|
||||
@@ -467,9 +515,6 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Видалено"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "«{name}» потребує оновлення, щоб грати. Будь ласка, оновіть до останньої версії, щоб запустити гру."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Проєкт уже встановлено"
|
||||
},
|
||||
@@ -479,12 +524,27 @@
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Повернутися до дослідження"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Усі версії"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Завантажити в браузері"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Установлення"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Уже встановлено"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Увімкнено режим розробника."
|
||||
},
|
||||
"app.settings.downloading": {
|
||||
"message": "Завантаження v{version}"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "Реклама підтримує існування Modrinth та фінансує виплати творцям. Наші партнери можуть зберігати та отримувати доступ до cookie в застосунку, аби персоналізувати рекламу та збирати метрики. Ви можете відмовитися від них або керувати налаштуваннями нижче."
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "Вигляд"
|
||||
},
|
||||
@@ -527,6 +587,9 @@
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "Помилка обробки файлу"
|
||||
},
|
||||
"app.skins.ears-feature-notice": {
|
||||
"message": "Цей скін використовує функціонал моду «{ears}»"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "Редагувати скін"
|
||||
},
|
||||
@@ -653,6 +716,12 @@
|
||||
"app.skins.title": {
|
||||
"message": "Вибір скіну"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "Вимкнути"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "Увімкнути"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Modrinth App v{version} завантажено. Перезапустіть, щоб оновити зараз, або це відбудеться автоматично після закриття застосунку."
|
||||
},
|
||||
@@ -764,6 +833,33 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>Увійдіть в обліковий запис Modrinth</link>, щоб додати друзів і бачити, у що вони грають!"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "Створити ярлик"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "Експортувати збірку"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "Запустити профіль"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "Інші дії"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "Відкрити теку"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "Виправити"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "Налаштування профілю"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "Запускаємо…"
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "Зупиняємо…"
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "Додати та грати"
|
||||
},
|
||||
@@ -806,6 +902,9 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "Зберегти як..."
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "Не запускався"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "Адреса"
|
||||
},
|
||||
@@ -1010,6 +1109,9 @@
|
||||
"instance.settings.tabs.window.width.enter": {
|
||||
"message": "Уведіть ширину…"
|
||||
},
|
||||
"instance.shared-instance.unavailable.access-revoked-text": {
|
||||
"message": "Ваш доступ до цього спільного профілю відкликано. Профіль досі доступний, але вже не прив'язаний та не отримуватиме оновлення."
|
||||
},
|
||||
"instance.worlds.a_minecraft_server": {
|
||||
"message": "Сервер Minecraft"
|
||||
},
|
||||
@@ -1073,6 +1175,27 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "Увійти в Minecraft"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "Ви повинні мати обліковий запис Microsoft із придбаним Minecraft, перш ніж запускати ігри."
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "Увійти в обліковий запис Microsoft"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "Не маєте облікового запису?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "Отримати Minecraft"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "Отримати підтримку"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "Потрібний Minecraft"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "Увійти в Microsoft"
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "Надано профілем"
|
||||
},
|
||||
|
||||
@@ -11,6 +11,15 @@
|
||||
"app.action-bar.hide-more-running-instances": {
|
||||
"message": "Đóng các phiên bản đang chạy"
|
||||
},
|
||||
"app.action-bar.install.copied-details": {
|
||||
"message": "Đã sao chép"
|
||||
},
|
||||
"app.action-bar.install.copy-details": {
|
||||
"message": "Sao chép chi tiết"
|
||||
},
|
||||
"app.action-bar.install.dismiss": {
|
||||
"message": "Bỏ qua"
|
||||
},
|
||||
"app.action-bar.install.retry": {
|
||||
"message": "Thử lại"
|
||||
},
|
||||
@@ -38,6 +47,45 @@
|
||||
"app.action-bar.install.summary.download-failed": {
|
||||
"message": "Không hoàn tất tải xuống"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-file-path": {
|
||||
"message": "Đường dẫn tệp tin không hợp lệ"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack": {
|
||||
"message": "Dữ liệu modpack không hợp lệ"
|
||||
},
|
||||
"app.action-bar.install.summary.invalid-modpack-files": {
|
||||
"message": "Tệp modpack có metadata không hợp lệ"
|
||||
},
|
||||
"app.action-bar.install.summary.java-setup-failed": {
|
||||
"message": "Quá trình cài đặt Java không thể hoàn thành"
|
||||
},
|
||||
"app.action-bar.install.summary.loader-setup-failed": {
|
||||
"message": "Cài đặt Loader thất bại"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "Không thể cập nhật dữ liệu cục bộ"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "Cài đặt Minecraft thất bại"
|
||||
},
|
||||
"app.action-bar.install.summary.modrinth-unreachable": {
|
||||
"message": "Không thể kết nối được với Modrinth"
|
||||
},
|
||||
"app.action-bar.install.summary.no-write-permission": {
|
||||
"message": "Không có quyền để viết"
|
||||
},
|
||||
"app.action-bar.install.summary.pack-download-failed": {
|
||||
"message": "Không thể tải xuống gói"
|
||||
},
|
||||
"app.action-bar.install.summary.unexpected-error": {
|
||||
"message": "Đã xảy ra lỗi"
|
||||
},
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "Instance không rõ"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "Cài đặt"
|
||||
},
|
||||
"app.action-bar.make-primary-instance": {
|
||||
"message": "Đặt làm bản instance chính"
|
||||
},
|
||||
@@ -71,6 +119,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "Xem logs"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "Chấp nhận tất cả"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "Quảng cáo giúp Modrinth hoạt động và tài trợ cho việc thanh toán cho người sáng tạo nội dung. Các đối tác của chúng tôi có thể lưu trữ hoặc truy cập cookie trong ứng dụng để cá nhân hóa quảng cáo và đo lường hiệu suất."
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "Quản lý tùy chọn"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "Từ chối tất cả"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "Quyền riêng tư của bạn và cách quảng cáo hỗ trợ Modrinth"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "Kích hoạt các tính năng dựng hình nâng cao như hiệu ứng làm mờ, có thể gây giảm hiệu năng nếu không có chế độ tăng tốc phần cứng."
|
||||
},
|
||||
@@ -128,6 +191,12 @@
|
||||
"app.appearance-settings.show-play-time.title": {
|
||||
"message": "Hiện thời gian chơi"
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.description": {
|
||||
"message": "Tự động bỏ qua các bước xác nhận rủi ro thấp như cài đặt gói mod trùng lặp, xóa nội dung thông thường, cập nhật hàng loạt, hủy liên kết gói mod và lời nhắc sửa chữa. Các cảnh báo nguy hiểm vẫn sẽ được hiển thị."
|
||||
},
|
||||
"app.appearance-settings.skip-non-essential-warnings.title": {
|
||||
"message": "Bỏ qua các cảnh báo không quan trọng"
|
||||
},
|
||||
"app.appearance-settings.toggle-sidebar.description": {
|
||||
"message": "Bật tính năng ẩn hiển thị thanh menu bên."
|
||||
},
|
||||
@@ -173,6 +242,9 @@
|
||||
"app.browse.discover-servers": {
|
||||
"message": "Khám phá máy chủ"
|
||||
},
|
||||
"app.browse.hide-added-servers": {
|
||||
"message": "Ẩn máy chủ đã thêm vào"
|
||||
},
|
||||
"app.browse.project-type.modpacks": {
|
||||
"message": "Modpack"
|
||||
},
|
||||
@@ -194,6 +266,9 @@
|
||||
"app.export-modal.header": {
|
||||
"message": "Xuất modpack"
|
||||
},
|
||||
"app.export-modal.modpack-name-label": {
|
||||
"message": "Tên modpack"
|
||||
},
|
||||
"app.export-modal.modpack-name-placeholder": {
|
||||
"message": "Tên modpack"
|
||||
},
|
||||
@@ -203,6 +278,39 @@
|
||||
"app.export-modal.version-number-placeholder": {
|
||||
"message": "1.0.0"
|
||||
},
|
||||
"app.install.phase.downloading_content": {
|
||||
"message": "Đang tải nội dung"
|
||||
},
|
||||
"app.install.phase.downloading_minecraft": {
|
||||
"message": "Đang tải Minecraft"
|
||||
},
|
||||
"app.install.phase.downloading_pack_file": {
|
||||
"message": "Đang tải tệp gói"
|
||||
},
|
||||
"app.install.phase.extracting_overrides": {
|
||||
"message": "Trích xuất ghi đè"
|
||||
},
|
||||
"app.install.phase.finalizing": {
|
||||
"message": "Hoàn tất"
|
||||
},
|
||||
"app.install.phase.preparing_instance": {
|
||||
"message": "Đã thêm vào hàng chờ tải"
|
||||
},
|
||||
"app.install.phase.preparing_java": {
|
||||
"message": "Đang chuẩn bị Java"
|
||||
},
|
||||
"app.install.phase.preparing_java.downloading": {
|
||||
"message": "Đang tải Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.extracting": {
|
||||
"message": "Trích xuất Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.fetching-metadata": {
|
||||
"message": "Đang tìm Java {version}"
|
||||
},
|
||||
"app.install.phase.preparing_java.resolving": {
|
||||
"message": "Đang chuẩn bị Java {version}"
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "Tất cả dữ liệu trong gói hồ sơ này sẽ bị xoá, bao gồm thế giới của bạn, cấu hình, và tất cả nội dung đã được tải xuống."
|
||||
},
|
||||
@@ -290,9 +398,6 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "Tìm kiếm {count} world..."
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"message": "Ngừng tải"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "Tải xuống để chơi"
|
||||
},
|
||||
@@ -317,9 +422,6 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "Đã bỏ"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "Bạn cần cập nhật {name} để có thể chơi. Vui lòng cập nhật lên bản mới nhất để khởi chạy trò chơi."
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "Dự án này đã được cài đặt"
|
||||
},
|
||||
@@ -329,6 +431,18 @@
|
||||
"app.project.install-context.back-to-browse": {
|
||||
"message": "Quay lại trang Khám Phá"
|
||||
},
|
||||
"app.project.version.all-versions": {
|
||||
"message": "Tất cả phiên bản"
|
||||
},
|
||||
"app.project.version.download-in-browser": {
|
||||
"message": "Tải trong trình duyệt"
|
||||
},
|
||||
"app.project.version.installing": {
|
||||
"message": "Đang tải"
|
||||
},
|
||||
"app.project.versions.already-installed": {
|
||||
"message": "Đã có sẵn"
|
||||
},
|
||||
"app.settings.developer-mode-enabled": {
|
||||
"message": "Chế độ nhà phát triển đã được bật."
|
||||
},
|
||||
|
||||
@@ -89,6 +89,9 @@
|
||||
"app.action-bar.install.unknown-instance": {
|
||||
"message": "未知的实例"
|
||||
},
|
||||
"app.action-bar.install.updating-shared-content": {
|
||||
"message": "更新共享内容"
|
||||
},
|
||||
"app.action-bar.installs": {
|
||||
"message": "安装"
|
||||
},
|
||||
@@ -125,6 +128,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "查看日志"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "全部接受"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "广告使 Modrinth 得以运营,并为创作者报酬提供资金支持。我们的合作伙伴可能会在应用中存储或访问 Cookie,以便实现广告个性化和效果衡量。"
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "管理偏好设置"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "全部拒绝"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "您的隐私以及广告如何支持 Modrinth"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "启用模糊效果等高级渲染。可能会在没有硬件加速渲染的情况下造成性能问题。"
|
||||
},
|
||||
@@ -323,6 +341,36 @@
|
||||
"app.install.phase.running_loader_processors": {
|
||||
"message": "正在运行加载处理器"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.added-label": {
|
||||
"message": "新增内容"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-body": {
|
||||
"message": "本地实例有尚未同步给其他用户的更改。"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.changes-header": {
|
||||
"message": "本地更改尚未发布分享"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publish-button": {
|
||||
"message": "推送更新"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.publishing-button": {
|
||||
"message": "推送中……"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.removed-label": {
|
||||
"message": "移除内容"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-admonition-header": {
|
||||
"message": "推送更新"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-description": {
|
||||
"message": "预览即将同步给所有使用该实例用户的变更内容。"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.review-header": {
|
||||
"message": "审核变更"
|
||||
},
|
||||
"app.instance.admonitions.shared-instance.reviewing-button": {
|
||||
"message": "正在审核……"
|
||||
},
|
||||
"app.instance.confirm-delete.admonition-body": {
|
||||
"message": "你实例的所有数据将被永久删除,包括你的世界、配置和所有已安装的内容。"
|
||||
},
|
||||
@@ -359,6 +407,9 @@
|
||||
"app.instance.mods.content-type-project": {
|
||||
"message": "项目"
|
||||
},
|
||||
"app.instance.mods.locked-content": {
|
||||
"message": "已锁定实例中的内容无法修改。"
|
||||
},
|
||||
"app.instance.mods.project-was-added": {
|
||||
"message": "已添加 “{name}”"
|
||||
},
|
||||
@@ -374,6 +425,102 @@
|
||||
"app.instance.mods.successfully-uploaded": {
|
||||
"message": "上传成功"
|
||||
},
|
||||
"app.instance.share.empty.description": {
|
||||
"message": "你可以将此实例分享给你的好友!"
|
||||
},
|
||||
"app.instance.share.empty.heading": {
|
||||
"message": "没有邀请好友"
|
||||
},
|
||||
"app.instance.share.empty.invite-friends-button": {
|
||||
"message": "邀请好友"
|
||||
},
|
||||
"app.instance.share.invite-modal.heading": {
|
||||
"message": "分享 {name}"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-prefix": {
|
||||
"message": "你需要登录账号"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-suffix": {
|
||||
"message": "才能访问此页面。"
|
||||
},
|
||||
"app.instance.share.locked.linked-account-fallback": {
|
||||
"message": "已关联的账号"
|
||||
},
|
||||
"app.instance.share.locked.signed-out-heading": {
|
||||
"message": "未登录"
|
||||
},
|
||||
"app.instance.share.locked.switch-account-button": {
|
||||
"message": "切换账号"
|
||||
},
|
||||
"app.instance.share.locked.wrong-account-heading": {
|
||||
"message": "账号不正确"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-access": {
|
||||
"message": "对方将不再收到该共享实例的后续更新"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-installed-copy": {
|
||||
"message": "对方已安装的副本仍将保留在其设备上"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-invite-again": {
|
||||
"message": "你可以稍后仍可以再邀请对方"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effect-last-user": {
|
||||
"message": "这是最后一位共享成员,移除后将关闭此实例的共享"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effects-label": {
|
||||
"message": "这会产生什么影响?"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.header": {
|
||||
"message": "撤销访问权限"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.remove-button": {
|
||||
"message": "撤销访问权限"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.user-avatar-alt": {
|
||||
"message": "{username} 的头像"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.warning-body": {
|
||||
"message": "若撤销 {username} 对该共享实例的访问权限,你需要重新向其发送邀请才能使其接收后续更新。"
|
||||
},
|
||||
"app.instance.share.sign-in.button": {
|
||||
"message": "登录"
|
||||
},
|
||||
"app.instance.share.unlink.body": {
|
||||
"message": "你必须先取消关联此整合包才能分享你的实例"
|
||||
},
|
||||
"app.instance.share.unlink.header": {
|
||||
"message": "分享前需要取消关联"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.body": {
|
||||
"message": "本地已安装该共享实例,名称为 <bold>{instanceName}</bold>。确定要再安装一份吗?"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.header": {
|
||||
"message": "共享实例已安装"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.install-anyway": {
|
||||
"message": "仍要安装"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.instance": {
|
||||
"message": "实例"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.fallback-username": {
|
||||
"message": "已关联的账号"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.owner-admonition-body-v2": {
|
||||
"message": "才能管理此共享实例。否则你将无法向其他用户推送更新。"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.sign-in-as-label": {
|
||||
"message": "登录账号"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.signed-out-header": {
|
||||
"message": "你需要登录 Modrinth"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.user-admonition-body-v2": {
|
||||
"message": "才能接收此共享实例的更新。"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.warning-header": {
|
||||
"message": "你当前使用的 Modrinth 账号不正确"
|
||||
},
|
||||
"app.instance.worlds.add-server": {
|
||||
"message": "添加服务器"
|
||||
},
|
||||
@@ -425,8 +572,20 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "搜索 {count} 个世界……"
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"message": "不要安装"
|
||||
"app.modal.install-to-play.additional-context": {
|
||||
"message": "补充说明"
|
||||
},
|
||||
"app.modal.install-to-play.additional-context-placeholder": {
|
||||
"message": "如有必要,请尽量附上相关链接与图片"
|
||||
},
|
||||
"app.modal.install-to-play.content-you-are-reporting": {
|
||||
"message": "所举报的实例"
|
||||
},
|
||||
"app.modal.install-to-play.delete-instance": {
|
||||
"message": "删除实例"
|
||||
},
|
||||
"app.modal.install-to-play.external-files-dont-install": {
|
||||
"message": "请勿安装"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
"message": "安装以游玩"
|
||||
@@ -443,12 +602,51 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count} 个模组"
|
||||
},
|
||||
"app.modal.install-to-play.report-description": {
|
||||
"message": "请使用此表单举报违反我们<rules-link>规则</rules-link>和<terms-link>使用条款</terms-link>的实例。"
|
||||
},
|
||||
"app.modal.install-to-play.report-image-invalid-type": {
|
||||
"message": "不支持的图片格式"
|
||||
},
|
||||
"app.modal.install-to-play.report-image-too-large": {
|
||||
"message": "文件大小超出 1 MiB 限制"
|
||||
},
|
||||
"app.modal.install-to-play.report-legal-claims": {
|
||||
"message": "如需提交 DMCA 通知或其他法律诉求,请参阅我们的<copyright-link>版权政策</copyright-link>。"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason": {
|
||||
"message": "该实例违反了哪项规则?"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.inappropriate": {
|
||||
"message": "不当内容"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.malicious": {
|
||||
"message": "恶意内容"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.spam": {
|
||||
"message": "垃圾内容"
|
||||
},
|
||||
"app.modal.install-to-play.report-shared-instance-header": {
|
||||
"message": "举报共享实例"
|
||||
},
|
||||
"app.modal.install-to-play.report-submitted": {
|
||||
"message": "举报已提交"
|
||||
},
|
||||
"app.modal.install-to-play.report-support-and-bugs": {
|
||||
"message": "为了寻求支持,请咨询我们的<support-link>支持团队</support-link>为了发漏洞请进开启我们的一个<github-link>github-漏洞报告</github-link>。"
|
||||
},
|
||||
"app.modal.install-to-play.reviewed-files": {
|
||||
"message": "只有上传到 Modrinth 的文件才会经过审核,无论其文件格式如何(包括 .mrpack)。"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance": {
|
||||
"message": "共享实例"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance-content": {
|
||||
"message": "共享的实例"
|
||||
},
|
||||
"app.modal.install-to-play.shared-instance-unknown-files-description": {
|
||||
"message": "这实例里面有东西没有在modrinth。我们真的建议只安装你信任的文件源。"
|
||||
},
|
||||
"app.modal.install-to-play.unknown-files-description": {
|
||||
"message": "这个整合包包含一些未在 Modrinth 发布的文件。我们强烈建议只从你信任的来源安装文件。"
|
||||
},
|
||||
@@ -467,8 +665,23 @@
|
||||
"app.modal.update-to-play.removed": {
|
||||
"message": "已移除"
|
||||
},
|
||||
"app.modal.update-to-play.server-modpack-unknown-files-description": {
|
||||
"message": "这服务器里面的模组有些不在modrinth。我们真的建议只安装你信任的文件源。"
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-added-label": {
|
||||
"message": "被加入的"
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-removed-label": {
|
||||
"message": "被删除的"
|
||||
},
|
||||
"app.modal.update-to-play.shared-instance-unknown-files-description": {
|
||||
"message": "这分享实例里面有东西没有在modrinth。我们真的建议只安装你信任的文件源。"
|
||||
},
|
||||
"app.modal.update-to-play.update-required": {
|
||||
"message": "需要更新"
|
||||
},
|
||||
"app.modal.update-to-play.update-required-description": {
|
||||
"message": "需要更新至最新版本才能运行 {name}。请更新后启动游戏。"
|
||||
"message": "为了玩{name}你需要更新。"
|
||||
},
|
||||
"app.project.install-button.already-installed": {
|
||||
"message": "此项目已安装"
|
||||
@@ -497,6 +710,9 @@
|
||||
"app.settings.downloading": {
|
||||
"message": "正在下载 v{version}"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "广告使 Modrinth 得以运营,并为创作者报酬提供资金支持。我们的合作伙伴可能会在应用中存储或访问 Cookie,以便实现广告个性化和效果衡量。您可以在下方选择退出或管理您的偏好设置。"
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "外观"
|
||||
},
|
||||
@@ -539,6 +755,9 @@
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "处理文件时出错"
|
||||
},
|
||||
"app.skins.ears-feature-notice": {
|
||||
"message": "此皮肤使用了 {ears} 模组的功能特性"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "编辑皮肤"
|
||||
},
|
||||
@@ -665,6 +884,12 @@
|
||||
"app.skins.title": {
|
||||
"message": "皮肤选择器"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "切换至关"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "切换至开"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Modrinth App v{version} 更新已下载完成!立即重启更新,或退出时自动安装。"
|
||||
},
|
||||
@@ -713,6 +938,39 @@
|
||||
"app.world.world-item.players-online": {
|
||||
"message": "{count} 人在线"
|
||||
},
|
||||
"content.shared-instance.change-version-body": {
|
||||
"message": "更改版本只会修改你的本地副本。未来的共享实例更新可能会再次将其恢复或更改。"
|
||||
},
|
||||
"content.shared-instance.delete-bulk-body": {
|
||||
"message": "部分选中的项目属于共享实例的一部分。删除它们只会修改你的本地副本,未来的共享实例更新可能会再次将其恢复或更改。"
|
||||
},
|
||||
"content.shared-instance.delete-button": {
|
||||
"message": "就要删除"
|
||||
},
|
||||
"content.shared-instance.delete-many-button": {
|
||||
"message": "就要删除{count, number}"
|
||||
},
|
||||
"content.shared-instance.delete-single-body": {
|
||||
"message": "删除它只会修改你的本地副本。未来的共享实例更新可能会再次将其恢复或更改。"
|
||||
},
|
||||
"content.shared-instance.disable-bulk-body": {
|
||||
"message": "部分选中的项目属于共享实例的一部分。禁用它们只会修改你的本地副本,未来的共享实例更新可能会再次重新启用、恢复或更改它们。"
|
||||
},
|
||||
"content.shared-instance.disable-button": {
|
||||
"message": "坚持禁用"
|
||||
},
|
||||
"content.shared-instance.disable-many-button": {
|
||||
"message": "坚持禁用这 {count, number} 个项目"
|
||||
},
|
||||
"content.shared-instance.disable-single-body": {
|
||||
"message": "禁用它只会修改你的本地副本。未来的共享实例更新可能会再次将其启用、恢复或更改。"
|
||||
},
|
||||
"content.shared-instance.unlink-body": {
|
||||
"message": "解除关联只会修改你的本地副本。未来的共享实例更新可能会再次将其恢复或更改。"
|
||||
},
|
||||
"content.shared-instance.warning-header": {
|
||||
"message": "这是共享实例的一部分"
|
||||
},
|
||||
"friends.action.add-friend": {
|
||||
"message": "添加好友"
|
||||
},
|
||||
@@ -776,6 +1034,75 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "登录你的 <link>Modrinth 账号</link>,添加好友,看看他们在玩什么!"
|
||||
},
|
||||
"installation-settings.shared-instance.linked-title": {
|
||||
"message": "已关联的共享实例"
|
||||
},
|
||||
"installation-settings.shared-instance.title": {
|
||||
"message": "取消发布实例"
|
||||
},
|
||||
"installation-settings.shared-instance.unlink-button": {
|
||||
"message": "解除共享实例关联"
|
||||
},
|
||||
"installation-settings.shared-instance.unlink-description": {
|
||||
"message": "断开此本地实例与未来共享更新的连接。"
|
||||
},
|
||||
"installation-settings.shared-instance.unlinking-button": {
|
||||
"message": "正在解除关联……"
|
||||
},
|
||||
"installation-settings.shared-instance.unpublish-button": {
|
||||
"message": "取消发布共享实例"
|
||||
},
|
||||
"installation-settings.shared-instance.unpublish-description": {
|
||||
"message": "从Modrinth移除这个分享实例,同时停止发送新的更新到正在使用它的人,你的本地实例不会被影响。"
|
||||
},
|
||||
"installation-settings.shared-instance.unpublishing-button": {
|
||||
"message": "取消发布中……"
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.admonition-body": {
|
||||
"message": "这只会影响到你的本地实例,你安装过的内容依然会在你的设备上保留,被其他人使用的分享实例也不会被影响。"
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.admonition-header": {
|
||||
"message": "解除共享实例关联"
|
||||
},
|
||||
"installation-settings.unlink-shared-instance.modal.header": {
|
||||
"message": "解除共享实例关联"
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.admonition-body": {
|
||||
"message": "这将从 Modrinth 服务器上删除该共享实例。在 Modrinth App 中使用它的用户将停止接收更新,但你的本地实例及其内容仍会保留在此设备上。"
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.admonition-header": {
|
||||
"message": "取消发布共享实例"
|
||||
},
|
||||
"installation-settings.unpublish-shared-instance.modal.header": {
|
||||
"message": "取消发布共享实例"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "创建快捷方式"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "导出整合包"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "启动实例"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "更多操作"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "打开文件夹"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "修复"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "实例设置"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "正在启动……"
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "正在停止……"
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "添加并游玩"
|
||||
},
|
||||
@@ -818,6 +1145,15 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "保存为……"
|
||||
},
|
||||
"instance.locked.delete-button": {
|
||||
"message": "删除实例"
|
||||
},
|
||||
"instance.locked.play-tooltip": {
|
||||
"message": "此实例已被锁定"
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "从未玩过"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "地址"
|
||||
},
|
||||
@@ -891,13 +1227,13 @@
|
||||
"message": "Alpha 测试版"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.alpha.description": {
|
||||
"message": "正式版,beta 和 alpha 测试版会被显示为可用更新。"
|
||||
"message": "正式版、beta 和 alpha 版本会显示为可用更新。"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.beta": {
|
||||
"message": "Beta 测试版"
|
||||
"message": "Beta"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.beta.description": {
|
||||
"message": "正式版和 beta 测试版会被显示为可用更新。"
|
||||
"message": "正式版和 beta 版本会被显示为可用更新。"
|
||||
},
|
||||
"instance.settings.tabs.general.update-channel.release": {
|
||||
"message": "正式版"
|
||||
@@ -953,6 +1289,9 @@
|
||||
"instance.settings.tabs.installation.loader-version": {
|
||||
"message": "{loader} 版本"
|
||||
},
|
||||
"instance.settings.tabs.installation.locked": {
|
||||
"message": "当实例被锁定时,安装设置不可用。"
|
||||
},
|
||||
"instance.settings.tabs.java": {
|
||||
"message": "Java 及内存"
|
||||
},
|
||||
@@ -992,6 +1331,9 @@
|
||||
"instance.settings.tabs.java.java-path-placeholder": {
|
||||
"message": "/path/to/java"
|
||||
},
|
||||
"instance.settings.tabs.sharing": {
|
||||
"message": "共享"
|
||||
},
|
||||
"instance.settings.tabs.window": {
|
||||
"message": "游戏窗口"
|
||||
},
|
||||
@@ -1022,6 +1364,57 @@
|
||||
"instance.settings.tabs.window.width.enter": {
|
||||
"message": "输入宽度……"
|
||||
},
|
||||
"instance.shared-instance.error.title": {
|
||||
"message": "出错了"
|
||||
},
|
||||
"instance.shared-instance.owner-tooltip": {
|
||||
"message": "此实例的内容正在共享给其他用户。"
|
||||
},
|
||||
"instance.shared-instance.publish-review.added-label": {
|
||||
"message": "新增"
|
||||
},
|
||||
"instance.shared-instance.publish-review.admonition-header": {
|
||||
"message": "向玩家推送更新"
|
||||
},
|
||||
"instance.shared-instance.publish-review.config-title-v2": {
|
||||
"message": "预览内容变更,并选择要在本次更新中包含的配置文件"
|
||||
},
|
||||
"instance.shared-instance.publish-review.description": {
|
||||
"message": "审核哪些内容做了更改,并选择你想要包含在这次更新的的配置文件。"
|
||||
},
|
||||
"instance.shared-instance.publish-review.header": {
|
||||
"message": "审核更改内容"
|
||||
},
|
||||
"instance.shared-instance.publish-review.publish-button": {
|
||||
"message": "推送更新"
|
||||
},
|
||||
"instance.shared-instance.publish-review.removed-label": {
|
||||
"message": "已移除"
|
||||
},
|
||||
"instance.shared-instance.tooltip": {
|
||||
"message": "此实例的内容正由他人管理。"
|
||||
},
|
||||
"instance.shared-instance.unavailable.access-revoked-text": {
|
||||
"message": "你对此共享实例的访问权限已被撤销。该实例仍可正常使用,但已解除关联且不再接收后续更新。"
|
||||
},
|
||||
"instance.shared-instance.unavailable.deleted-text": {
|
||||
"message": "源实例已被删除。该实例仍可正常使用,但已解除关联且不再接收后续更新。"
|
||||
},
|
||||
"instance.shared-instance.unavailable.locked-text": {
|
||||
"message": "此共享实例已被内容审核团队锁定。它将不再接收主实例的更新,且无法继续游玩。"
|
||||
},
|
||||
"instance.shared-instance.unavailable.locked-title": {
|
||||
"message": "实例已锁定"
|
||||
},
|
||||
"instance.shared-instance.unavailable.manager-fallback": {
|
||||
"message": "该实例的管理者"
|
||||
},
|
||||
"instance.shared-instance.unavailable.text": {
|
||||
"message": "你的本地实例仍可正常使用,但已解除关联且不再接收后续更新。"
|
||||
},
|
||||
"instance.shared-instance.unavailable.title": {
|
||||
"message": "共享实例不再可用"
|
||||
},
|
||||
"instance.worlds.a_minecraft_server": {
|
||||
"message": "Minecraft 服务器"
|
||||
},
|
||||
@@ -1085,6 +1478,63 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "登录 Minecraft"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "你需要先登录拥有 Minecraft 的 Microsoft 账户,然后才能启动游戏。"
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "请登录 Microsoft 账户"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "没有账户?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "获取 Minecraft"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "获取支持"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "需要 Minecraft"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "登录 Microsoft 账户"
|
||||
},
|
||||
"modal.modrinth-account-required.browser-description": {
|
||||
"message": "一个新的标签页已打开,你需要在那里完成登录,然后回到Modrinth app。"
|
||||
},
|
||||
"modal.modrinth-account-required.cancel-button": {
|
||||
"message": "取消"
|
||||
},
|
||||
"modal.modrinth-account-required.continue-in-browser-heading": {
|
||||
"message": "请在你的浏览器中继续"
|
||||
},
|
||||
"modal.modrinth-account-required.create-account-button": {
|
||||
"message": "创建账户"
|
||||
},
|
||||
"modal.modrinth-account-required.description": {
|
||||
"message": "在使用这个功能之前,你需要登入你的Modrinth账户。"
|
||||
},
|
||||
"modal.modrinth-account-required.header": {
|
||||
"message": "需要账户"
|
||||
},
|
||||
"modal.modrinth-account-required.open-browser-again-button": {
|
||||
"message": "再次开启浏览器"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-button": {
|
||||
"message": "登录 Modrinth"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-heading": {
|
||||
"message": "登录 Modrinth 账号"
|
||||
},
|
||||
"modal.modrinth-account-required.signing-in-header": {
|
||||
"message": "正在登录"
|
||||
},
|
||||
"modal.modrinth-account-required.support-prompt": {
|
||||
"message": "在登录时遇到困难?<support>获取帮助</support>"
|
||||
},
|
||||
"modal.modrinth-account-required.waiting-for-browser": {
|
||||
"message": "等待浏览器确认……"
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "由该实例提供"
|
||||
},
|
||||
|
||||
@@ -69,7 +69,7 @@
|
||||
"message": "無法設定載入器"
|
||||
},
|
||||
"app.action-bar.install.summary.local-data-error": {
|
||||
"message": "無法更新本地資料"
|
||||
"message": "無法更新本機資料"
|
||||
},
|
||||
"app.action-bar.install.summary.minecraft-setup-failed": {
|
||||
"message": "無法設定 Minecraft"
|
||||
@@ -125,6 +125,21 @@
|
||||
"app.action-bar.view-logs": {
|
||||
"message": "查看紀錄"
|
||||
},
|
||||
"app.ads-consent.accept": {
|
||||
"message": "全部接受"
|
||||
},
|
||||
"app.ads-consent.body": {
|
||||
"message": "廣告使 Modrinth 得以營運,並為創作者提供收益。我們的合作夥伴可能會在應用程式中儲存或存取 Cookie,以實現個人化廣告並衡量廣告成效。"
|
||||
},
|
||||
"app.ads-consent.manage": {
|
||||
"message": "管理偏好設定"
|
||||
},
|
||||
"app.ads-consent.reject": {
|
||||
"message": "全部拒絕"
|
||||
},
|
||||
"app.ads-consent.title": {
|
||||
"message": "關於你的隱私,以及廣告如何幫助 Modrinth"
|
||||
},
|
||||
"app.appearance-settings.advanced-rendering.description": {
|
||||
"message": "啟用進階繪製(如模糊效果),若無硬體加速可能會導致效能問題。"
|
||||
},
|
||||
@@ -168,7 +183,7 @@
|
||||
"message": "最小化啟動器"
|
||||
},
|
||||
"app.appearance-settings.native-decorations.description": {
|
||||
"message": "使用系統內建的視窗外框(需要重啟應用程式)。"
|
||||
"message": "使用系統內建的視窗外框(需要重新啟動應用程式)。"
|
||||
},
|
||||
"app.appearance-settings.native-decorations.title": {
|
||||
"message": "原生視窗"
|
||||
@@ -249,7 +264,7 @@
|
||||
"message": "沒有符合 {compatibilityLabel} 的可用版本。請選擇一個版本強制安裝。不會自動安裝相依模組。"
|
||||
},
|
||||
"app.export-modal.description-placeholder": {
|
||||
"message": "輸入模組包描述……"
|
||||
"message": "輸入模組包描述..."
|
||||
},
|
||||
"app.export-modal.export-button": {
|
||||
"message": "匯出"
|
||||
@@ -374,6 +389,48 @@
|
||||
"app.instance.mods.successfully-uploaded": {
|
||||
"message": "已成功上傳"
|
||||
},
|
||||
"app.instance.share.empty.invite-friends-button": {
|
||||
"message": "邀請好友"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-prefix": {
|
||||
"message": "你需要以"
|
||||
},
|
||||
"app.instance.share.locked.empty-description-suffix": {
|
||||
"message": "登入才能存取這個頁面。"
|
||||
},
|
||||
"app.instance.share.locked.linked-account-fallback": {
|
||||
"message": "已連結的帳號"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.effects-label": {
|
||||
"message": "會發生什麼事?"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.header": {
|
||||
"message": "撤銷存取權"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.remove-button": {
|
||||
"message": "撤銷存取權"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.user-avatar-alt": {
|
||||
"message": "{username} 的顯示圖片"
|
||||
},
|
||||
"app.instance.share.remove-user-modal.warning-body": {
|
||||
"message": "如果你撤銷了 {username} 對這個共用實例的存取權,你需要重新邀請他,他才會收到更新。"
|
||||
},
|
||||
"app.instance.share.sign-in.button": {
|
||||
"message": "登入"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.install-anyway": {
|
||||
"message": "仍要安裝"
|
||||
},
|
||||
"app.instance.shared-instance-already-installed.instance": {
|
||||
"message": "實例"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.fallback-username": {
|
||||
"message": "已連結的帳號"
|
||||
},
|
||||
"app.instance.shared-instance-wrong-account.signed-out-header": {
|
||||
"message": "你需要登入 Modrinth"
|
||||
},
|
||||
"app.instance.worlds.add-server": {
|
||||
"message": "新增伺服器"
|
||||
},
|
||||
@@ -387,10 +444,10 @@
|
||||
"message": "刪除世界"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-body": {
|
||||
"message": "這個世界將會被永久刪除,此操作無法復原。"
|
||||
"message": "這個世界將從這個實例永久刪除,這項動作無法復原。"
|
||||
},
|
||||
"app.instance.worlds.delete-world-modal.warning-header": {
|
||||
"message": "即將刪除 {name}"
|
||||
"message": "即將刪除「{name}」"
|
||||
},
|
||||
"app.instance.worlds.filter-modded": {
|
||||
"message": "模組"
|
||||
@@ -425,7 +482,10 @@
|
||||
"app.instance.worlds.search-worlds-placeholder": {
|
||||
"message": "搜尋 {count} 個世界..."
|
||||
},
|
||||
"app.modal.install-to-play.dont-install": {
|
||||
"app.modal.install-to-play.delete-instance": {
|
||||
"message": "刪除實例"
|
||||
},
|
||||
"app.modal.install-to-play.external-files-dont-install": {
|
||||
"message": "不要安裝"
|
||||
},
|
||||
"app.modal.install-to-play.header": {
|
||||
@@ -443,6 +503,21 @@
|
||||
"app.modal.install-to-play.mod-count": {
|
||||
"message": "{count, plural, other {# 個模組}}"
|
||||
},
|
||||
"app.modal.install-to-play.report-image-invalid-type": {
|
||||
"message": "不支援的圖片格式"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason": {
|
||||
"message": "這個實例違反了哪一條規則?"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.inappropriate": {
|
||||
"message": "不恰當內容"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.malicious": {
|
||||
"message": "惡意內容"
|
||||
},
|
||||
"app.modal.install-to-play.report-reason.spam": {
|
||||
"message": "垃圾內容"
|
||||
},
|
||||
"app.modal.install-to-play.reviewed-files": {
|
||||
"message": "只有在 Modrinth 上發布的檔案才會經過審查,無論其檔案格式為何(包含 .mrpack)。"
|
||||
},
|
||||
@@ -497,6 +572,9 @@
|
||||
"app.settings.downloading": {
|
||||
"message": "正在下載 v{version}"
|
||||
},
|
||||
"app.settings.privacy.ads-consent.intro": {
|
||||
"message": "廣告使 Modrinth 得以營運,並為創作者提供收益。我們的合作夥伴可能會在應用程式中儲存或存取 Cookie,以實現個人化廣告並衡量廣告成效。你可以在下方選擇退出或管理偏好設定。"
|
||||
},
|
||||
"app.settings.tabs.appearance": {
|
||||
"message": "外觀"
|
||||
},
|
||||
@@ -539,6 +617,9 @@
|
||||
"app.skins.dropped-file-error.title": {
|
||||
"message": "處理檔案時發生錯誤"
|
||||
},
|
||||
"app.skins.ears-feature-notice": {
|
||||
"message": "這個外觀使用了 {ears} 模組的功能"
|
||||
},
|
||||
"app.skins.edit-button": {
|
||||
"message": "編輯外觀"
|
||||
},
|
||||
@@ -665,6 +746,12 @@
|
||||
"app.skins.title": {
|
||||
"message": "外觀選擇工具"
|
||||
},
|
||||
"app.skins.toggle-ears-features-off": {
|
||||
"message": "關閉"
|
||||
},
|
||||
"app.skins.toggle-ears-features-on": {
|
||||
"message": "開啟"
|
||||
},
|
||||
"app.update-popup.body.download-complete": {
|
||||
"message": "Modrinth App v{version} 已完成下載!立即重新載入以更新,或在關閉 Modrinth App 時自動更新。"
|
||||
},
|
||||
@@ -713,6 +800,9 @@
|
||||
"app.world.world-item.players-online": {
|
||||
"message": "{count} 人在線上"
|
||||
},
|
||||
"content.shared-instance.delete-button": {
|
||||
"message": "仍要刪除"
|
||||
},
|
||||
"friends.action.add-friend": {
|
||||
"message": "新增好友"
|
||||
},
|
||||
@@ -776,6 +866,33 @@
|
||||
"friends.sign-in-to-add-friends": {
|
||||
"message": "<link>登入 Modrinth 帳號</link>即可新增好友並查看他們正在玩什麼!"
|
||||
},
|
||||
"instance.action.create-shortcut": {
|
||||
"message": "建立捷徑"
|
||||
},
|
||||
"instance.action.export-modpack": {
|
||||
"message": "匯出模組包"
|
||||
},
|
||||
"instance.action.launch-instance": {
|
||||
"message": "啟動實例"
|
||||
},
|
||||
"instance.action.more-actions": {
|
||||
"message": "更多動作"
|
||||
},
|
||||
"instance.action.open-folder": {
|
||||
"message": "開啟資料夾"
|
||||
},
|
||||
"instance.action.repair": {
|
||||
"message": "修復"
|
||||
},
|
||||
"instance.action.settings": {
|
||||
"message": "實例設定"
|
||||
},
|
||||
"instance.action.starting": {
|
||||
"message": "正在啟動..."
|
||||
},
|
||||
"instance.action.stopping": {
|
||||
"message": "正在停止..."
|
||||
},
|
||||
"instance.add-server.add-and-play": {
|
||||
"message": "新增並遊玩"
|
||||
},
|
||||
@@ -818,6 +935,12 @@
|
||||
"instance.files.save-as": {
|
||||
"message": "另存新檔..."
|
||||
},
|
||||
"instance.locked.delete-button": {
|
||||
"message": "刪除實例"
|
||||
},
|
||||
"instance.playtime.never-played": {
|
||||
"message": "從未遊玩"
|
||||
},
|
||||
"instance.server-modal.address": {
|
||||
"message": "位址"
|
||||
},
|
||||
@@ -1059,7 +1182,7 @@
|
||||
"message": "你只能在 Minecraft 1.20 以上版本直接進入單人遊戲世界"
|
||||
},
|
||||
"instance.worlds.play_instance": {
|
||||
"message": "遊戲實例"
|
||||
"message": "遊玩實例"
|
||||
},
|
||||
"instance.worlds.view_instance": {
|
||||
"message": "檢視實例"
|
||||
@@ -1085,6 +1208,39 @@
|
||||
"minecraft-account.sign-in": {
|
||||
"message": "登入 Minecraft"
|
||||
},
|
||||
"minecraft-required.description": {
|
||||
"message": "你需要登入擁有 Minecraft 的 Microsoft 帳號才能啟動遊戲。"
|
||||
},
|
||||
"minecraft-required.description-header": {
|
||||
"message": "登入 Microsoft 帳號"
|
||||
},
|
||||
"minecraft-required.dont-have-account": {
|
||||
"message": "還沒有帳號嗎?"
|
||||
},
|
||||
"minecraft-required.get-minecraft": {
|
||||
"message": "取得 Minecraft"
|
||||
},
|
||||
"minecraft-required.get-support": {
|
||||
"message": "取得支援"
|
||||
},
|
||||
"minecraft-required.header": {
|
||||
"message": "需要 Minecraft"
|
||||
},
|
||||
"minecraft-required.sign-in": {
|
||||
"message": "登入 Microsoft"
|
||||
},
|
||||
"modal.modrinth-account-required.cancel-button": {
|
||||
"message": "取消"
|
||||
},
|
||||
"modal.modrinth-account-required.create-account-button": {
|
||||
"message": "建立帳號"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-button": {
|
||||
"message": "登入 Modrinth"
|
||||
},
|
||||
"modal.modrinth-account-required.sign-in-heading": {
|
||||
"message": "登入 Modrinth 帳號"
|
||||
},
|
||||
"search.filter.locked.instance": {
|
||||
"message": "由該實例提供"
|
||||
},
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user