Compare commits

..
Author SHA1 Message Date
aecsocket 0f8da58745 tombi 2026-04-16 13:06:32 +01:00
aecsocket 108ac8032c Improve directory moving error messages 2026-04-15 14:16:01 +01:00
aecsocket 1271de47b5 Fix canceling app directory change 2026-04-15 14:16:00 +01:00
815 changed files with 20034 additions and 73018 deletions
@@ -22,5 +22,4 @@ Refer to the standards: @standards/frontend/CROSS_PLATFORM_PAGES.md and @standar
- Move the page component into `packages/ui/src/layouts/wrapped/` matching the route structure.
- Replace any platform-specific imports with shared utilities.
- Import and render the wrapped page from both frontends as a simple component.
- If the layout uses TanStack Query for initial route paint with `ReadyTransition` / `useReadyState`, each platform route shell must call `ensureQueryData` for those queries with matching keys and fetchers — see **Platform route shells: prefetch with `ensureQueryData`** in `standards/frontend/CROSS_PLATFORM_PAGES.md`.
6. **Verify** the page renders correctly by checking for missing imports and that all DI contracts are satisfied.
-36
View File
@@ -1,36 +0,0 @@
---
name: review-changelog
description: Review the latest changelog entry in packages/blog/changelog.ts against the project's changelog style guide and flag bullets that need rewriting. Use when checking a freshly added changelog entry before opening a PR, or when the user asks to review/lint the latest changelog.
argument-hint: [product?]
---
Refer to the standard: @standards/maintaining/CHANGELOG.md
## Steps
1. **Locate the latest entry:**
- Open `packages/blog/changelog.ts`.
- The latest entries are at the top of the `VERSIONS` array.
- If `$ARGUMENTS` specifies a product (`web`, `hosting`, `app`), review the most recent entry for that product. Otherwise, review the most recent entry overall, plus any sibling entries sharing the same `date` (coordinated releases ship together).
2. **Read the standard above** in full before reviewing. The bullet rules, section/verb agreement, and "Don't" list are the source of truth.
3. **Check the entry shell:**
- `date` is a valid ISO 8601 timestamp.
- `product` is one of `web`, `hosting`, `app`.
- `version` is present for `app` entries and omitted for `web`/`hosting`.
- Section headings use `## Added`, `## Changed`, `## Fixed`, `## Security` (or a featured-release linked heading). Flag legacy `## Improvements`.
4. **Review each bullet** against the standard. For each bullet, check:
- Voice/tense matches the section heading.
- Opening verb agrees with its section.
- Describes observable behavior, not implementation.
- Specific enough to identify the surface (names the tab/page/modal).
- One sentence, ends with a period, sentence case.
- Uses branded names (Modrinth App, Modrinth Hosting) correctly.
- No filler ("issue with", "issue where", "various", "some"), no vague intensifiers, no apologies, no PR/commit references (unless crediting a third-party contributor with a linked GitHub profile).
- Not a duplicate sub-fix of a bigger change already listed.
5. **Report findings** as a short list grouped by entry. For each problem bullet, show the original line and a suggested rewrite. If the entry is clean, say so explicitly. Do not edit the file unless the user asks - this skill is a review pass, not a rewrite pass.
6. **If the user then asks to apply fixes**, edit `packages/blog/changelog.ts` directly using the suggested rewrites. Preserve tab indentation and template literal formatting.
-171
View File
@@ -1,171 +0,0 @@
# MIT License
#
# Copyright (c) 2024 CARIAD SE
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
name: 'Merge Queue CI Check Skipper'
description: 'Outputs `skip-check` as `true` if this is running as part of merge queue checks and the same checks have already been executed in the PR itself.'
inputs:
secret:
description: 'Optional GitHub Secret that can access branch protection rules using the administration:read permission'
required: false
outputs:
skip-check:
description: 'Skip Check (boolean)'
value: ${{ steps.passed-checks.outputs.can-skip-checks }}
runs:
using: 'composite'
steps:
- name: Checkout code
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Extract PR Number and Commit ID
id: extract-pr-info
uses: actions/github-script@v7
with:
script: |
const githubRef = process.env.GITHUB_REF;
const regex = /^refs\/heads\/gh-readonly-queue\/([a-zA-Z0-9.\-_\/]+)\/pr-(\d+)-([a-f0-9]+)$/;
if (regex.test(githubRef)) {
const [, targetBranchName, prNumber, commitId] = githubRef.match(regex);
core.setOutput('targetBranchName', targetBranchName);
core.setOutput('prNumber', prNumber);
core.setOutput('commitId', commitId);
} else {
console.log(`GITHUB_REF is not a merge queue ref, setting CAN_SKIP_CHECKS to false: ${githubRef}`);
core.exportVariable('CAN_SKIP_CHECKS', 'false');
}
- name: Print PR Number and Target Commit ID
if: env.CAN_SKIP_CHECKS != 'false'
shell: bash
run: |
echo "Target Branch Name: ${{ steps.extract-pr-info.outputs.targetBranchName }}"
echo "PR Number: ${{ steps.extract-pr-info.outputs.prNumber }}"
echo "Target Commit ID: ${{ steps.extract-pr-info.outputs.commitId }}"
- name: Check if merge queue entry was enqueued as head of the queue
if: env.CAN_SKIP_CHECKS != 'false'
shell: bash
run: |
targetBranchHead=$(git rev-parse origin/${{ steps.extract-pr-info.outputs.targetBranchName }})
if [[ "$targetBranchHead" != "${{ steps.extract-pr-info.outputs.commitId }}" ]]; then
echo "'${{ steps.extract-pr-info.outputs.targetBranchName }}' branch commit ID does not match PR commit ID. This Merge Queue run was not head of the queue when it was enqueued. Setting CAN_SKIP_CHECKS to false."
echo "CAN_SKIP_CHECKS=false" >> "$GITHUB_ENV"
else
echo "This merge queue entry is targeting '${{ steps.extract-pr-info.outputs.targetBranchName }}' directly."
fi
- name: Get PR Branch
id: get-pr-branch
if: env.CAN_SKIP_CHECKS != 'false'
shell: bash
env:
GH_TOKEN: ${{ github.token }}
run: |
prNumber=${{ steps.extract-pr-info.outputs.prNumber }}
branchName=$(gh pr view ${prNumber} --json headRefName -q '.headRefName')
echo "prBranch=$branchName" >> "$GITHUB_OUTPUT"
- name: Print PR Branch
if: env.CAN_SKIP_CHECKS != 'false'
shell: bash
run: |
echo "PR Branch: ${{ steps.get-pr-branch.outputs.prBranch }}"
- name: Check if PR branch contains the Merge Queue target commit ID
if: env.CAN_SKIP_CHECKS != 'false'
shell: bash
run: |
# Get the branch name from previous steps
branch_name="origin/${{ steps.get-pr-branch.outputs.prBranch }}"
commit_id="${{ steps.extract-pr-info.outputs.commitId }}"
# Check if the branch history contains the commit
if git branch -r --contains "$commit_id" | grep -q "$branch_name"; then
echo "Branch '$branch_name' contains commit '$commit_id'. It is up to date with ${{ steps.extract-pr-info.outputs.targetBranchName }}."
else
echo "Branch '$branch_name' does not contain commit '$commit_id'. It is outdated. Setting CAN_SKIP_CHECKS to false."
echo "CAN_SKIP_CHECKS=false" >> "$GITHUB_ENV"
fi
- name: Compare PR Branch with Current Branch
if: env.CAN_SKIP_CHECKS != 'false'
shell: bash
run: |
if git diff --quiet "origin/${{ steps.get-pr-branch.outputs.prBranch }}"; then
echo "No differences found. PR branch is identical with this merge queue branch."
else
echo "Differences detected. PR branch has been updated after PR was added to merge queue. Setting CAN_SKIP_CHECKS to false."
echo "CAN_SKIP_CHECKS=false" >> "$GITHUB_ENV"
fi
- name: Compute/publish skip result
id: passed-checks
uses: actions/github-script@v7
env:
SECRET: ${{ inputs.secret }}
with:
github-token: ${{ inputs.secret != '' && inputs.secret || github.token }}
script: |
if (process.env.CAN_SKIP_CHECKS == "false") {
console.log("Setting CAN_SKIP_CHECKS to false");
core.setOutput("can-skip-checks", false);
return;
}
const secretProvided = !!process.env.SECRET;
if (!secretProvided) {
console.log("secret input not set, assuming all checks have passed. Ensure 'Require status checks to pass before merging' is enabled, or provide a secret with administration:read.");
core.setOutput("can-skip-checks", true);
return;
}
const { data: branchProtection } = await github.rest.repos.getBranchProtection({
owner: context.repo.owner,
repo: context.repo.repo,
branch: "${{ steps.extract-pr-info.outputs.targetBranchName }}",
});
const requiredCheckNames = branchProtection.required_status_checks.contexts;
console.log(`requiredCheckNames = ${requiredCheckNames}`);
const { data: checks } = await github.rest.checks.listForRef({
owner: context.repo.owner,
repo: context.repo.repo,
ref: "refs/heads/${{ steps.get-pr-branch.outputs.prBranch }}",
});
console.log(`checks.check_runs = ${checks.check_runs.map(check => `${check.status},${check.conclusion},${check.name};`)}`);
const nonSuccessfulChecks = checks.check_runs.filter(check => check.status !== "completed" || check.conclusion !== "success");
const nonSuccessfulCheckNames = nonSuccessfulChecks.map(check => check.name);
console.log(`nonSuccessfulCheckNames = ${nonSuccessfulCheckNames}`);
const missingChecks = requiredCheckNames.filter(checkName => nonSuccessfulCheckNames.includes(checkName));
if (missingChecks.length > 0) {
console.log(`Required checks not passed, cannot skip merge queue checks. Setting CAN_SKIP_CHECKS to false. Missing checks: ${missingChecks.join(', ')}`);
core.setOutput("can-skip-checks", false);
} else {
console.log("No missing checks. Setting CAN_SKIP_CHECKS to true.");
core.setOutput("can-skip-checks", true);
}
-125
View File
@@ -1,125 +0,0 @@
name: API client release
on:
push:
branches: [main]
paths:
- .github/workflows/api-client-release.yml
- packages/api-client/**
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: false
permissions:
contents: read
id-token: write
jobs:
release:
if: github.repository_owner == 'modrinth' && github.ref == 'refs/heads/main'
# npm Trusted Publishing requires a GitHub-hosted runner.
runs-on: ubuntu-latest
env:
FORCE_COLOR: 3
PACKAGE_DIR: packages/api-client
PACKAGE_NAME: '@modrinth/api-client'
BUMP_TYPE: minor
steps:
- name: Check out code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
with:
fetch-depth: 0
- name: Check for api-client changes
id: changes
run: |
if [ "${{ github.event.before }}" = "0000000000000000000000000000000000000000" ]; then
echo "changed=true" >> "$GITHUB_OUTPUT"
exit 0
fi
if git diff --quiet "${{ github.event.before }}" "$GITHUB_SHA" -- "$PACKAGE_DIR"; then
echo "changed=false" >> "$GITHUB_OUTPUT"
else
echo "changed=true" >> "$GITHUB_OUTPUT"
fi
- name: Setup Node
if: steps.changes.outputs.changed == 'true'
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
with:
node-version-file: .nvmrc
registry-url: https://registry.npmjs.org
- name: Enable Corepack
if: steps.changes.outputs.changed == 'true'
run: corepack enable
- name: Get pnpm store path
if: steps.changes.outputs.changed == 'true'
id: pnpm-store
run: echo "store-path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"
- name: Restore pnpm cache
if: steps.changes.outputs.changed == 'true'
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ${{ steps.pnpm-store.outputs.store-path }}
key: pnpm-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
pnpm-cache-
- name: Install dependencies
if: steps.changes.outputs.changed == 'true'
run: pnpm install --frozen-lockfile --filter @modrinth/api-client...
- name: Resolve release version
if: steps.changes.outputs.changed == 'true'
id: version
run: |
CURRENT_VERSION_JSON="$(npm view "${PACKAGE_NAME}" version --json)"
CURRENT_VERSION="$(
jq -nr \
--argjson version "$CURRENT_VERSION_JSON" \
'if ($version | type) == "array" then $version[-1] else $version end'
)"
NEXT_VERSION="$(
jq -nr \
--arg version "$CURRENT_VERSION" \
--arg bump "$BUMP_TYPE" '
def semver:
capture("^(?<major>[0-9]+)\\.(?<minor>[0-9]+)\\.(?<patch>[0-9]+)$")
| with_entries(.value |= tonumber);
($version | semver) as $current
| if $bump == "major" then "\($current.major + 1).0.0"
elif $bump == "minor" then "\($current.major).\($current.minor + 1).0"
elif $bump == "patch" then "\($current.major).\($current.minor).\($current.patch + 1)"
else error("Unsupported bump type: \($bump)")
end
'
)"
PACKAGE_JSON="$(mktemp)"
jq --tab --arg version "$NEXT_VERSION" '.version = $version' "$PACKAGE_DIR/package.json" > "$PACKAGE_JSON"
mv "$PACKAGE_JSON" "$PACKAGE_DIR/package.json"
echo "current_version=$CURRENT_VERSION" >> "$GITHUB_OUTPUT"
echo "published_version=$CURRENT_VERSION" >> "$GITHUB_OUTPUT"
echo "version=$NEXT_VERSION" >> "$GITHUB_OUTPUT"
- name: Build api-client
if: steps.changes.outputs.changed == 'true'
run: pnpm --filter @modrinth/api-client build
- name: Check package contents
if: steps.changes.outputs.changed == 'true'
working-directory: packages/api-client
run: pnpm pack --dry-run
- name: Publish api-client
if: steps.changes.outputs.changed == 'true'
working-directory: packages/api-client
run: pnpm publish --access public --provenance --no-git-checks
@@ -1,22 +0,0 @@
name: Cancel PR Workflows on Merge
on:
pull_request_target:
types:
- closed
permissions:
actions: write
jobs:
cancel:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Cancel Previous Runs
uses: styfle/cancel-workflow-action@85880fa0301c86cca9da44039ee3bb12d3bedbfa # 0.12.1
with:
workflow_id: all
access_token: ${{ secrets.GITHUB_TOKEN }}
ignore_sha: true
pr_number: ${{ github.event.pull_request.number }}
+2 -2
View File
@@ -16,8 +16,8 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Post or update changelog comment
uses: actions/github-script@d746ffe35508b1917358783b479e04febd2b8f71 # v9.0.0
- name: 💬 Post or update changelog comment
uses: actions/github-script@v7
with:
github-token: ${{ secrets.CROWDIN_GH_TOKEN }}
script: |
+5 -5
View File
@@ -2,7 +2,7 @@ on:
pull_request:
push:
branches:
- main
- master
env:
CARGO_TERM_COLOR: always
@@ -12,15 +12,15 @@ 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@v4
- uses: crate-ci/typos@v1.43.1
# see <https://github.com/influxdata/datafusion-udf-wasm/pull/275>
tombi:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: taiki-e/install-action@b5fddbb5361bce8a06fb168c9d403a6cc552b084 # v2.75.29
- uses: actions/checkout@v4
- uses: taiki-e/install-action@v2
with:
tool: tombi
- run: tombi lint
+4 -4
View File
@@ -2,7 +2,7 @@ on:
pull_request:
push:
branches:
- main
- master
env:
CARGO_TERM_COLOR: always
@@ -12,8 +12,8 @@ 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@v4
- uses: dtolnay/rust-toolchain@stable
- uses: cargo-bins/cargo-binstall@main
- run: cargo binstall --no-confirm cargo-shear
- run: cargo shear
+18 -117
View File
@@ -3,133 +3,33 @@ name: daedalus-docker-build
on:
push:
branches:
- 'main'
- '**'
paths:
- .github/workflows/daedalus-docker.yml
- 'apps/daedalus_client/**'
- 'packages/daedalus/**'
- Cargo.toml
- Cargo.lock
pull_request:
types: [opened, synchronize]
paths:
- .github/workflows/daedalus-docker.yml
- 'apps/daedalus_client/**'
- 'packages/daedalus/**'
- Cargo.toml
- Cargo.lock
merge_group:
types: [checks_requested]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/prod' }}
jobs:
skip-if-clean:
name: Skip if merge_queue produces no diff
runs-on: ubuntu-latest
outputs:
skip: ${{ steps.check.outputs.skip }}
internal: ${{ steps.check-internal.outputs.internal }}
if: ${{ always() }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Check if workflow runs on an internal branch
id: check-internal
env:
EVENT_NAME: ${{ github.event_name }}
HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
REPO: ${{ github.repository }}
run: |
if [ "$EVENT_NAME" != "pull_request" ] || [ "$HEAD_REPO" = "$REPO" ]; then
echo "internal=true" >> $GITHUB_OUTPUT
else
echo "internal=false" >> $GITHUB_OUTPUT
fi
- name: Merge Queue CI Check Skipper
id: merge-queue-ci-skipper
uses: ./.github/merge-queue-ci-skipper
with:
secret: ${{ secrets.GH_ACCESS_TOKEN }}
- name: Check merge_group synthetic commit
id: check
run: |
# PR mode: never skip
if [ "${{ github.event_name }}" != "merge_group" ]; then
echo "skip=false" >> $GITHUB_OUTPUT
exit 0
fi
if [ "${{ steps.merge-queue-ci-skipper.outputs.skip-check }}" = "true" ]; then
echo "skip=true" >> $GITHUB_OUTPUT
else
echo "skip=false" >> $GITHUB_OUTPUT
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' || '' }}
SCCACHE_MULTILEVEL_CHAIN: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'disk,s3' || '' }}
SCCACHE_S3_KEY_PREFIX: ${{ needs.skip-if-clean.outputs.internal == 'true' && format('{0}/', github.repository) || '' }}
SCCACHE_BUCKET: ${{ secrets.SCCACHE_BUCKET }}
SCCACHE_REGION: ${{ secrets.SCCACHE_REGION }}
SCCACHE_ENDPOINT: ${{ secrets.SCCACHE_ENDPOINT }}
AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_S3_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_S3_SECRET_ACCESS_KEY }}
RUSTC_WRAPPER: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'sccache' || '' }}
needs: [skip-if-clean]
if: ${{ needs.skip-if-clean.outputs.skip != 'true' }}
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: 📥 Check out code
uses: actions/checkout@v4
- name: Setup Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
with:
rustflags: ''
cache: false
- name: 🧰 Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- 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 }}-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
- name: Stage Docker context
run: |
mkdir -p apps/daedalus_client/docker-stage
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
- name: Generate Docker image metadata
id: docker-meta
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
- name: ⚙️ Generate Docker image metadata
id: docker_meta
uses: docker/metadata-action@v5
env:
DOCKER_METADATA_ANNOTATIONS_LEVELS: manifest,index
with:
@@ -143,19 +43,20 @@ jobs:
org.opencontainers.image.description=Modrinth game metadata query client
org.opencontainers.image.licenses=MIT
- name: Login to GitHub Packages
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
- name: 🔑 Login to GitHub Packages
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
- name: 🔨 Build and push
uses: docker/build-push-action@v6
with:
context: ./apps/daedalus_client/docker-stage
file: ./apps/daedalus_client/Dockerfile
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.docker-meta.outputs.tags }}
labels: ${{ steps.docker-meta.outputs.labels }}
annotations: ${{ steps.docker-meta.outputs.annotations }}
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
annotations: ${{ steps.docker_meta.outputs.annotations }}
cache-from: type=registry,ref=ghcr.io/modrinth/daedalus:main
cache-to: type=inline
+2 -2
View File
@@ -12,10 +12,10 @@ jobs:
steps:
- name: Checkout repository
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@v3
- name: Log in to GitHub Container Registry
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
+10 -25
View File
@@ -21,20 +21,16 @@ on:
type: string
description: 'The environment to deploy to (staging-preview or production-preview)'
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ inputs.environment || 'push' }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/prod' }}
jobs:
deploy:
runs-on: blacksmith-2vcpu-ubuntu-2404
runs-on: ubuntu-latest
permissions:
contents: read
deployments: write
pull-requests: write
steps:
- name: Checkout code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@v4
with:
fetch-depth: 0
@@ -67,25 +63,14 @@ jobs:
echo "url=https://modrinth.com" >> $GITHUB_OUTPUT
fi
- name: Setup pnpm
uses: pnpm/action-setup@v4
- name: Setup Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
uses: actions/setup-node@v4
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
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: Inject build variables
working-directory: ./apps/frontend
@@ -114,7 +99,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@v3
env:
SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
SENTRY_ORG: modrinth
@@ -126,7 +111,7 @@ jobs:
- name: Deploy Cloudflare Worker
id: wrangler
uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3.15.0
uses: cloudflare/wrangler-action@v3
with:
apiToken: ${{ secrets.CF_API_TOKEN }}
accountId: ${{ secrets.CF_ACCOUNT_ID }}
@@ -152,7 +137,7 @@ jobs:
- name: Upload deployment URL
if: ${{ inputs.environment != '' }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
uses: actions/upload-artifact@v6
with:
name: deployment-url-${{ inputs.environment }}
path: deployment-url-${{ inputs.environment }}.txt
+4 -64
View File
@@ -16,77 +16,19 @@ jobs:
if: github.repository_owner == 'modrinth' && github.event.pull_request.head.repo.full_name == github.repository
uses: ./.github/workflows/frontend-deploy.yml
secrets: inherit
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-${{ matrix.environment }}
cancel-in-progress: true
strategy:
matrix:
environment: [staging-preview, production-preview]
with:
environment: ${{ matrix.environment }}
deploy-storybook:
if: github.repository_owner == 'modrinth' && github.event.pull_request.head.repo.full_name == github.repository
runs-on: blacksmith-2vcpu-ubuntu-2404
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}-storybook
cancel-in-progress: true
permissions:
contents: read
deployments: write
steps:
- name: Checkout code
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: Restore pnpm cache
uses: actions/cache/restore@27d5ce7f107fe9357f9df03efb73ab90386fccae # v5.0.5
with:
path: ${{ steps.pnpm-store.outputs.store-path }}
key: pnpm-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
pnpm-cache-
- name: Install dependencies
working-directory: ./packages/ui
run: pnpm install
- name: Build Storybook
working-directory: ./packages/ui
run: pnpm run build-storybook
- name: Configure short SHA
id: meta
run: echo "sha_short=${GITHUB_SHA::8}" >> $GITHUB_OUTPUT
- name: Deploy Storybook preview
uses: cloudflare/wrangler-action@9acf94ace14e7dc412b076f2c5c20b8ce93c79cd # v3.15.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 }}
comment:
if: github.repository_owner == 'modrinth' && github.event.pull_request.head.repo.full_name == github.repository
runs-on: ubuntu-latest
needs: [deploy, deploy-storybook]
needs: deploy
steps:
- name: Download deployment URLs
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
uses: actions/download-artifact@v7
with:
pattern: deployment-url-*
merge-multiple: true
@@ -102,11 +44,10 @@ jobs:
echo "staging-preview-url=$STAGING_PREVIEW_URL" >> $GITHUB_OUTPUT
echo "production-preview-url=$PRODUCTION_PREVIEW_URL" >> $GITHUB_OUTPUT
echo "storybook-preview-url=https://git-${GITHUB_SHA::8}-storybook.modrinth.workers.dev" >> $GITHUB_OUTPUT
- name: Find comment
if: github.event_name == 'pull_request'
uses: peter-evans/find-comment@b30e6a3c0ed37e7c023ccd3f1db5c6c0b0c23aad # v4.0.0
uses: peter-evans/find-comment@v3
id: fc
with:
token: ${{ secrets.CROWDIN_GH_TOKEN }}
@@ -115,7 +56,7 @@ jobs:
- name: Comment deploy URL on PR
if: github.event_name == 'pull_request'
uses: peter-evans/create-or-update-comment@e8674b075228eee787fea43ef493e45ece1004c9 # v5.0.0
uses: peter-evans/create-or-update-comment@v5
with:
token: ${{ secrets.CROWDIN_GH_TOKEN }}
issue-number: ${{ github.event.pull_request.number }}
@@ -129,5 +70,4 @@ jobs:
|-------------|-----|
| staging | ${{ steps.urls.outputs.staging-preview-url }} |
| production | ${{ steps.urls.outputs.production-preview-url }} |
| storybook | ${{ steps.urls.outputs.storybook-preview-url }} |
edit-mode: replace
+4 -4
View File
@@ -51,14 +51,14 @@ jobs:
CROWDIN_GH_TOKEN_DEFINED: ${{ secrets.CROWDIN_GH_TOKEN != '' }}
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
token: ${{ secrets.CROWDIN_GH_TOKEN }}
- name: Configure Git author
id: git-author
uses: MarcoIeni/git-config@59144859caf016f8b817a2ac9b051578729173c4 # v0.1.2
uses: MarcoIeni/git-config@v0.1
env:
GITHUB_TOKEN: ${{ secrets.CROWDIN_GH_TOKEN }}
@@ -79,7 +79,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@v2
with:
upload_sources: false
upload_translations: false
@@ -96,7 +96,7 @@ jobs:
run: sudo chown -R $USER:$USER .
- name: Create Pull Request
uses: peter-evans/create-pull-request@5f6978faf089d4d20b00c7766989d076bb2fc7f1 # v8.1.1
uses: peter-evans/create-pull-request@v7
with:
title: 'New translations from Crowdin (${{ steps.branch-name.outputs.branch_name }})'
body-path: .github/templates/crowdin-pr.md
+2 -2
View File
@@ -53,7 +53,7 @@ jobs:
CROWDIN_PERSONAL_TOKEN_DEFINED: ${{ secrets.CROWDIN_PERSONAL_TOKEN != '' }}
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
uses: actions/checkout@v4
with:
ref: ${{ github.ref }}
@@ -68,7 +68,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@v1
with:
upload_sources: true
upload_translations: false
+21 -121
View File
@@ -3,7 +3,7 @@ name: docker-build
on:
push:
branches:
- 'main'
- '**'
paths:
- .github/workflows/labrinth-docker.yml
- 'apps/labrinth/**'
@@ -19,122 +19,19 @@ on:
merge_group:
types: [checks_requested]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/prod' }}
jobs:
skip-if-clean:
name: Skip if merge_queue produces no diff
runs-on: ubuntu-latest
outputs:
skip: ${{ steps.check.outputs.skip }}
internal: ${{ steps.check-internal.outputs.internal }}
if: ${{ always() }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Check if workflow runs on an internal branch
id: check-internal
env:
EVENT_NAME: ${{ github.event_name }}
HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
REPO: ${{ github.repository }}
run: |
if [ "$EVENT_NAME" != "pull_request" ] || [ "$HEAD_REPO" = "$REPO" ]; then
echo "internal=true" >> $GITHUB_OUTPUT
else
echo "internal=false" >> $GITHUB_OUTPUT
fi
- name: Merge Queue CI Check Skipper
id: merge-queue-ci-skipper
uses: ./.github/merge-queue-ci-skipper
with:
secret: ${{ secrets.GH_ACCESS_TOKEN }}
- name: Check merge_group synthetic commit
id: check
run: |
# PR mode: never skip
if [ "${{ github.event_name }}" != "merge_group" ]; then
echo "skip=false" >> $GITHUB_OUTPUT
exit 0
fi
if [ "${{ steps.merge-queue-ci-skipper.outputs.skip-check }}" = "true" ]; then
echo "skip=true" >> $GITHUB_OUTPUT
else
echo "skip=false" >> $GITHUB_OUTPUT
fi
docker:
runs-on: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'blacksmith-4vcpu-ubuntu-2404' || '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_MULTILEVEL_CHAIN: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'disk,s3' || '' }}
SCCACHE_S3_KEY_PREFIX: ${{ needs.skip-if-clean.outputs.internal == 'true' && format('{0}/', github.repository) || '' }}
SCCACHE_BUCKET: ${{ secrets.SCCACHE_BUCKET }}
SCCACHE_REGION: ${{ secrets.SCCACHE_REGION }}
SCCACHE_ENDPOINT: ${{ secrets.SCCACHE_ENDPOINT }}
AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_S3_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_S3_SECRET_ACCESS_KEY }}
RUSTC_WRAPPER: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'sccache' || '' }}
runs-on: ubuntu-latest
steps:
- name: Check out code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: 📥 Check out code
uses: actions/checkout@v4
- name: Setup Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
with:
rustflags: ''
cache: false
- name: 🧰 Set up Docker Buildx
uses: docker/setup-buildx-action@v2
- 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 }}-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
- name: Stage Docker context
run: |
mkdir -p apps/labrinth/docker-stage
cp target/release-labrinth/labrinth apps/labrinth/docker-stage/labrinth
cp -r apps/labrinth/migrations apps/labrinth/docker-stage/migrations
cp -r apps/labrinth/assets apps/labrinth/docker-stage/assets
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@4d04d5d9486b7bd6fa91e7baf45bbb4f8b9deedd # v4.0.0
- name: Generate Docker image metadata
id: docker-meta
uses: docker/metadata-action@030e881283bb7a6894de51c315a6bfe6a94e05cf # v6.0.0
- name: ⚙️ Generate Docker image metadata
id: docker_meta
uses: docker/metadata-action@v5
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
@@ -152,19 +49,22 @@ jobs:
org.opencontainers.image.description=Modrinth API
org.opencontainers.image.licenses=AGPL-3.0-only
- name: Login to GitHub Packages
uses: docker/login-action@4907a6ddec9925e35a0a9e82d7399ccc52663121 # v4.1.0
- name: 🔑 Login to GitHub Packages
uses: docker/login-action@v3
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ secrets.GITHUB_TOKEN }}
- name: Build and push
uses: docker/build-push-action@bcafcacb16a39f128d818304e6c9c0c18556b85f # v7.1.0
- name: 🔨 Build and push
uses: docker/build-push-action@v6
with:
context: ./apps/labrinth/docker-stage
file: ./apps/labrinth/Dockerfile
push: true
tags: ${{ steps.docker-meta.outputs.tags }}
labels: ${{ steps.docker-meta.outputs.labels }}
annotations: ${{ steps.docker-meta.outputs.annotations }}
push: ${{ github.event_name != 'pull_request' }}
tags: ${{ steps.docker_meta.outputs.tags }}
labels: ${{ steps.docker_meta.outputs.labels }}
annotations: ${{ steps.docker_meta.outputs.annotations }}
build-args: |
GIT_HASH=${{ fromJSON(steps.docker_meta.outputs.json).labels['org.opencontainers.image.revision'] }}
cache-from: type=registry,ref=ghcr.io/modrinth/labrinth:main
cache-to: type=inline
-41
View File
@@ -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
+24 -47
View File
@@ -31,66 +31,45 @@ on:
default: prod
required: false
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/prod' }}
jobs:
build:
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: [macos-latest, windows-latest, ubuntu-latest]
include:
- platform: blacksmith-6vcpu-macos-26
- platform: macos-latest
artifact-target-name: universal-apple-darwin
- platform: blacksmith-8vcpu-windows-2025
- platform: windows-latest
artifact-target-name: x86_64-pc-windows-msvc
- platform: blacksmith-4vcpu-ubuntu-2404
- platform: ubuntu-latest
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@v4
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@v1
with:
rustflags: ''
target: ${{ contains(matrix.platform, 'macos') && 'x86_64-apple-darwin' || '' }}
target: ${{ startsWith(matrix.platform, 'macos') && 'x86_64-apple-darwin' || '' }}
- name: Setup sccache
uses: mozilla-actions/sccache-action@9e7fa8a12102821edf02ca5dbea1acd0f89a2696 # v0.0.10
- name: Install pnpm
uses: pnpm/action-setup@v4
- name: Enable Corepack
run: corepack enable
- name: Setup Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- name: Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: 'pnpm'
cache: pnpm
- name: Generate tauri-dev.conf.json
shell: bash
@@ -108,19 +87,18 @@ jobs:
EOF
- name: Install Linux build dependencies
if: contains(matrix.platform, 'ubuntu')
uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # v1.6.0
with:
packages: libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev
version: v1 # cache key
if: startsWith(matrix.platform, 'ubuntu')
run: |
sudo apt-get update
sudo apt-get install -yq libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev
- name: Setup Dasel
uses: jaxxstorm/action-install-gh-release@25e24d2d23ae098373794ef1d6faecb48ee52da8 # v3.0.0
uses: jaxxstorm/action-install-gh-release@v2.1.0
with:
repo: TomWright/dasel
tag: v2.8.1
extension-matching: disable
rename-to: ${{ contains(matrix.platform, 'windows') && 'dasel.exe' || 'dasel' }}
rename-to: ${{ startsWith(matrix.platform, 'windows') && 'dasel.exe' || 'dasel' }}
chmod: 0755
- name: Set application version and environment
@@ -137,13 +115,13 @@ 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
uses: rharkor/caching-for-turbo@v1.8
- name: Install dependencies
run: pnpm install
- name: Set up Windows code signing
if: contains(matrix.platform, 'windows')
if: startsWith(matrix.platform, 'windows')
shell: bash
run: |
if [ '${{ startsWith(github.ref, 'refs/tags/v') || inputs.sign-windows-binaries }}' = 'true' ]; then
@@ -154,9 +132,8 @@ jobs:
- name: Build macOS app
run: ${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) && 'pnpm --filter=@modrinth/app run tauri build --target universal-apple-darwin --config tauri-release.conf.json' || 'pnpm --filter=@modrinth/app run tauri build --target universal-apple-darwin --config tauri-dev.conf.json' }}
if: contains(matrix.platform, 'macos')
if: startsWith(matrix.platform, 'macos')
env:
TAURI_BUNDLER_DMG_IGNORE_CI: 'true'
ENABLE_CODE_SIGNING: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE: ${{ secrets.APPLE_CERTIFICATE }}
APPLE_CERTIFICATE_PASSWORD: ${{ secrets.APPLE_CERTIFICATE_PASSWORD }}
@@ -169,7 +146,7 @@ jobs:
- name: Build Linux app
run: ${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) && 'pnpm --filter=@modrinth/app run tauri build --config tauri-release.conf.json' || 'pnpm --filter=@modrinth/app run tauri build --config tauri-dev.conf.json' }}
if: contains(matrix.platform, 'ubuntu')
if: startsWith(matrix.platform, 'ubuntu')
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
@@ -181,7 +158,7 @@ jobs:
$env:JAVA_HOME = "$env:JAVA_HOME_17_X64"
${{ (github.ref == 'refs/heads/main' || startsWith(github.ref, 'refs/tags/v')) && 'pnpm --filter=@modrinth/app run tauri build --config tauri-release.conf.json --verbose --bundles "nsis,updater"' || 'pnpm --filter=@modrinth/app run tauri build --config tauri-dev.conf.json --verbose --bundles "nsis,updater"' }}
Remove-Item -Path signer-client-cert.p12 -ErrorAction SilentlyContinue
if: contains(matrix.platform, 'windows')
if: startsWith(matrix.platform, 'windows')
env:
TAURI_SIGNING_PRIVATE_KEY: ${{ secrets.TAURI_PRIVATE_KEY }}
TAURI_SIGNING_PRIVATE_KEY_PASSWORD: ${{ secrets.TAURI_KEY_PASSWORD }}
@@ -190,7 +167,7 @@ jobs:
DIGICERT_ONE_SIGNER_CLIENT_CERTIFICATE_PASSWORD: ${{ secrets.DIGICERT_ONE_SIGNER_CLIENT_CERTIFICATE_PASSWORD }}
- name: Upload app bundles
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
uses: actions/upload-artifact@v4
with:
name: App bundle (${{ matrix.artifact-target-name }})
path: |
+27 -15
View File
@@ -4,10 +4,6 @@ on:
workflows: ['Modrinth App build']
types: [completed]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/prod' }}
jobs:
release:
name: Release Modrinth App
@@ -15,7 +11,8 @@ 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: ubuntu-latest
env:
VERSION_TAG: ${{ github.event.workflow_run.head_branch }}
LINUX_X64_BUNDLE_ARTIFACT_NAME: App bundle (x86_64-unknown-linux-gnu)
@@ -24,10 +21,10 @@ jobs:
LAUNCHER_FILES_BUCKET_BASE_URL: https://launcher-files.modrinth.com
steps:
- name: Check out code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: 📥 Check out code
uses: actions/checkout@v4
- name: Verify ref is a tag
- name: 🔒 Verify ref is a tag
env:
GH_TOKEN: ${{ github.token }}
HEAD_SHA: ${{ github.event.workflow_run.head_sha }}
@@ -46,8 +43,8 @@ jobs:
fi
echo "Verified ${VERSION_TAG} is a tag pointing at ${HEAD_SHA}"
- name: Download Modrinth App artifacts
uses: dawidd6/action-download-artifact@b6e2e70617bc3265edd6dab6c906732b2f1ae151 # v21
- name: 📥 Download Modrinth App artifacts
uses: dawidd6/action-download-artifact@v11
with:
workflow: theseus-build.yml
workflow_conclusion: success
@@ -55,12 +52,27 @@ jobs:
branch: ${{ env.VERSION_TAG }}
use_unzip: true
- name: Extract app changelog
- name: 📝 Extract app changelog
env:
VERSION: ${{ env.VERSION_TAG }}
run: npx --yes tsx scripts/build-theseus-release-notes.ts
run: |
node <<'EOF'
const fs = require('fs');
const version = process.env.VERSION.replace(/^v/, '');
const src = fs.readFileSync('packages/blog/changelog.ts', 'utf8');
const escaped = version.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
const re = new RegExp("product:\\s*'app',\\s*version:\\s*'" + escaped + "',\\s*body:\\s*`([\\s\\S]*?)`,\\s*\\}");
const m = src.match(re);
if (!m) {
console.error(`No app changelog entry found for version ${version}`);
process.exit(1);
}
fs.writeFileSync('release-notes.md', m[1]);
console.log(`Extracted changelog for app ${version}:`);
console.log(m[1]);
EOF
- name: Generate version manifest
- name: 🛠️ Generate version manifest
run: |
# Reference: https://tauri.app/plugin/updater/#server-support
jq -nc \
@@ -105,7 +117,7 @@ jobs:
echo "Generated manifest for version ${VERSION_TAG}:"
cat updates.json
- name: Upload release artifacts
- name: 📤 Upload release artifacts
env:
AWS_ACCESS_KEY_ID: ${{ secrets.LAUNCHER_FILES_BUCKET_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.LAUNCHER_FILES_BUCKET_SECRET_ACCESS_KEY }}
@@ -140,7 +152,7 @@ jobs:
aws s3 cp updates.json "s3://${AWS_BUCKET}"
- name: Create GitHub release
- name: 🏷️ Create GitHub release
env:
GH_TOKEN: ${{ github.token }}
run: |
+29 -130
View File
@@ -8,63 +8,10 @@ on:
merge_group:
types: [checks_requested]
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/prod' }}
jobs:
skip-if-clean:
name: Skip if merge_queue produces no diff
runs-on: ubuntu-latest
outputs:
skip: ${{ steps.check.outputs.skip }}
internal: ${{ steps.check-internal.outputs.internal }}
if: ${{ always() }}
steps:
- name: Checkout
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Check if workflow runs on an internal branch
id: check-internal
env:
EVENT_NAME: ${{ github.event_name }}
HEAD_REPO: ${{ github.event.pull_request.head.repo.full_name }}
REPO: ${{ github.repository }}
run: |
if [ "$EVENT_NAME" != "pull_request" ] || [ "$HEAD_REPO" = "$REPO" ]; then
echo "internal=true" >> $GITHUB_OUTPUT
else
echo "internal=false" >> $GITHUB_OUTPUT
fi
- name: Merge Queue CI Check Skipper
id: merge-queue-ci-skipper
uses: ./.github/merge-queue-ci-skipper
with:
secret: ${{ secrets.GH_ACCESS_TOKEN }}
- name: Check merge_group synthetic commit
id: check
env:
EVENT_NAME: ${{ github.event_name }}
SKIP_CHECK: ${{ steps.merge-queue-ci-skipper.outputs.skip-check }}
run: |
if [ "$EVENT_NAME" != "merge_group" ]; then
echo "skip=false" >> $GITHUB_OUTPUT
exit 0
fi
if [ "$SKIP_CHECK" = "true" ]; then
echo "skip=true" >> $GITHUB_OUTPUT
else
echo "skip=false" >> $GITHUB_OUTPUT
fi
build:
name: Lint and Test
runs-on: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-latest' }}
needs: [skip-if-clean]
if: ${{ needs.skip-if-clean.outputs.skip != 'true' }}
runs-on: ubuntu-latest
env:
# Ensure pnpm output is colored in GitHub Actions logs
@@ -76,107 +23,59 @@ 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' || '' }}
SCCACHE_MULTILEVEL_CHAIN: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'disk,s3' || '' }}
SCCACHE_S3_KEY_PREFIX: ${{ needs.skip-if-clean.outputs.internal == 'true' && format('{0}/', github.repository) || '' }}
SCCACHE_BUCKET: ${{ secrets.SCCACHE_BUCKET }}
SCCACHE_REGION: ${{ secrets.SCCACHE_REGION }}
SCCACHE_ENDPOINT: ${{ secrets.SCCACHE_ENDPOINT }}
AWS_ACCESS_KEY_ID: ${{ secrets.SCCACHE_S3_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.SCCACHE_S3_SECRET_ACCESS_KEY }}
RUSTC_WRAPPER: ${{ needs.skip-if-clean.outputs.internal == 'true' && 'sccache' || '' }}
steps:
- name: Check out code
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: 📥 Check out code
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Install build dependencies
uses: awalsh128/cache-apt-pkgs-action@acb598e5ddbc6f68a970c5da0688d2f3a9f04d05 # v1.6.0
with:
packages: libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev
version: v1 # cache key
- name: 🧰 Install build dependencies
run: |
sudo apt-get update
sudo apt-get install -yq libwebkit2gtk-4.1-dev libayatana-appindicator3-dev librsvg2-dev
- name: Setup Node
uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6.4.0
- name: 🧰 Install pnpm
uses: pnpm/action-setup@v4
- name: 🧰 Setup Node.js
uses: actions/setup-node@v4
with:
node-version-file: .nvmrc
cache: pnpm
- 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
with:
path: ${{ steps.pnpm-store.outputs.store-path }}
key: pnpm-cache-${{ runner.os }}-${{ runner.arch }}-${{ hashFiles('**/pnpm-lock.yaml') }}
restore-keys: |
pnpm-cache-
- name: Setup Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@2b1f5e9b395427c92ee4e3331786ca3c37afe2d7 # v1.16.0
- name: 🧰 Setup Rust toolchain
uses: actions-rust-lang/setup-rust-toolchain@v1
with:
rustflags: ''
components: clippy, rustfmt
cache: false
- 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
- name: Setup nextest
run: cargo binstall --no-confirm --secure cargo-nextest@0.9.133
- name: 🧰 Setup nextest
uses: taiki-e/install-action@nextest
# 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
- name: 🧰 Setup cargo-sqlx
uses: taiki-e/cache-cargo-install-action@v2
with:
tool: sqlx-cli@0.8.6
tool: sqlx-cli
locked: false
no-default-features: true
features: rustls,postgres
- name: Setup Turbo cache
uses: rharkor/caching-for-turbo@56219402aacc0d06b650d898c222996dbc1191ec # v2.3.14
- name: 💨 Setup Turbo cache
uses: rharkor/caching-for-turbo@v1.8
- name: Install dependencies
- name: 🧰 Install dependencies
run: pnpm install
- name: Set app environment
- name: ⚙️ Set app environment
working-directory: packages/app-lib
run: cp .env.staging .env
# check if labrinth tests will actually run (cache miss)
- name: Check if labrinth tests need to run
- name: 🔍 Check if labrinth tests need to run
id: check-labrinth
run: |
LABRINTH_TEST_STATUS=$(pnpm turbo run test --filter=@modrinth/labrinth --dry-run=json | jq -r '.tasks[] | select(.task == "test") | .cache.status')
@@ -187,21 +86,21 @@ jobs:
echo "needs_services=true" >> $GITHUB_OUTPUT
fi
- name: Start services
- name: ⚙️ Start services
if: steps.check-labrinth.outputs.needs_services == 'true'
run: docker compose up --wait
- name: Setup labrinth environment and database
- name: ⚙️ Setup labrinth environment and database
if: steps.check-labrinth.outputs.needs_services == 'true'
working-directory: apps/labrinth
run: |
cp .env.local .env
sqlx database setup
- name: Lint and test
- name: 🔍 Lint and test
run: pnpm run ci
- name: Verify intl:extract has been run
- name: 🔍 Verify intl:extract has been run
run: |
pnpm turbo run intl:extract --force
git diff --exit-code --color */*/src/locales/en-US/index.json
-8
View File
@@ -78,11 +78,3 @@ storybook-static
# frontend robots.txt
apps/frontend/src/public/robots.txt
# Oh My Code
.omc/
# Local dry-run output for scripts/build-theseus-release-notes.mjs
/test_result.md
packages/tooling-config/script-utils/import-sort.js
-9
View File
@@ -1,11 +1,2 @@
strict-peer-dependencies=false
auto-install-peers=true
public-hoist-pattern[]=prettier-plugin-*
public-hoist-pattern[]=@prettier/plugin-*
public-hoist-pattern[]=eslint
public-hoist-pattern[]=@eslint/*
public-hoist-pattern[]=eslint-plugin-*
public-hoist-pattern[]=@nuxt/eslint-config
public-hoist-pattern[]=typescript-eslint
public-hoist-pattern[]=vue-eslint-parser
public-hoist-pattern[]=globals
+1 -1
View File
@@ -1 +1 @@
24.15.0
20.19.2
-1
View File
@@ -1 +0,0 @@
CLAUDE.md
+1
View File
@@ -0,0 +1 @@
See [CLAUDE.md](./CLAUDE.md) for all project instructions and guidelines.
Generated
+63 -430
View File
@@ -27,7 +27,7 @@ checksum = "daa239b93927be1ff123eebada5a3ff23e89f0124ccb8609234e5103d5a5ae6d"
dependencies = [
"actix-utils",
"actix-web",
"derive_more 2.1.1",
"derive_more 2.0.1",
"futures-util",
"log",
"once_cell",
@@ -46,7 +46,7 @@ dependencies = [
"actix-web",
"bitflags 2.9.4",
"bytes",
"derive_more 2.1.1",
"derive_more 2.0.1",
"futures-core",
"http-range",
"log",
@@ -72,10 +72,10 @@ dependencies = [
"brotli",
"bytes",
"bytestring",
"derive_more 2.1.1",
"derive_more 2.0.1",
"encoding_rs",
"flate2",
"foldhash 0.1.5",
"foldhash",
"futures-core",
"h2 0.3.27",
"http 0.2.12",
@@ -226,9 +226,9 @@ dependencies = [
"bytestring",
"cfg-if",
"cookie 0.16.2",
"derive_more 2.1.1",
"derive_more 2.0.1",
"encoding_rs",
"foldhash 0.1.5",
"foldhash",
"futures-core",
"futures-util",
"impl-more",
@@ -914,18 +914,6 @@ dependencies = [
"arrayvec",
]
[[package]]
name = "aws-credential-types"
version = "1.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cd362783681b15d136480ad555a099e82ecd8e2d10a841e14dfd0078d67fee3"
dependencies = [
"aws-smithy-async",
"aws-smithy-runtime-api",
"aws-smithy-types",
"zeroize",
]
[[package]]
name = "aws-creds"
version = "0.39.0"
@@ -976,295 +964,6 @@ dependencies = [
"thiserror 2.0.17",
]
[[package]]
name = "aws-runtime"
version = "1.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c635c2dc792cb4a11ce1a4f392a925340d1bdf499289b5ec1ec6810954eb43f5"
dependencies = [
"aws-credential-types",
"aws-sigv4",
"aws-smithy-async",
"aws-smithy-eventstream",
"aws-smithy-http",
"aws-smithy-runtime",
"aws-smithy-runtime-api",
"aws-smithy-types",
"aws-types",
"bytes",
"fastrand 2.3.0",
"http 0.2.12",
"http 1.3.1",
"http-body 0.4.6",
"http-body 1.0.1",
"percent-encoding",
"pin-project-lite",
"tracing",
"uuid 1.18.1",
]
[[package]]
name = "aws-sdk-s3"
version = "1.122.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "94c2ca0cba97e8e279eb6c0b2d0aa10db5959000e602ab2b7c02de6b85d4c19b"
dependencies = [
"aws-credential-types",
"aws-runtime",
"aws-sigv4",
"aws-smithy-async",
"aws-smithy-checksums",
"aws-smithy-eventstream",
"aws-smithy-http",
"aws-smithy-json",
"aws-smithy-observability",
"aws-smithy-runtime",
"aws-smithy-runtime-api",
"aws-smithy-types",
"aws-smithy-xml",
"aws-types",
"bytes",
"fastrand 2.3.0",
"hex",
"hmac",
"http 0.2.12",
"http 1.3.1",
"http-body 1.0.1",
"lru",
"percent-encoding",
"regex-lite",
"sha2",
"tracing",
"url",
]
[[package]]
name = "aws-sigv4"
version = "1.3.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "efa49f3c607b92daae0c078d48a4571f599f966dce3caee5f1ea55c4d9073f99"
dependencies = [
"aws-credential-types",
"aws-smithy-eventstream",
"aws-smithy-http",
"aws-smithy-runtime-api",
"aws-smithy-types",
"bytes",
"form_urlencoded",
"hex",
"hmac",
"http 0.2.12",
"http 1.3.1",
"percent-encoding",
"sha2",
"time",
"tracing",
]
[[package]]
name = "aws-smithy-async"
version = "1.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52eec3db979d18cb807fc1070961cc51d87d069abe9ab57917769687368a8c6c"
dependencies = [
"futures-util",
"pin-project-lite",
"tokio",
]
[[package]]
name = "aws-smithy-checksums"
version = "0.64.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ddcf418858f9f3edd228acb8759d77394fed7531cce78d02bdda499025368439"
dependencies = [
"aws-smithy-http",
"aws-smithy-types",
"bytes",
"crc-fast",
"hex",
"http 1.3.1",
"http-body 1.0.1",
"http-body-util",
"md-5",
"pin-project-lite",
"sha1",
"sha2",
"tracing",
]
[[package]]
name = "aws-smithy-eventstream"
version = "0.60.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35b9c7354a3b13c66f60fe4616d6d1969c9fd36b1b5333a5dfb3ee716b33c588"
dependencies = [
"aws-smithy-types",
"bytes",
"crc32fast",
]
[[package]]
name = "aws-smithy-http"
version = "0.63.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "630e67f2a31094ffa51b210ae030855cb8f3b7ee1329bdd8d085aaf61e8b97fc"
dependencies = [
"aws-smithy-eventstream",
"aws-smithy-runtime-api",
"aws-smithy-types",
"bytes",
"bytes-utils",
"futures-core",
"futures-util",
"http 1.3.1",
"http-body 1.0.1",
"http-body-util",
"percent-encoding",
"pin-project-lite",
"pin-utils",
"tracing",
]
[[package]]
name = "aws-smithy-http-client"
version = "1.1.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12fb0abf49ff0cab20fd31ac1215ed7ce0ea92286ba09e2854b42ba5cabe7525"
dependencies = [
"aws-smithy-async",
"aws-smithy-runtime-api",
"aws-smithy-types",
"h2 0.3.27",
"h2 0.4.12",
"http 0.2.12",
"http 1.3.1",
"http-body 0.4.6",
"hyper 0.14.32",
"hyper 1.7.0",
"hyper-rustls 0.24.2",
"hyper-rustls 0.27.7",
"hyper-util",
"pin-project-lite",
"rustls 0.21.12",
"rustls 0.23.32",
"rustls-native-certs 0.8.1",
"rustls-pki-types",
"tokio",
"tokio-rustls 0.26.4",
"tower",
"tracing",
]
[[package]]
name = "aws-smithy-json"
version = "0.62.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3cb96aa208d62ee94104645f7b2ecaf77bf27edf161590b6224bfbac2832f979"
dependencies = [
"aws-smithy-types",
]
[[package]]
name = "aws-smithy-observability"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c0a46543fbc94621080b3cf553eb4cbbdc41dd9780a30c4756400f0139440a1d"
dependencies = [
"aws-smithy-runtime-api",
]
[[package]]
name = "aws-smithy-runtime"
version = "1.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f3df87c14f0127a0d77eb261c3bc45d5b4833e2a1f63583ebfb728e4852134ee"
dependencies = [
"aws-smithy-async",
"aws-smithy-http",
"aws-smithy-http-client",
"aws-smithy-observability",
"aws-smithy-runtime-api",
"aws-smithy-types",
"bytes",
"fastrand 2.3.0",
"http 0.2.12",
"http 1.3.1",
"http-body 0.4.6",
"http-body 1.0.1",
"http-body-util",
"pin-project-lite",
"pin-utils",
"tokio",
"tracing",
]
[[package]]
name = "aws-smithy-runtime-api"
version = "1.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49952c52f7eebb72ce2a754d3866cc0f87b97d2a46146b79f80f3a93fb2b3716"
dependencies = [
"aws-smithy-async",
"aws-smithy-types",
"bytes",
"http 0.2.12",
"http 1.3.1",
"pin-project-lite",
"tokio",
"tracing",
"zeroize",
]
[[package]]
name = "aws-smithy-types"
version = "1.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b3a26048eeab0ddeba4b4f9d51654c79af8c3b32357dc5f336cee85ab331c33"
dependencies = [
"base64-simd",
"bytes",
"bytes-utils",
"futures-core",
"http 0.2.12",
"http 1.3.1",
"http-body 0.4.6",
"http-body 1.0.1",
"http-body-util",
"itoa",
"num-integer",
"pin-project-lite",
"pin-utils",
"ryu",
"serde",
"time",
"tokio",
"tokio-util",
]
[[package]]
name = "aws-smithy-xml"
version = "0.60.13"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "11b2f670422ff42bf7065031e72b45bc52a3508bd089f743ea90731ca2b6ea57"
dependencies = [
"xmlparser",
]
[[package]]
name = "aws-types"
version = "1.3.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d980627d2dd7bfc32a3c025685a033eeab8d365cc840c631ef59d1b8f428164"
dependencies = [
"aws-credential-types",
"aws-smithy-async",
"aws-smithy-runtime-api",
"aws-smithy-types",
"rustc_version",
"tracing",
]
[[package]]
name = "axum"
version = "0.8.8"
@@ -1353,16 +1052,6 @@ version = "0.22.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6"
[[package]]
name = "base64-simd"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195"
dependencies = [
"outref",
"vsimd",
]
[[package]]
name = "base64ct"
version = "1.8.0"
@@ -1378,7 +1067,7 @@ dependencies = [
"bitflags 2.9.4",
"cexpr",
"clang-sys",
"itertools 0.12.1",
"itertools 0.13.0",
"log",
"prettyplease",
"proc-macro2",
@@ -1683,16 +1372,6 @@ dependencies = [
"serde",
]
[[package]]
name = "bytes-utils"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35"
dependencies = [
"bytes",
"either",
]
[[package]]
name = "bytestring"
version = "1.5.0"
@@ -1893,19 +1572,18 @@ dependencies = [
[[package]]
name = "cidre"
version = "0.15.0"
version = "0.11.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0c903ff1729987d29e07295d2c5841993db25ff86cca43bee04505878d3ec1a7"
checksum = "0cc0eb4d7faf9f94493eaf7e7c0534dee2dfa9642353382039572abb4e0e56e9"
dependencies = [
"cc",
"cidre-macros",
]
[[package]]
name = "cidre-macros"
version = "0.5.0"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6facfeffa8b9792dc014bb4e65e364d13518b74e06783d56249810a3e48cfad7"
checksum = "82bc2f84c0baaa09299da3a03864491549685912c1e338a54211e00589dc1e4c"
[[package]]
name = "cityhash-rs"
@@ -2224,15 +1902,6 @@ dependencies = [
"unicode-segmentation",
]
[[package]]
name = "convert_case"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "cookie"
version = "0.16.2"
@@ -2347,18 +2016,6 @@ version = "2.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "19d374276b40fb8bbdee95aef7c7fa6b5316ec764510eb64b8dd0e2ed0d7e7f5"
[[package]]
name = "crc-fast"
version = "1.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2fd92aca2c6001b1bf5ba0ff84ee74ec8501b52bbef0cac80bf25a6c1d87a83d"
dependencies = [
"crc",
"digest",
"rustversion",
"spin 0.10.0",
]
[[package]]
name = "crc32fast"
version = "1.5.0"
@@ -2793,23 +2450,21 @@ dependencies = [
[[package]]
name = "derive_more"
version = "2.1.1"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d751e9e49156b02b44f9c1815bcb94b984cdcc4396ecc32521c739452808b134"
checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678"
dependencies = [
"derive_more-impl",
]
[[package]]
name = "derive_more-impl"
version = "2.1.1"
version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "799a97264921d8623a957f6c3b9011f3b5492f557bbb7a5a19b7fa6d06ba8dcb"
checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3"
dependencies = [
"convert_case 0.10.0",
"proc-macro2",
"quote",
"rustc_version",
"syn 2.0.106",
"unicode-xid",
]
@@ -2927,7 +2582,7 @@ version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "330c60081dcc4c72131f8eb70510f1ac07223e5d4163db481a04a0befcffa412"
dependencies = [
"libloading 0.7.4",
"libloading 0.8.8",
]
[[package]]
@@ -3059,6 +2714,29 @@ dependencies = [
"serde",
]
[[package]]
name = "elasticsearch"
version = "9.1.0-alpha.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "12bb303aa6e1d28c0c86b6fbfe484fd0fd3f512629aeed1ac4f6b85f81d9834a"
dependencies = [
"base64 0.22.1",
"bytes",
"dyn-clone",
"flate2",
"lazy_static",
"parking_lot",
"percent-encoding",
"reqwest 0.12.24",
"rustc_version",
"serde",
"serde_json",
"serde_with",
"tokio",
"url",
"void",
]
[[package]]
name = "elliptic-curve"
version = "0.13.8"
@@ -3260,7 +2938,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "39cab71617ae0d63f51a36d69f866391735b51691dbda63cf6f96d042b63efeb"
dependencies = [
"libc",
"windows-sys 0.52.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -3461,7 +3139,7 @@ checksum = "da0e4dd2a88388a1f4ccc7c9ce104604dab68d9f408dc34cd45823d5a9069095"
dependencies = [
"futures-core",
"futures-sink",
"spin 0.9.8",
"spin",
]
[[package]]
@@ -3476,12 +3154,6 @@ version = "0.1.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2"
[[package]]
name = "foldhash"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "77ce24cb58228fbb8aa041425bb1050850ac19177686ea6e0f41a70416f56fdb"
[[package]]
name = "foreign-types"
version = "0.3.2"
@@ -4133,7 +3805,7 @@ checksum = "9229cfe53dfd69f0609a49f65461bd93001ea1ef889cd5529dd176593f5338a1"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash 0.1.5",
"foldhash",
]
[[package]]
@@ -4141,11 +3813,6 @@ name = "hashbrown"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5419bdc4f6a9207fbeba6d11b604d481addf78ecd10c11ad51e76c2f6482748d"
dependencies = [
"allocator-api2",
"equivalent",
"foldhash 0.2.0",
]
[[package]]
name = "hashlink"
@@ -4577,7 +4244,7 @@ dependencies = [
"libc",
"percent-encoding",
"pin-project-lite",
"socket2 0.5.10",
"socket2 0.6.1",
"system-configuration",
"tokio",
"tower-service",
@@ -4914,9 +4581,9 @@ dependencies = [
[[package]]
name = "io-uring"
version = "0.7.12"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4d09b98f7eace8982db770e4408e7470b028ce513ac28fecdc6bf4c30fe92b62"
checksum = "046fa2d4d00aea763528b4950358d0ead425372445dc8ff86312b3c69ff7727b"
dependencies = [
"bitflags 2.9.4",
"cfg-if",
@@ -4974,7 +4641,7 @@ checksum = "e04d7f318608d35d4b61ddd75cbdaee86b023ebe2bd5a66ee0915f0bf93095a9"
dependencies = [
"hermit-abi 0.5.2",
"libc",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -5235,7 +4902,6 @@ dependencies = [
"async-minecraft-ping",
"async-stripe",
"async-trait",
"aws-sdk-s3",
"base64 0.22.1",
"bitflags 2.9.4",
"bytes",
@@ -5248,10 +4914,11 @@ dependencies = [
"const_format",
"dashmap",
"deadpool-redis",
"derive_more 2.1.1",
"derive_more 2.0.1",
"dotenv-build",
"dotenvy",
"either",
"elasticsearch",
"eyre",
"futures",
"futures-util",
@@ -5274,12 +4941,12 @@ dependencies = [
"paste",
"path-util",
"prometheus",
"quick-xml 0.38.3",
"rand 0.8.5",
"rand_chacha 0.3.1",
"redis",
"regex",
"reqwest 0.12.24",
"rust-s3",
"rust_decimal",
"rust_iso3166",
"rustls 0.23.32",
@@ -5338,7 +5005,7 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
dependencies = [
"spin 0.9.8",
"spin",
]
[[package]]
@@ -5439,7 +5106,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "07033963ba89ebaf1584d767badaa2e8fcec21aedea6b8c0346d487d49c28667"
dependencies = [
"cfg-if",
"windows-targets 0.48.5",
"windows-targets 0.53.5",
]
[[package]]
@@ -5560,15 +5227,6 @@ dependencies = [
"imgref",
]
[[package]]
name = "lru"
version = "0.16.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f66e8d5d03f609abc3a39e6f08e4164ebf1447a732906d39eb9b99b7919ef39"
dependencies = [
"hashbrown 0.16.0",
]
[[package]]
name = "lru-cache"
version = "0.1.2"
@@ -5857,7 +5515,7 @@ name = "modrinth-util"
version = "0.0.0"
dependencies = [
"actix-web",
"derive_more 2.1.1",
"derive_more 2.0.1",
"dotenvy",
"eyre",
"modrinth-log",
@@ -5923,7 +5581,7 @@ dependencies = [
"arc-swap",
"bytes",
"chrono",
"derive_more 2.1.1",
"derive_more 2.0.1",
"reqwest 0.12.24",
"rust_decimal",
"rust_iso3166",
@@ -6810,12 +6468,6 @@ dependencies = [
"thiserror 2.0.17",
]
[[package]]
name = "outref"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a80800c0488c3a21695ea981a54918fbb37abf04f4d0720c453632255e2ff0e"
[[package]]
name = "owo-colors"
version = "4.2.3"
@@ -6940,7 +6592,7 @@ checksum = "57c0d7b74b563b49d38dae00a0c37d4d6de9b432382b2892f0574ddcae73fd0a"
name = "path-util"
version = "0.0.0"
dependencies = [
"derive_more 2.1.1",
"derive_more 2.0.1",
"itertools 0.14.0",
"serde",
"typed-path",
@@ -7701,7 +7353,7 @@ dependencies = [
"quinn-udp",
"rustc-hash",
"rustls 0.23.32",
"socket2 0.5.10",
"socket2 0.6.1",
"thiserror 2.0.17",
"tokio",
"tracing",
@@ -7738,9 +7390,9 @@ dependencies = [
"cfg_aliases",
"libc",
"once_cell",
"socket2 0.5.10",
"socket2 0.6.1",
"tracing",
"windows-sys 0.52.0",
"windows-sys 0.60.2",
]
[[package]]
@@ -8413,7 +8065,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.4.15",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
[[package]]
@@ -8426,7 +8078,7 @@ dependencies = [
"errno",
"libc",
"linux-raw-sys 0.11.0",
"windows-sys 0.52.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -9407,12 +9059,6 @@ dependencies = [
"lock_api",
]
[[package]]
name = "spin"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d5fe4ccb98d9c292d56fec89a5e07da7fc4cf0dc11e156b41793132775d3e591"
[[package]]
name = "spki"
version = "0.7.3"
@@ -9628,7 +9274,7 @@ dependencies = [
name = "sqlx-tracing"
version = "0.2.0"
dependencies = [
"derive_more 2.1.1",
"derive_more 2.0.1",
"futures",
"opentelemetry",
"opentelemetry-testing",
@@ -9654,7 +9300,6 @@ dependencies = [
"cfg-if",
"libc",
"psm",
"windows-sys 0.52.0",
"windows-sys 0.59.0",
]
@@ -10419,7 +10064,7 @@ dependencies = [
"getrandom 0.3.3",
"once_cell",
"rustix 1.1.2",
"windows-sys 0.52.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -10502,7 +10147,7 @@ dependencies = [
"daedalus",
"dashmap",
"data-url",
"derive_more 2.1.1",
"derive_more 2.0.1",
"dirs",
"discord-rich-presence",
"dotenvy",
@@ -11647,12 +11292,6 @@ version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6a02e4885ed3bc0f2de90ea6dd45ebcbb66dacffe03547fadbb0eeae2770887d"
[[package]]
name = "vsimd"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64"
[[package]]
name = "vswhom"
version = "0.1.0"
@@ -12073,7 +11712,7 @@ version = "0.1.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a7b1c03c876122aa43f3020e6c3c3ee5c05081c9a00739faf7503aeba10d22"
dependencies = [
"windows-sys 0.48.0",
"windows-sys 0.61.2",
]
[[package]]
@@ -12719,12 +12358,6 @@ version = "0.8.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6fd8403733700263c6eb89f192880191f1b83e332f7a20371ddcf421c4a337c7"
[[package]]
name = "xmlparser"
version = "0.13.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4"
[[package]]
name = "yaserde"
version = "0.12.0"
+4 -10
View File
@@ -44,11 +44,6 @@ async-tungstenite = { version = "0.31.0", default-features = false, features = [
] }
async-walkdir = "2.1.0"
async_zip = "0.0.18"
aws-sdk-s3 = { version = "=1.122.0", default-features = false, features = [
"default-https-client",
"rt-tokio",
"rustls",
] }
base64 = "0.22.1"
bitflags = "2.9.4"
bytemuck = "1.24.0"
@@ -56,7 +51,7 @@ bytes = "1.10.1"
censor = "0.3.0"
chardetng = "0.1.17"
chrono = "0.4.42"
cidre = { version = "0.15.0", default-features = false, features = [
cidre = { version = "0.11.3", default-features = false, features = [
"macos_15_0"
] }
clap = "4.5.48"
@@ -69,7 +64,7 @@ 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" }
derive_more = "2.1.1"
derive_more = "2.0.1"
directories = "6.0.0"
dirs = "6.0.0"
discord-rich-presence = "1.0.0"
@@ -77,6 +72,7 @@ dotenv-build = "0.1.1"
dotenvy = "0.15.7"
dunce = "1.0.5"
either = "1.15.0"
elasticsearch = "9.1.0-alpha.1"
encoding_rs = "0.8.35"
enumset = "1.1.10"
eyre = "0.6.12"
@@ -262,7 +258,6 @@ read_zero_byte_vec = "warn"
redundant_clone = "warn"
redundant_feature_names = "warn"
redundant_type_annotations = "warn"
result_large_err = "allow"
todo = "warn"
too_many_arguments = "allow"
uninlined_format_args = "warn"
@@ -278,11 +273,10 @@ opt-level = "s" # Optimize for binary size
strip = true # Remove debug symbols
lto = true # Enables link to optimizations
panic = "abort" # Strip expensive panic clean-up logic
codegen-units = 1 # Compile crates one after another so the compiler can optimize better
# Specific profile for labrinth production builds
[profile.release-labrinth]
inherits = "release"
opt-level = 2
strip = false # Keep debug symbols for Sentry
lto = "thin" # Enable LTO but keep compile times reasonable
panic = "unwind" # Don't exit the whole app on panic in production
+3 -3
View File
@@ -15,10 +15,10 @@ If you're not a developer and you've stumbled upon this repository, you can acce
## Development
This repository contains two primary packages. For detailed development information, please refer to their respective guides:
This repository contains two primary packages. For detailed development information, please refer to their respective READMEs:
- [Website frontend](https://docs.modrinth.com/contributing/knossos/)
- [Desktop app](https://docs.modrinth.com/contributing/theseus/)
- [Web Interface](apps/frontend/README.md)
- [Desktop App](apps/app/README.md)
## Contributing
+1 -3
View File
@@ -13,14 +13,13 @@
"test": "vue-tsc --noEmit"
},
"dependencies": {
"@intercom/messenger-js-sdk": "^0.0.14",
"@modrinth/api-client": "workspace:^",
"@modrinth/assets": "workspace:*",
"@modrinth/ui": "workspace:*",
"@modrinth/utils": "workspace:*",
"@sentry/vue": "^8.27.0",
"@sfirew/minecraft-motd-parser": "^1.1.6",
"@tanstack/vue-query": "5.90.7",
"@tanstack/vue-query": "^5.90.7",
"@tauri-apps/api": "^2.5.0",
"@tauri-apps/plugin-dialog": "^2.2.1",
"@tauri-apps/plugin-fs": "^2.4.5",
@@ -36,7 +35,6 @@
"fuse.js": "^6.6.2",
"intl-messageformat": "^10.7.7",
"ofetch": "^1.3.4",
"overlayscrollbars": "^2.15.1",
"pinia": "^3.0.0",
"posthog-js": "^1.158.2",
"three": "^0.172.0",
+139 -316
View File
@@ -1,8 +1,6 @@
<script setup>
import { Intercom, shutdown as shutdownIntercom } from '@intercom/messenger-js-sdk'
import {
AuthFeature,
ModrinthApiError,
NodeAuthFeature,
nodeAuthState,
PanelVersionFeature,
@@ -20,10 +18,13 @@ import {
LibraryIcon,
LogInIcon,
LogOutIcon,
MaximizeIcon,
MinimizeIcon,
NewspaperIcon,
NotepadTextIcon,
PlusIcon,
RefreshCwIcon,
RestoreIcon,
RightArrowIcon,
ServerStackIcon,
SettingsIcon,
@@ -34,13 +35,13 @@ import {
import {
Admonition,
Avatar,
Button,
ButtonStyled,
commonMessages,
ContentInstallModal,
CreationFlowModal,
defineMessages,
I18nDebugPanel,
LoadingBar,
NewsArticleCard,
NotificationPanel,
OverflowMenu,
@@ -52,15 +53,13 @@ import {
providePageContext,
providePopupNotificationManager,
useDebugLogger,
useFormatBytes,
useVIntl,
} from '@modrinth/ui'
import { renderString } from '@modrinth/utils'
import { useQuery, useQueryClient } from '@tanstack/vue-query'
import { formatBytes, renderString } from '@modrinth/utils'
import { useQuery } from '@tanstack/vue-query'
import { getVersion } from '@tauri-apps/api/app'
import { invoke } from '@tauri-apps/api/core'
import { getCurrentWindow } from '@tauri-apps/api/window'
import { fetch as tauriFetch } from '@tauri-apps/plugin-http'
import { openUrl } from '@tauri-apps/plugin-opener'
import { type } from '@tauri-apps/plugin-os'
import { saveWindowState, StateFlags } from '@tauri-apps/plugin-window-state'
@@ -69,14 +68,13 @@ import { computed, onMounted, onUnmounted, provide, ref, watch } from 'vue'
import { RouterView, useRoute, useRouter } from 'vue-router'
import ModrinthAppLogo from '@/assets/modrinth_app.svg?component'
import ModrinthLoadingIndicator from '@/components/LoadingIndicatorBar.vue'
import AccountsCard from '@/components/ui/AccountsCard.vue'
import AppActionBar from '@/components/ui/AppActionBar.vue'
import Breadcrumbs from '@/components/ui/Breadcrumbs.vue'
import ErrorModal from '@/components/ui/ErrorModal.vue'
import FriendsList from '@/components/ui/friends/FriendsList.vue'
import AddServerToInstanceModal from '@/components/ui/install_flow/AddServerToInstanceModal.vue'
import IncompatibilityWarningModal from '@/components/ui/install_flow/IncompatibilityWarningModal.vue'
import UnknownPackWarningModal from '@/components/ui/install_flow/UnknownPackWarningModal.vue'
import MinecraftAuthErrorModal from '@/components/ui/minecraft-auth-error-modal/MinecraftAuthErrorModal.vue'
import AppSettingsModal from '@/components/ui/modal/AppSettingsModal.vue'
import AuthGrantFlowWaitModal from '@/components/ui/modal/AuthGrantFlowWaitModal.vue'
@@ -86,9 +84,8 @@ import UpdateToPlayModal from '@/components/ui/modal/UpdateToPlayModal.vue'
import NavButton from '@/components/ui/NavButton.vue'
import PromotionWrapper from '@/components/ui/PromotionWrapper.vue'
import QuickInstanceSwitcher from '@/components/ui/QuickInstanceSwitcher.vue'
import RunningAppBar from '@/components/ui/RunningAppBar.vue'
import SplashScreen from '@/components/ui/SplashScreen.vue'
import WindowControls from '@/components/ui/WindowControls.vue'
import { useIntercomPositioning } from '@/composables/intercom-positioning'
import { useCheckDisableMouseover } from '@/composables/macCssFix.js'
import { config } from '@/config'
import { hide_ads_window, init_ads_window, show_ads_window } from '@/helpers/ads.js'
@@ -99,7 +96,6 @@ import { command_listener, warning_listener } from '@/helpers/events.js'
import { cancelLogin, get as getCreds, login, logout } from '@/helpers/mr_auth.ts'
import { create_profile_and_install_from_file } from '@/helpers/pack'
import { list } from '@/helpers/profile.js'
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'
import {
@@ -109,7 +105,6 @@ import {
getUpdateSize,
isDev,
isNetworkMetered,
setRestartAfterPendingUpdate,
} from '@/helpers/utils.js'
import i18n from '@/i18n.config'
import { createContentInstall, provideContentInstall } from '@/providers/content-install'
@@ -120,9 +115,8 @@ import {
import { createServerInstall, provideServerInstall } from '@/providers/server-install'
import { setupProviders } from '@/providers/setup'
import { setupAuthProvider } from '@/providers/setup/auth'
import { setupLoadingStateProvider } from '@/providers/setup/loading-state'
import { useError } from '@/store/error.js'
import { useTheming } from '@/store/state'
import { useLoading, useTheming } from '@/store/state'
import { generateSkinPreviews } from './helpers/rendering/batch-skin-renderer'
import { get_available_capes, get_available_skins } from './helpers/skins'
@@ -130,17 +124,6 @@ import { AppNotificationManager } from './providers/app-notifications'
import { AppPopupNotificationManager } from './providers/app-popup-notifications'
const themeStore = useTheming()
const router = useRouter()
const route = useRoute()
const intercomBubblePositioning = useIntercomPositioning({ route, themeStore })
const {
sidebarToggled,
forceSidebar,
sidebarVisible,
intercomBubblePosition,
updateIntercomBubbleStyles,
clearIntercomBubbleStyles,
} = intercomBubblePositioning
const notificationManager = new AppNotificationManager()
provideNotificationManager(notificationManager)
@@ -150,9 +133,8 @@ const popupNotificationManager = new AppPopupNotificationManager()
providePopupNotificationManager(popupNotificationManager)
const { addPopupNotification } = popupNotificationManager
const appVersion = getVersion()
const tauriApiClient = new TauriModrinthClient({
userAgent: async () => `modrinth/theseus/${await appVersion} (support@modrinth.com)`,
userAgent: `modrinth/theseus/${getVersion()} (support@modrinth.com)`,
labrinthBaseUrl: config.labrinthBaseUrl,
archonBaseUrl: config.archonBaseUrl,
features: [
@@ -175,7 +157,6 @@ provideModrinthClient(tauriApiClient)
providePageContext({
hierarchicalSidebarAvailable: ref(true),
showAds: ref(false),
...intercomBubblePositioning.pageContext,
featureFlags: {
serverRamAsBytesAlwaysOn: computed(() =>
themeStore.getFeatureFlag('server_ram_as_bytes_always_on'),
@@ -191,17 +172,15 @@ provideModalBehavior({
const {
installationModal,
unknownPackWarningModal,
fetchExistingInstanceNames,
handleCreate,
handleBrowseModpacks,
searchModpacks,
getProjectVersions,
getLoaderManifest,
setModpackAlreadyInstalledModal,
handleModpackDuplicateCreateAnyway,
handleModpackDuplicateGoToInstance,
} = setupProviders(notificationManager, popupNotificationManager)
} = setupProviders(notificationManager)
const news = ref([])
const availableSurvey = ref(false)
@@ -259,15 +238,11 @@ onMounted(async () => {
onUnmounted(async () => {
document.querySelector('body').removeEventListener('click', handleClick)
document.querySelector('body').removeEventListener('auxclick', handleAuxClick)
shutdownHostingIntercom()
clearIntercomBubbleStyles()
await unlistenUpdateDownload?.()
})
const { formatMessage } = useVIntl()
const formatBytes = useFormatBytes()
const messages = defineMessages({
updateInstalledToastTitle: {
id: 'app.update.complete-toast.title',
@@ -444,25 +419,18 @@ const handleClose = async () => {
await getCurrentWindow().close()
}
const loading = setupLoadingStateProvider()
const router = useRouter()
const route = useRoute()
const loading = useLoading()
loading.setEnabled(false)
let initialLoadToken = loading.begin()
let routerToken = null
let suspenseToken = null
loading.startLoading()
let suspensePending = false
const sidebarOverlayScrollbarsOptions = Object.freeze({
overflow: {
x: 'hidden',
y: 'scroll',
},
})
router.beforeEach(() => {
suspensePending = false
if (routerToken) loading.end(routerToken)
routerToken = loading.begin()
loading.startLoading()
})
router.afterEach((to, from, failure) => {
trackEvent('PageView', {
@@ -471,84 +439,12 @@ router.afterEach((to, from, failure) => {
failed: failure,
})
setTimeout(() => {
if (!suspensePending && stateInitialized.value) {
if (initialLoadToken) {
loading.end(initialLoadToken)
initialLoadToken = null
}
if (routerToken) {
loading.end(routerToken)
routerToken = null
}
if (!suspensePending) {
loading.stopLoading()
}
}, 100)
})
function onSuspensePending() {
suspensePending = true
if (suspenseToken) loading.end(suspenseToken)
suspenseToken = loading.begin()
}
function onSuspenseResolve() {
if (suspenseToken) {
loading.end(suspenseToken)
suspenseToken = null
}
if (routerToken) {
loading.end(routerToken)
routerToken = null
}
}
const queryClient = useQueryClient()
watch(stateInitialized, (ready) => {
if (ready) {
if (initialLoadToken) {
loading.end(initialLoadToken)
initialLoadToken = null
}
if (routerToken) {
loading.end(routerToken)
routerToken = null
}
queryClient.prefetchQuery({
queryKey: ['servers'],
queryFn: async () => {
const response = await tauriApiClient.archon.servers_v0.list({ limit: 100 })
const hasMedalServers = response.servers.some((s) => s.is_medal)
if (hasMedalServers) {
const subscriptions = await tauriApiClient.labrinth.billing_internal.getSubscriptions()
for (const server of response.servers) {
if (server.is_medal) {
const sub = subscriptions.find((s) => s.metadata?.id === server.server_id)
if (sub) {
server.medal_expires = new Date(
new Date(sub.created).getTime() + 5 * 86400000,
).toISOString()
}
}
}
}
return response
},
staleTime: 30_000,
})
queryClient.prefetchQuery({
queryKey: ['billing', 'subscriptions'],
queryFn: () => tauriApiClient.labrinth.billing_internal.getSubscriptions(),
staleTime: 30_000,
})
queryClient.prefetchQuery({
queryKey: ['billing', 'payments'],
queryFn: () => tauriApiClient.labrinth.billing_internal.getPayments(),
staleTime: 30_000,
})
}
})
const error = useError()
const errorModal = ref()
const minecraftAuthErrorModal = ref()
@@ -601,27 +497,9 @@ setupAuthProvider(credentials, async (_redirectPath) => {
await signIn()
})
async function validateSession(sessionToken) {
try {
const response = await tauriFetch(`${config.labrinthBaseUrl}/v2/user`, {
method: 'GET',
headers: { Authorization: sessionToken },
})
if (response.status === 401) return false
return true
} catch {
return true
}
}
async function fetchCredentials() {
const creds = await getCreds().catch(handleError)
if (creds && creds.user_id) {
if (creds.session && !(await validateSession(creds.session))) {
await logout().catch(handleError)
credentials.value = null
return
}
creds.user = await get_user(creds.user_id, 'bypass').catch(handleError)
}
credentials.value = creds ?? null
@@ -661,100 +539,19 @@ const hasPlus = computed(
(credentials.value.user.badges & MIDAS_BITFLAG) === MIDAS_BITFLAG,
)
const sidebarToggled = ref(true)
themeStore.$subscribe(() => {
sidebarToggled.value = !themeStore.toggleSidebar
})
const forceSidebar = computed(
() => route.path.startsWith('/browse') || route.path.startsWith('/project'),
)
const sidebarVisible = computed(() => sidebarToggled.value || forceSidebar.value)
const showAd = computed(
() => sidebarVisible.value && !hasPlus.value && credentials.value !== undefined,
)
const hostingRouteActive = computed(() => route.path.startsWith('/hosting'))
let intercomBooting = false
let intercomBooted = false
async function fetchIntercomToken() {
const creds = await getCreds()
if (!creds?.session) {
throw new Error('Not authenticated')
}
const params = new URLSearchParams()
if (route.path.startsWith('/hosting/manage/') && typeof route.params.id === 'string') {
params.set('server_id', route.params.id)
}
const query = params.size > 0 ? `?${params.toString()}` : ''
const response = await tauriFetch(`${config.siteUrl}/api/intercom/messenger-jwt${query}`, {
method: 'GET',
headers: {
Authorization: `Bearer ${creds.session}`,
},
})
if (!response.ok) {
throw new Error(`Failed to fetch Intercom token: ${response.status}`)
}
return await response.json()
}
async function bootIntercom() {
if (
intercomBooting ||
intercomBooted ||
!hostingRouteActive.value ||
!credentials.value?.session
) {
return
}
intercomBooting = true
console.debug('[APP][INTERCOM] initializing secure support chat')
try {
const { token } = await fetchIntercomToken()
Intercom({
app_id: 'ykeritl9',
intercom_user_jwt: token,
session_duration: 1000 * 60 * 60 * 24,
alignment: 'right',
horizontal_padding: intercomBubblePosition.value.horizontalPadding,
vertical_padding: intercomBubblePosition.value.verticalPadding,
})
intercomBooted = true
} catch (error) {
console.warn('[APP][INTERCOM] failed to initialize secure support chat', error)
} finally {
intercomBooting = false
}
}
function shutdownHostingIntercom() {
if (!intercomBooted && !intercomBooting) return
shutdownIntercom()
intercomBooting = false
intercomBooted = false
}
watch(
intercomBubblePosition,
(position) => {
updateIntercomBubbleStyles(position)
if (intercomBooted) {
window.Intercom?.('update', {
horizontal_padding: position.horizontalPadding,
vertical_padding: position.verticalPadding,
})
}
},
{ immediate: true },
)
watch(
[hostingRouteActive, credentials],
([active]) => {
if (active) {
void bootIntercom()
} else {
shutdownHostingIntercom()
}
},
{ immediate: true },
)
watch(showAd, () => {
if (!showAd.value) {
@@ -789,9 +586,7 @@ async function handleCommand(e) {
if (e.event === 'RunMRPack') {
// RunMRPack should directly install a local mrpack given a path
if (e.path.endsWith('.mrpack')) {
await create_profile_and_install_from_file(e.path, (createProfile, fileName) =>
unknownPackWarningModal.value?.show(createProfile, fileName),
).catch(handleError)
await create_profile_and_install_from_file(e.path).catch(handleError)
trackEvent('InstanceCreate', {
source: 'CreationModalFileDrop',
})
@@ -927,7 +722,6 @@ async function checkUpdates() {
{
label: formatMessage(updatePopupMessages.changelog),
action: () => openUrl('https://modrinth.com/news/changelog?filter=app'),
keepOpen: true,
},
],
})
@@ -1010,7 +804,6 @@ async function downloadUpdate(versionToDownload) {
{
label: formatMessage(updatePopupMessages.changelog),
action: () => openUrl('https://modrinth.com/news/changelog?filter=app'),
keepOpen: true,
},
],
})
@@ -1026,40 +819,11 @@ async function downloadUpdate(versionToDownload) {
async function installUpdate() {
restarting.value = true
try {
await setRestartAfterPendingUpdate(true)
} catch (e) {
restarting.value = false
handleError(e)
return
}
setTimeout(async () => {
await handleClose()
}, 250)
}
async function openModrinthProjectLinkInApp(parsed) {
const { slug, pathSuffix, url } = parsed
const loadToken = loading.begin()
try {
const { id } = await tauriApiClient.labrinth.projects_v2.check(slug)
const query = mergeUrlQuery(route.query, url)
await router.push({
path: `/project/${id}${pathSuffix}`,
query,
hash: url.hash || undefined,
})
} catch (err) {
if (err instanceof ModrinthApiError && err.statusCode === 404) {
openUrl(url.href)
} else {
handleError(err)
}
} finally {
loading.end(loadToken)
}
}
function handleClick(e) {
let target = e.target
while (target != null) {
@@ -1072,12 +836,7 @@ function handleClick(e) {
!target.href.startsWith('https://tauri.localhost') &&
!target.href.startsWith('http://tauri.localhost')
) {
const parsed = parseModrinthLink(target.href)
if (target.target !== '_blank' && parsed) {
void openModrinthProjectLinkInApp(parsed)
} else {
openUrl(target.href)
}
openUrl(target.href)
}
e.preventDefault()
break
@@ -1218,7 +977,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
<div id="teleports"></div>
<div
v-if="stateInitialized"
class="app-grid-layout relative"
class="app-grid-layout experimental-styles-within relative"
:class="{ 'disable-advanced-rendering': !themeStore.advancedRendering }"
>
<Transition name="fade">
@@ -1249,11 +1008,9 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
:fetch-existing-instance-names="fetchExistingInstanceNames"
:search-modpacks="searchModpacks"
:get-project-versions="getProjectVersions"
:get-loader-manifest="getLoaderManifest"
@create="handleCreate"
@browse-modpacks="handleBrowseModpacks"
/>
<UnknownPackWarningModal ref="unknownPackWarningModal" />
<div
class="app-grid-navbar bg-bg-raised flex flex-col p-[0.5rem] pt-0 gap-[0.5rem] w-[--left-bar-width]"
>
@@ -1410,16 +1167,31 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
</ButtonStyled>
<div class="flex mr-3">
<Suspense>
<AppActionBar />
<RunningAppBar />
</Suspense>
</div>
<WindowControls />
<section v-if="!nativeDecorations" class="window-controls" data-tauri-drag-region-exclude>
<Button class="titlebar-button" icon-only @click="() => getCurrentWindow().minimize()">
<MinimizeIcon />
</Button>
<Button
class="titlebar-button"
icon-only
@click="() => getCurrentWindow().toggleMaximize()"
>
<RestoreIcon v-if="isMaximized" />
<MaximizeIcon v-else />
</Button>
<Button class="titlebar-button close" icon-only @click="handleClose">
<XIcon />
</Button>
</section>
</section>
</div>
</div>
<div
v-if="stateInitialized"
class="app-contents"
class="app-contents experimental-styles-within"
:class="{
'sidebar-enabled': sidebarVisible,
'disable-advanced-rendering': !themeStore.advancedRendering,
@@ -1456,7 +1228,7 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
width: 'calc(100% - var(--left-bar-width) - var(--right-bar-width))',
}"
>
<LoadingBar position="absolute" />
<ModrinthLoadingIndicator />
</div>
<div
v-if="themeStore.featureFlags.page_path"
@@ -1492,36 +1264,44 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
</Admonition>
<RouterView v-slot="{ Component }">
<template v-if="Component">
<Suspense @pending="onSuspensePending" @resolve="onSuspenseResolve">
<Suspense
@pending="
() => {
suspensePending = true
loading.startLoading()
}
"
@resolve="loading.stopLoading()"
>
<component :is="Component"></component>
</Suspense>
</template>
</RouterView>
</div>
<div
class="app-sidebar mt-px shrink-0 flex flex-col border-0 border-l-[1px] border-[--brand-gradient-border] border-solid"
class="app-sidebar mt-px shrink-0 flex flex-col border-0 border-l-[1px] border-[--brand-gradient-border] border-solid overflow-auto"
:class="{ 'has-plus': hasPlus }"
>
<div
v-overlay-scrollbars="sidebarOverlayScrollbarsOptions"
class="app-sidebar-scrollable flex-grow shrink relative"
class="app-sidebar-scrollable flex-grow shrink overflow-y-auto relative"
:class="{ 'pb-12': !hasPlus }"
data-overlayscrollbars-initialize
>
<div id="sidebar-teleport-target" class="sidebar-teleport-content"></div>
<div class="sidebar-default-content" :class="{ 'sidebar-enabled': sidebarVisible }">
<div class="p-4 border-0 border-b-[1px] border-[--brand-gradient-border] border-solid">
<div
class="p-4 pr-1 border-0 border-b-[1px] border-[--brand-gradient-border] border-solid"
>
<h3 class="text-base text-primary font-medium m-0">Playing as</h3>
<suspense>
<AccountsCard ref="accounts" />
<AccountsCard ref="accounts" mode="small" />
</suspense>
</div>
<div class="p-4 border-0 border-b-[1px] border-[--brand-gradient-border] border-solid">
<div class="py-4 border-0 border-b-[1px] border-[--brand-gradient-border] border-solid">
<suspense>
<FriendsList :credentials="credentials" :sign-in="() => signIn()" />
</suspense>
</div>
<div v-if="news && news.length > 0" class="p-4 flex flex-col items-center">
<div v-if="news && news.length > 0" class="p-4 pr-1 flex flex-col items-center">
<h3 class="text-base mb-4 text-primary font-medium m-0 text-left w-full">News</h3>
<div class="space-y-4 flex flex-col items-center w-full">
<NewsArticleCard
@@ -1588,6 +1368,72 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
</template>
<style lang="scss" scoped>
.window-controls {
z-index: 20;
display: none;
flex-direction: row;
align-items: center;
.titlebar-button {
display: flex;
align-items: center;
justify-content: center;
cursor: pointer;
transition: all ease-in-out 0.1s;
background-color: transparent;
color: var(--color-base);
height: 100%;
width: 3rem;
position: relative;
box-shadow: none;
&:last-child {
padding-right: 0.75rem;
width: 3.75rem;
}
svg {
width: 1.25rem;
height: 1.25rem;
}
&::before {
content: '';
border-radius: 999999px;
width: 3rem;
height: 3rem;
aspect-ratio: 1 / 1;
margin-block: auto;
position: absolute;
background-color: transparent;
scale: 0.9;
transition: all ease-in-out 0.2s;
z-index: -1;
}
&.close {
&:hover,
&:active {
color: var(--color-accent-contrast);
&::before {
background-color: var(--color-red);
}
}
}
&:hover,
&:active {
color: var(--color-contrast);
&::before {
background-color: var(--color-button-bg);
scale: 1;
}
}
}
}
.app-grid-layout,
.app-contents {
--top-bar-height: 3rem;
@@ -1608,15 +1454,10 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
.app-grid-navbar {
grid-area: nav;
position: relative;
z-index: 2;
}
.app-grid-statusbar {
grid-area: status;
padding-right: var(--window-controls-width, 0px);
position: relative;
z-index: 2;
}
[data-tauri-drag-region-exclude] {
@@ -1684,12 +1525,6 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
&.app-contents::before {
box-shadow: none;
}
*,
:deep(*) {
box-shadow: none !important;
--tw-drop-shadow:;
}
}
.app-sidebar::before {
@@ -1708,11 +1543,10 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
height: 100%;
overflow: auto;
overflow-x: hidden;
scrollbar-gutter: stable;
}
.app-contents::before {
z-index: 30;
z-index: 1;
content: '';
position: fixed;
left: var(--left-bar-width);
@@ -1815,21 +1649,6 @@ provideAppUpdateDownloadProgress(appUpdateDownload)
}
</style>
<style>
.os-theme-dark,
.os-theme-light {
--os-handle-bg: var(--color-scrollbar) !important;
--os-handle-bg-hover: var(--color-scrollbar) !important;
--os-handle-bg-active: var(--color-scrollbar) !important;
}
.intercom-lightweight-app-launcher,
.intercom-launcher-frame,
iframe[name='intercom-launcher-frame'] {
right: var(--app-support-launcher-right, 20px) !important;
bottom: var(--app-support-launcher-bottom, 20px) !important;
z-index: 9 !important;
}
.mac {
.app-grid-statusbar {
padding-left: 5rem;
@@ -1841,6 +1660,10 @@ iframe[name='intercom-launcher-frame'] {
height: 2.5rem !important;
}
.window-controls {
display: flex !important;
}
.info-card {
right: 22rem;
}
@@ -180,6 +180,13 @@ img {
}
}
button,
input[type='button'] {
cursor: pointer;
border: none;
outline: 2px solid transparent;
}
@import '@modrinth/assets/omorphia.scss';
input {
@@ -10,7 +10,6 @@ import {
TrashIcon,
} from '@modrinth/assets'
import {
Accordion,
DropdownSelect,
formatLoader,
injectNotificationManager,
@@ -134,33 +133,12 @@ const state = useStorage(
{
group: 'Group',
sortBy: 'Name',
collapsedGroups: [],
},
localStorage,
{ mergeDefaults: true },
)
const search = ref('')
const collapsedSectionKeys = computed(() => new Set(state.value.collapsedGroups ?? []))
const getSectionKey = (sectionName) => `${state.value.group}:${sectionName}`
const isSectionCollapsed = (sectionName) => {
return collapsedSectionKeys.value.has(getSectionKey(sectionName))
}
const setSectionCollapsed = (sectionName, collapsed) => {
const sectionKey = getSectionKey(sectionName)
const collapsedSections = new Set(state.value.collapsedGroups ?? [])
if (collapsed) {
collapsedSections.add(sectionKey)
} else {
collapsedSections.delete(sectionKey)
}
state.value.collapsedGroups = [...collapsedSections]
}
const filteredResults = computed(() => {
const { group = 'Group', sortBy = 'Name' } = state.value
@@ -302,21 +280,18 @@ const filteredResults = computed(() => {
<span class="font-semibold text-secondary">{{ selected }}</span>
</DropdownSelect>
</div>
<Accordion
<div
v-for="instanceSection in Array.from(filteredResults, ([key, value]) => ({
key,
value,
}))"
:key="instanceSection.key"
:divider="instanceSection.key !== 'None'"
:open-by-default="!isSectionCollapsed(instanceSection.key)"
class="row"
@on-open="setSectionCollapsed(instanceSection.key, false)"
@on-close="setSectionCollapsed(instanceSection.key, true)"
>
<template v-if="instanceSection.key !== 'None'" #title>
<span class="text-base">{{ instanceSection.key }}</span>
</template>
<div v-if="instanceSection.key !== 'None'" class="divider">
<p>{{ instanceSection.key }}</p>
<hr aria-hidden="true" />
</div>
<section class="instances">
<Instance
v-for="instance in instanceSection.value"
@@ -326,7 +301,7 @@ const filteredResults = computed(() => {
@contextmenu.prevent.stop="(event) => handleRightClick(event, instance.path)"
/>
</section>
</Accordion>
</div>
<ConfirmDeleteInstanceModal ref="confirmModal" @delete="deleteProfile" />
<ContextMenu ref="instanceOptions" @option-clicked="handleOptionsClick">
<template #play> <PlayIcon /> Play </template>
@@ -341,7 +316,73 @@ const filteredResults = computed(() => {
</template>
<style lang="scss" scoped>
.row {
display: flex;
flex-direction: column;
align-items: flex-start;
width: 100%;
.divider {
display: flex;
justify-content: space-between;
align-items: center;
width: 100%;
gap: 1rem;
margin-bottom: 1rem;
p {
margin: 0;
font-size: 1rem;
white-space: nowrap;
color: var(--color-contrast);
}
hr {
background-color: var(--color-gray);
height: 1px;
width: 100%;
border: none;
}
}
}
.header {
display: flex;
flex-direction: row;
flex-wrap: wrap;
justify-content: space-between;
gap: 1rem;
align-items: inherit;
margin: 1rem 1rem 0 !important;
padding: 1rem;
width: calc(100% - 2rem);
.iconified-input {
flex-grow: 1;
input {
min-width: 100%;
}
}
.sort-dropdown {
width: 10rem;
}
.filter-dropdown {
width: 15rem;
}
.group-dropdown {
width: 10rem;
}
.labeled_button {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.5rem;
white-space: nowrap;
}
}
.instances {
@@ -0,0 +1,142 @@
<script setup>
import { computed, onBeforeUnmount, ref, watch } from 'vue'
import { useLoading } from '@/store/state.js'
const props = defineProps({
throttle: {
type: Number,
default: 0,
},
duration: {
type: Number,
default: 1000,
},
height: {
type: Number,
default: 2,
},
color: {
type: String,
default: 'var(--loading-bar-gradient)',
},
})
const indicator = useLoadingIndicator({
duration: props.duration,
throttle: props.throttle,
})
onBeforeUnmount(() => indicator.clear)
const loading = useLoading()
watch(loading, (newValue) => {
if (newValue.barEnabled) {
if (newValue.loading) {
indicator.start()
} else {
indicator.finish()
}
}
})
function useLoadingIndicator(opts) {
const progress = ref(0)
const isLoading = ref(false)
const step = computed(() => 10000 / opts.duration)
let _timer = null
let _throttle = null
function start() {
clear()
progress.value = 0
if (opts.throttle) {
_throttle = setTimeout(() => {
isLoading.value = true
_startTimer()
}, opts.throttle)
} else {
isLoading.value = true
_startTimer()
}
}
function finish() {
progress.value = 100
_hide()
}
function clear() {
clearInterval(_timer)
clearTimeout(_throttle)
_timer = null
_throttle = null
}
function _increase(num) {
progress.value = Math.min(100, progress.value + num)
}
function _hide() {
clear()
setTimeout(() => {
isLoading.value = false
setTimeout(() => {
progress.value = 0
}, 400)
}, 500)
}
function _startTimer() {
_timer = setInterval(() => {
_increase(step.value)
}, 100)
}
return { progress, isLoading, start, finish, clear }
}
</script>
<template>
<div
class="loading-indicator-bar"
:style="{
'--_width': `${indicator.progress.value}%`,
'--_height': `${indicator.isLoading.value ? props.height : 0}px`,
'--_opacity': `${indicator.isLoading.value ? 1 : 0}`,
top: `0`,
right: `0`,
left: `${props.offsetWidth}`,
pointerEvents: 'none',
width: `var(--_width)`,
height: `var(--_height)`,
borderRadius: `var(--_height)`,
// opacity: `var(--_opacity)`,
background: `${props.color}`,
backgroundSize: `${(100 / indicator.progress.value) * 100}% auto`,
transition: 'width 0.1s ease-in-out, height 0.1s ease-out',
zIndex: 6,
}"
>
<slot />
</div>
</template>
<style lang="scss" scoped>
.loading-indicator-bar::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
width: var(--_width);
bottom: 0;
background-image: radial-gradient(80% 100% at 20% 0%, var(--color-brand) 0%, transparent 80%);
opacity: calc(var(--_opacity) * 0.1);
z-index: 5;
transition:
width 0.1s ease-in-out,
opacity 0.1s ease-out;
}
</style>
@@ -149,7 +149,7 @@ const handleOptionsClick = async (args) => {
break
case 'edit':
await router.push({
path: `/instance/${encodeURIComponent(args.item.path)}`,
path: `/instance/${encodeURIComponent(args.item.path)}/`,
})
break
case 'duplicate':
@@ -1,107 +1,81 @@
<template>
<div
v-if="accounts.length === 0"
class="flex flex-col gap-3 bg-button-bg border border-solid border-surface-5 rounded-xl p-3 mt-2"
v-if="mode !== 'isolated'"
ref="button"
class="button-base mt-2 px-3 py-2 bg-button-bg rounded-xl flex items-center gap-2"
:class="{ expanded: mode === 'expanded' }"
@click="toggleMenu"
>
<span>{{ formatMessage(messages.notSignedIn) }}</span>
<ButtonStyled color="brand">
<button color="primary" :disabled="loginDisabled" @click="login()">
<LogInIcon v-if="!loginDisabled" />
<SpinnerIcon v-else class="animate-spin" />
{{ formatMessage(messages.signInToMinecraft) }}
</button>
</ButtonStyled>
</div>
<Accordion
v-else
class="w-full mt-2 bg-button-bg border border-solid border-surface-5 rounded-xl overflow-clip"
button-class="button-base w-full bg-transparent px-3 py-2 border-0 cursor-pointer"
:open-by-default="false"
>
<template #title>
<div class="flex gap-2 w-full min-w-0">
<Avatar
size="36px"
:src="
selectedAccount
? avatarUrl
: 'https://launcher-files.modrinth.com/assets/steve_head.png'
"
/>
<div class="flex flex-col items-start w-full min-w-0">
<span class="truncate w-full text-left">{{
selectedAccount ? selectedAccount.profile.name : formatMessage(messages.selectAccount)
}}</span>
<span class="text-secondary text-xs">{{ formatMessage(messages.minecraftAccount) }}</span>
</div>
</div>
</template>
<div class="bg-button-bg pt-1 pb-2 border border-solid border-surface-5">
<template v-if="accounts.length > 0">
<div v-for="account in accounts" :key="account.profile.id" class="flex gap-1 items-center">
<button
class="flex items-center flex-shrink flex-grow overflow-clip gap-2 p-2 border-0 bg-transparent cursor-pointer button-base min-w-0"
@click="setAccount(account)"
>
<RadioButtonCheckedIcon
v-if="selectedAccount && selectedAccount.profile.id === account.profile.id"
class="w-5 h-5 text-brand shrink-0"
/>
<RadioButtonIcon v-else class="w-5 h-5 text-secondary shrink-0" />
<Avatar :src="getAccountAvatarUrl(account)" size="24px" />
<p
class="m-0 truncate min-w-0"
:class="
selectedAccount && selectedAccount.profile.id === account.profile.id
? 'text-contrast font-semibold'
: 'text-primary'
"
>
{{ account.profile.name }}
</p>
</button>
<ButtonStyled circular color="red" color-fill="none" hover-color-fill="background">
<button
v-tooltip="formatMessage(messages.removeAccount)"
class="mr-2"
@click="logout(account.profile.id)"
>
<TrashIcon />
</button>
</ButtonStyled>
</div>
</template>
<div class="flex flex-col gap-2 px-2 pt-2">
<ButtonStyled v-if="accounts.length > 0" class="w-full">
<button :disabled="loginDisabled" @click="login()">
<PlusIcon />
{{ formatMessage(messages.addAccount) }}
</button>
</ButtonStyled>
</div>
<Avatar
size="36px"
:src="
selectedAccount ? avatarUrl : 'https://launcher-files.modrinth.com/assets/steve_head.png'
"
/>
<div class="flex flex-col w-full">
<span>{{ selectedAccount ? selectedAccount.profile.name : 'Select account' }}</span>
<span class="text-secondary text-xs">Minecraft account</span>
</div>
</Accordion>
<DropdownIcon class="w-5 h-5 shrink-0" />
</div>
<transition name="fade">
<Card
v-if="showCard || mode === 'isolated'"
ref="card"
class="account-card"
:class="{ expanded: mode === 'expanded', isolated: mode === 'isolated' }"
>
<div v-if="selectedAccount" class="selected account">
<Avatar size="xs" :src="avatarUrl" />
<div>
<h4>{{ selectedAccount.profile.name }}</h4>
<p>Selected</p>
</div>
<Button
v-tooltip="'Log out'"
icon-only
color="raised"
@click="logout(selectedAccount.profile.id)"
>
<TrashIcon />
</Button>
</div>
<div v-else class="logged-out account">
<h4>Not signed in</h4>
<Button
v-tooltip="'Log in'"
:disabled="loginDisabled"
icon-only
color="primary"
@click="login()"
>
<LogInIcon v-if="!loginDisabled" />
<SpinnerIcon v-else class="animate-spin" />
</Button>
</div>
<div v-if="displayAccounts.length > 0" class="account-group">
<div v-for="account in displayAccounts" :key="account.profile.id" class="account-row">
<Button class="option account" @click="setAccount(account)">
<Avatar :src="getAccountAvatarUrl(account)" class="icon" />
<p>{{ account.profile.name }}</p>
</Button>
<Button v-tooltip="'Log out'" icon-only @click="logout(account.profile.id)">
<TrashIcon />
</Button>
</div>
</div>
<Button v-if="accounts.length > 0" @click="login()">
<PlusIcon />
Add account
</Button>
</Card>
</transition>
</template>
<script setup lang="ts">
import {
LogInIcon,
PlusIcon,
RadioButtonCheckedIcon,
RadioButtonIcon,
SpinnerIcon,
TrashIcon,
} from '@modrinth/assets'
import {
Accordion,
Avatar,
ButtonStyled,
defineMessages,
injectNotificationManager,
useVIntl,
} from '@modrinth/ui'
import type { Ref } from 'vue'
import { computed, onUnmounted, ref } from 'vue'
<script setup>
import { DropdownIcon, LogInIcon, PlusIcon, SpinnerIcon, TrashIcon } from '@modrinth/assets'
import { Avatar, Button, Card, injectNotificationManager } from '@modrinth/ui'
import { computed, onBeforeUnmount, onMounted, onUnmounted, ref } from 'vue'
import { trackEvent } from '@/helpers/analytics'
import {
@@ -113,39 +87,34 @@ import {
} from '@/helpers/auth'
import { process_listener } from '@/helpers/events'
import { getPlayerHeadUrl } from '@/helpers/rendering/batch-skin-renderer.ts'
import type { Skin } from '@/helpers/skins'
import { get_available_skins } from '@/helpers/skins'
import { handleSevereError } from '@/store/error.js'
const { formatMessage } = useVIntl()
const { handleError } = injectNotificationManager()
const emit = defineEmits<{
change: []
}>()
defineProps({
mode: {
type: String,
required: true,
default: 'normal',
},
})
type MinecraftCredential = {
profile: {
id: string
name: string
}
}
const emit = defineEmits(['change'])
const accounts: Ref<MinecraftCredential[]> = ref([])
const accounts = ref({})
const loginDisabled = ref(false)
const defaultUser = ref<string | undefined>()
const equippedSkin = ref<Skin | null>(null)
const headUrlCache = ref(new Map<string, string>())
const defaultUser = ref()
const equippedSkin = ref(null)
const headUrlCache = ref(new Map())
async function refreshValues() {
defaultUser.value = await get_default_user().catch(handleError)
const userList = await users().catch(handleError)
accounts.value = Array.isArray(userList) ? [...userList] : []
accounts.value.sort((a, b) => (a.profile?.name ?? '').localeCompare(b.profile?.name ?? ''))
accounts.value = await users().catch(handleError)
try {
const skins = await get_available_skins()
equippedSkin.value = skins.find((skin) => skin.is_equipped) ?? null
equippedSkin.value = skins.find((skin) => skin.is_equipped)
if (equippedSkin.value) {
try {
@@ -160,7 +129,7 @@ async function refreshValues() {
}
}
function setLoginDisabled(value: boolean) {
function setLoginDisabled(value) {
loginDisabled.value = value
}
@@ -169,11 +138,10 @@ defineExpose({
setLoginDisabled,
loginDisabled,
})
await refreshValues()
const selectedAccount = computed(() =>
accounts.value.find((account) => account.profile.id === defaultUser.value),
const displayAccounts = computed(() =>
accounts.value.filter((account) => defaultUser.value !== account.profile.id),
)
const avatarUrl = computed(() => {
@@ -190,7 +158,7 @@ const avatarUrl = computed(() => {
return 'https://launcher-files.modrinth.com/assets/steve_head.png'
})
function getAccountAvatarUrl(account: MinecraftCredential) {
function getAccountAvatarUrl(account) {
if (
account.profile.id === selectedAccount.value?.profile?.id &&
equippedSkin.value?.texture_key
@@ -203,10 +171,13 @@ function getAccountAvatarUrl(account: MinecraftCredential) {
return `https://mc-heads.net/avatar/${account.profile.id}/128`
}
async function setAccount(account: MinecraftCredential) {
const selectedAccount = computed(() =>
accounts.value.find((account) => account.profile.id === defaultUser.value),
)
async function setAccount(account) {
defaultUser.value = account.profile.id
await set_default_user(account.profile.id).catch(handleError)
await refreshValues()
emit('change')
}
@@ -216,57 +187,292 @@ async function login() {
if (loggedIn) {
await setAccount(loggedIn)
await refreshValues()
}
trackEvent('AccountLogIn')
loginDisabled.value = false
}
async function logout(id: string) {
const logout = async (id) => {
await remove_user(id).catch(handleError)
await refreshValues()
if (!selectedAccount.value && accounts.value.length > 0) {
await setAccount(accounts.value[0])
await refreshValues()
} else {
emit('change')
}
trackEvent('AccountLogOut')
}
const showCard = ref(false)
const card = ref(null)
const button = ref(null)
const handleClickOutside = (event) => {
const elements = document.elementsFromPoint(event.clientX, event.clientY)
if (
card.value &&
card.value.$el !== event.target &&
!elements.includes(card.value.$el) &&
!button.value.contains(event.target)
) {
toggleMenu(false)
}
}
function toggleMenu(override = true) {
if (showCard.value || !override) {
showCard.value = false
} else {
showCard.value = true
}
}
const unlisten = await process_listener(async (e) => {
if (e.event === 'launched') {
await refreshValues()
}
})
onMounted(() => {
window.addEventListener('click', handleClickOutside)
})
onBeforeUnmount(() => {
window.removeEventListener('click', handleClickOutside)
})
onUnmounted(() => {
unlisten()
})
const messages = defineMessages({
notSignedIn: {
id: 'minecraft-account.not-signed-in',
defaultMessage: 'Not signed in',
},
addAccount: {
id: 'minecraft-account.add-account',
defaultMessage: 'Add account',
},
removeAccount: {
id: 'minecraft-account.remove-account',
defaultMessage: 'Remove account',
},
selectAccount: {
id: 'minecraft-account.select-account',
defaultMessage: 'Select account',
},
minecraftAccount: {
id: 'minecraft-account.label',
defaultMessage: 'Minecraft account',
},
signInToMinecraft: {
id: 'minecraft-account.sign-in',
defaultMessage: 'Sign in to Minecraft',
},
})
</script>
<style scoped lang="scss">
.selected {
background: var(--color-brand-highlight);
border-radius: var(--radius-lg);
color: var(--color-contrast);
gap: 1rem;
}
.logged-out {
background: var(--color-bg);
border-radius: var(--radius-lg);
gap: 1rem;
}
.account {
width: max-content;
display: flex;
align-items: center;
text-align: left;
padding: 0.5rem 1rem;
h4,
p {
margin: 0;
}
}
.account-card {
position: fixed;
display: flex;
flex-direction: column;
margin-top: 0.5rem;
right: 2rem;
z-index: 11;
gap: 0.5rem;
padding: 1rem;
border: 1px solid var(--color-divider);
width: max-content;
user-select: none;
-ms-user-select: none;
-webkit-user-select: none;
max-height: calc(100vh - 300px);
overflow-y: auto;
&::-webkit-scrollbar-track {
border-top-right-radius: 1rem;
border-bottom-right-radius: 1rem;
}
&::-webkit-scrollbar {
border-top-right-radius: 1rem;
border-bottom-right-radius: 1rem;
}
&.hidden {
display: none;
}
&.expanded {
left: 13.5rem;
}
&.isolated {
position: relative;
left: 0;
top: 0;
}
}
.accounts-title {
font-size: 1.2rem;
font-weight: bolder;
}
.account-group {
width: 100%;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.option {
width: calc(100% - 2.25rem);
background: var(--color-raised-bg);
color: var(--color-base);
box-shadow: none;
img {
margin-right: 0.5rem;
}
}
.icon {
--size: 1.5rem !important;
}
.account-row {
display: flex;
flex-direction: row;
gap: 0.5rem;
vertical-align: center;
justify-content: space-between;
padding-right: 1rem;
}
.fade-enter-active,
.fade-leave-active {
transition:
opacity 0.25s ease,
translate 0.25s ease,
scale 0.25s ease;
}
.fade-enter-from,
.fade-leave-to {
opacity: 0;
translate: 0 -2rem;
scale: 0.9;
}
.avatar-button {
display: flex;
align-items: center;
gap: 0.5rem;
color: var(--color-base);
background-color: var(--color-button-bg);
border-radius: var(--radius-md);
width: 100%;
padding: 0.5rem 0.75rem;
text-align: left;
&.expanded {
border: 1px solid var(--color-divider);
padding: 1rem;
}
}
.avatar-text {
margin: auto 0 auto 0.25rem;
display: flex;
flex-direction: column;
}
.text {
width: 6rem;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.accounts-text {
display: flex;
align-items: center;
gap: 0.25rem;
margin: 0;
}
.qr-code {
background-color: white !important;
border-radius: var(--radius-md);
}
.modal-body {
display: flex;
flex-direction: row;
gap: var(--gap-lg);
align-items: center;
padding: var(--gap-xl);
.modal-text {
display: flex;
flex-direction: column;
gap: var(--gap-sm);
width: 100%;
h2,
p {
margin: 0;
}
.code-text {
display: flex;
flex-direction: row;
gap: var(--gap-xs);
align-items: center;
.code {
background-color: var(--color-bg);
border-radius: var(--radius-md);
border: solid 1px var(--color-button-bg);
font-family: var(--mono-font);
letter-spacing: var(--gap-md);
color: var(--color-contrast);
font-size: 2rem;
font-weight: bold;
padding: var(--gap-sm) 0 var(--gap-sm) var(--gap-md);
}
.btn {
width: 2.5rem;
height: 2.5rem;
}
}
}
}
.button-row {
display: flex;
flex-direction: row;
}
.modal {
position: absolute;
}
.code {
color: var(--color-brand);
padding: 0.05rem 0.1rem;
// row not column
display: flex;
.card {
background: var(--color-base);
color: var(--color-contrast);
padding: 0.5rem 1rem;
}
}
</style>
@@ -1,434 +0,0 @@
<template>
<div class="flex gap-4 items-center">
<ButtonStyled
v-if="hasActiveLoadingBars && !hasVisibleActiveDownloadToasts"
color="brand"
type="transparent"
circular
>
<button v-tooltip="formatMessage(messages.viewActiveDownloads)" @click="openDownloadToast()">
<DownloadIcon />
</button>
</ButtonStyled>
<div v-if="offline" class="flex items-center gap-1">
<UnplugIcon class="text-secondary" />
<span class="text-sm text-contrast"> {{ formatMessage(messages.offline) }} </span>
</div>
<div
class="flex border-solid border-surface-5 text-sm items-center gap-2 py-1.5 px-3 rounded-xl border"
>
<template v-if="selectedProcess">
<OnlineIndicatorIcon />
<div class="text-contrast flex items-center gap-2">
<router-link
v-tooltip="formatMessage(messages.viewInstance)"
:to="`/instance/${encodeURIComponent(selectedProcess.profile.path)}`"
class="hover:underline"
>
{{ selectedProcess.profile.name }}
</router-link>
<Dropdown
v-if="currentProcesses.length > 1"
placement="bottom"
:triggers="['click']"
:hide-triggers="['click']"
@show="showProfiles = true"
@hide="showProfiles = false"
>
<ButtonStyled type="transparent" circular size="small">
<button
v-tooltip="
showProfiles
? formatMessage(messages.hideMoreRunningInstances)
: formatMessage(messages.showMoreRunningInstances)
"
>
<DropdownIcon :class="{ 'rotate-180': !!showProfiles }" />
</button>
</ButtonStyled>
<template #popper>
<div class="flex w-[20rem] max-h-[24rem] flex-col gap-2 overflow-auto">
<div
v-for="process in currentProcesses"
:key="process.uuid"
class="flex w-full items-center gap-2 rounded-xl bg-surface-4 p-2 text-sm"
>
<button
v-tooltip.left="
process.uuid === selectedProcess.uuid
? formatMessage(messages.primaryInstance)
: formatMessage(messages.makePrimaryInstance)
"
class="flex flex-grow items-center gap-2"
:class="{
'active:scale-95 transition-transform': process.uuid !== selectedProcess.uuid,
}"
:disabled="process.uuid === selectedProcess.uuid"
@click="selectProcess(process)"
>
<OnlineIndicatorIcon />
<span class="mr-auto text-contrast flex items-center gap-2">
{{ process.profile.name }}
<StarIcon v-if="process.uuid === selectedProcess.uuid" class="text-orange" />
</span>
</button>
<button
v-tooltip="formatMessage(messages.stopInstance)"
class="active:scale-95 flex"
@click.stop="stop(process)"
>
<StopCircleIcon class="text-red size-5" />
</button>
<button
v-tooltip="formatMessage(messages.viewLogs)"
class="active:scale-95 flex"
@click.stop="goToTerminal(process.profile.path)"
>
<TerminalSquareIcon class="text-secondary size-5" />
</button>
</div>
</div>
</template>
</Dropdown>
</div>
<button
v-tooltip="formatMessage(messages.stopInstance)"
class="active:scale-95 flex"
@click="stop(selectedProcess)"
>
<StopCircleIcon class="text-red size-5" />
</button>
<button
v-tooltip="formatMessage(messages.viewLogs)"
class="active:scale-95 flex"
@click="goToTerminal()"
>
<TerminalSquareIcon class="text-secondary size-5" />
</button>
</template>
<template v-else>
<span class="size-2 rounded-full bg-secondary" />
<span class="text-secondary"> {{ formatMessage(messages.noInstancesRunning) }} </span>
</template>
</div>
</div>
</template>
<script setup lang="ts">
import {
DownloadIcon,
DropdownIcon,
OnlineIndicatorIcon,
StarIcon,
StopCircleIcon,
TerminalSquareIcon,
UnplugIcon,
} from '@modrinth/assets'
import {
ButtonStyled,
defineMessages,
injectNotificationManager,
injectPopupNotificationManager,
type PopupNotification,
type PopupNotificationProgressItem,
useVIntl,
} from '@modrinth/ui'
import { Dropdown } from 'floating-vue'
import { computed, onBeforeUnmount, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import { trackEvent } from '@/helpers/analytics'
import { loading_listener, process_listener } from '@/helpers/events'
import { get_all as getRunningProcesses, kill as killProcess } from '@/helpers/process'
import { get_many as getInstances } from '@/helpers/profile.js'
import type { LoadingBar } from '@/helpers/state'
import { progress_bars_list } from '@/helpers/state'
import type { GameInstance } from '@/helpers/types'
const { handleError } = injectNotificationManager()
const popupNotificationManager = injectPopupNotificationManager()
const { formatMessage } = useVIntl()
const router = useRouter()
const showProfiles = ref(false)
interface RunningProcess {
uuid: string
profile_path: string
profile: GameInstance
}
const messages = defineMessages({
offline: {
id: 'app.action-bar.offline',
defaultMessage: 'Offline',
},
viewInstance: {
id: 'app.action-bar.view-instance',
defaultMessage: 'View instance',
},
showMoreRunningInstances: {
id: 'app.action-bar.show-more-running-instances',
defaultMessage: 'Show more running instances',
},
hideMoreRunningInstances: {
id: 'app.action-bar.hide-more-running-instances',
defaultMessage: 'Hide more running instances',
},
primaryInstance: {
id: 'app.action-bar.primary-instance',
defaultMessage: 'Primary instance',
},
makePrimaryInstance: {
id: 'app.action-bar.make-primary-instance',
defaultMessage: 'Make primary instance',
},
stopInstance: {
id: 'app.action-bar.stop-instance',
defaultMessage: 'Stop instance',
},
viewLogs: {
id: 'app.action-bar.view-logs',
defaultMessage: 'View logs',
},
noInstancesRunning: {
id: 'app.action-bar.no-instances-running',
defaultMessage: 'No instances running',
},
downloadingJava: {
id: 'app.action-bar.downloading-java',
defaultMessage: 'Downloading Java {version}',
},
downloads: {
id: 'app.action-bar.downloads',
defaultMessage: 'Downloads',
},
viewActiveDownloads: {
id: 'app.action-bar.view-active-downloads',
defaultMessage: 'View active downloads',
},
})
const currentProcesses = ref<RunningProcess[]>([])
const selectedProcess = ref<RunningProcess | undefined>()
const refresh = async () => {
const processes = ((await getRunningProcesses().catch((error) => {
handleError(error)
return []
})) ?? []) as Array<{ uuid: string; profile_path: string }>
const paths = processes.map((process) => process.profile_path)
const profiles: GameInstance[] = await getInstances(paths).catch((error) => {
handleError(error)
return []
})
currentProcesses.value = processes
.map((process) => {
const profile = profiles.find((item) => process.profile_path === item.path)
if (!profile) {
return null
}
return {
...process,
profile,
}
})
.filter((process): process is RunningProcess => process !== null)
if (!selectedProcess.value || !currentProcesses.value.includes(selectedProcess.value)) {
selectedProcess.value = currentProcesses.value[0]
}
}
await refresh()
const offline = ref(!navigator.onLine)
function handleOffline() {
offline.value = true
}
function handleOnline() {
offline.value = false
}
onMounted(() => {
window.addEventListener('offline', handleOffline)
window.addEventListener('online', handleOnline)
})
const unlistenProcess = await process_listener(async () => {
await refresh()
})
const stop = async (process: RunningProcess) => {
try {
await killProcess(process.uuid).catch(handleError)
trackEvent('InstanceStop', {
loader: process.profile.loader,
game_version: process.profile.game_version,
source: 'AppBar',
})
} catch (e) {
console.error(e)
}
await refresh()
}
function goToTerminal(path?: string) {
const selectedPath = path ?? selectedProcess.value?.profile.path
if (!selectedPath) {
return
}
router.push(`/instance/${encodeURIComponent(selectedPath)}/logs`)
}
const currentLoadingBars = ref<LoadingBar[]>([])
const notificationId = ref<string | number | null>(null)
const dismissed = ref(false)
function getLoadingBarKey(loadingBar: LoadingBar): string {
return `${loadingBar.loading_bar_uuid ?? loadingBar.id}`
}
function getLoadingProgress(loadingBar: LoadingBar): number {
if (!loadingBar.total || loadingBar.total <= 0) {
return 0
}
return Math.max(0, Math.min(1, (loadingBar.current ?? 0) / (loadingBar.total ?? 0)))
}
function getLoadingText(loadingBar: LoadingBar): string {
const percent = Math.floor(getLoadingProgress(loadingBar) * 100)
return loadingBar.message ? `${percent}% ${loadingBar.message}` : `${percent}%`
}
function getNotification(): PopupNotification | null {
if (!notificationId.value) {
return null
}
const notification = popupNotificationManager
.getNotifications()
.find((notification) => notification.id === notificationId.value)
return notification ?? null
}
function removeNotification(): void {
if (!notificationId.value) {
return
}
popupNotificationManager.removeNotification(notificationId.value)
notificationId.value = null
}
function buildDownloadItems(): PopupNotificationProgressItem[] {
return currentLoadingBars.value.map((bar) => ({
id: getLoadingBarKey(bar),
title: bar.title ?? '',
text: getLoadingText(bar),
progress: getLoadingProgress(bar),
waiting: !bar.total || bar.total <= 0,
}))
}
const hasVisibleActiveDownloadToasts = computed(() => !!getNotification())
const hasActiveLoadingBars = computed(() => currentLoadingBars.value.length > 0)
function updateNotification(resummon = false): void {
if (resummon) {
dismissed.value = false
}
if (currentLoadingBars.value.length === 0) {
removeNotification()
dismissed.value = false
return
}
if (notificationId.value && !getNotification()) {
notificationId.value = null
dismissed.value = true
}
if (dismissed.value && !resummon) {
return
}
let notif = getNotification()
const progressItems = buildDownloadItems()
if (notif) {
notif.title = formatMessage(messages.downloads)
notif.text = undefined
notif.progressItems = progressItems
notif.progress = undefined
notif.waiting = undefined
} else {
notif = popupNotificationManager.addPopupNotification({
title: formatMessage(messages.downloads),
type: 'download',
autoCloseMs: null,
progressItems,
})
notificationId.value = notif.id
}
}
function formatLoadingBars(loadingBar: LoadingBar): LoadingBar {
const formatted = { ...loadingBar }
if (formatted.bar_type?.type === 'java_download') {
formatted.title = formatMessage(messages.downloadingJava, {
version: formatted.bar_type.version,
})
}
if (formatted.bar_type?.profile_path) {
formatted.title = formatted.bar_type.profile_path
}
if (formatted.bar_type?.pack_name) {
formatted.title = formatted.bar_type.pack_name
}
return formatted
}
async function refreshLoadingBars() {
const bars: Record<string, LoadingBar> = await progress_bars_list().catch((error) => {
handleError(error)
return {}
})
currentLoadingBars.value = Object.values(bars)
.map(formatLoadingBars)
.filter((bar) => bar?.bar_type?.type !== 'launcher_update')
currentLoadingBars.value.sort((a, b) => {
const aKey = `${a.loading_bar_uuid ?? a.id ?? ''}`
const bKey = `${b.loading_bar_uuid ?? b.id ?? ''}`
return aKey.localeCompare(bKey)
})
updateNotification()
}
await refreshLoadingBars()
const unlistenLoading = await loading_listener(async () => {
await refreshLoadingBars()
})
function openDownloadToast() {
updateNotification(true)
}
function selectProcess(process: RunningProcess) {
selectedProcess.value = process
}
onBeforeUnmount(() => {
removeNotification()
dismissed.value = false
window.removeEventListener('offline', handleOffline)
window.removeEventListener('online', handleOnline)
unlistenProcess()
unlistenLoading()
})
</script>
@@ -61,7 +61,7 @@ defineExpose({
errorType.value = 'directory_move'
supportLink.value = 'https://support.modrinth.com'
if (errorVal.message.includes('directory is not writable')) {
if (errorVal.message.includes('directory is not writeable')) {
metadata.value.readOnly = true
}
@@ -1,8 +1,7 @@
<script setup>
import { WrenchIcon, XIcon } from '@modrinth/assets'
import { PlusIcon, XIcon } from '@modrinth/assets'
import {
Accordion,
ButtonStyled,
Button,
Checkbox,
commonMessages,
defineMessages,
@@ -10,7 +9,7 @@ import {
StyledInput,
useVIntl,
} from '@modrinth/ui'
import { save } from '@tauri-apps/plugin-dialog'
import { open } from '@tauri-apps/plugin-dialog'
import { ref } from 'vue'
import { PackageIcon, VersionIcon } from '@/assets/icons'
@@ -41,13 +40,9 @@ const messages = defineMessages({
},
selectFilesLabel: {
id: 'app.export-modal.select-files-label',
defaultMessage: 'Configure which files are included in this export',
defaultMessage: 'Select files and folders to include in pack',
},
exportButton: { id: 'app.export-modal.export-button', defaultMessage: 'Export' },
includeFile: {
id: 'app.export-modal.include-file-accessibility-label',
defaultMessage: 'Include "{file}"?',
},
})
const props = defineProps({
@@ -70,6 +65,7 @@ const exportDescription = ref('')
const versionInput = ref('1.0.0')
const files = ref([])
const folders = ref([])
const showingFiles = ref(false)
const initFiles = async () => {
const newFolders = new Map()
@@ -91,12 +87,7 @@ const initFiles = async () => {
folder.startsWith('modrinth_logs') ||
folder.startsWith('.fabric'),
}))
.filter(
(pathData) =>
!pathData.path.includes('.DS_Store') &&
pathData.path !== 'mods/.connector' &&
!pathData.path.startsWith('mods/.connector/'),
)
.filter((pathData) => !pathData.path.includes('.DS_Store'))
.forEach((pathData) => {
const parent = pathData.path.split(sep).slice(0, -1).join(sep)
if (parent !== '') {
@@ -130,20 +121,15 @@ const exportPack = async () => {
}
})
})
const outputPath = await save({
defaultPath: `${nameInput.value} ${versionInput.value}.mrpack`,
filters: [
{
name: 'Modrinth Modpack',
extensions: ['mrpack'],
},
],
const outputPath = await open({
directory: true,
multiple: false,
})
if (outputPath) {
export_profile_mrpack(
props.instance.path,
outputPath,
outputPath + `/${nameInput.value} ${versionInput.value}.mrpack`,
filesToExport,
versionInput.value,
exportDescription.value,
@@ -156,104 +142,188 @@ const exportPack = async () => {
<template>
<ModalWrapper ref="exportModal" :header="formatMessage(messages.header)">
<div class="flex flex-col gap-4 w-[40rem]">
<div class="grid grid-cols-2 gap-4">
<div class="labeled_input">
<p>{{ formatMessage(messages.modpackNameLabel) }}</p>
<StyledInput
v-model="nameInput"
:icon="PackageIcon"
type="text"
:placeholder="formatMessage(messages.modpackNamePlaceholder)"
clearable
/>
</div>
<div class="labeled_input">
<p>{{ formatMessage(messages.versionNumberLabel) }}</p>
<StyledInput
v-model="versionInput"
:icon="VersionIcon"
type="text"
:placeholder="formatMessage(messages.versionNumberPlaceholder)"
clearable
/>
</div>
</div>
<div class="flex flex-col gap-2">
<p class="m-0">{{ formatMessage(commonMessages.descriptionLabel) }}</p>
<div class="modal-body">
<div class="labeled_input">
<p>{{ formatMessage(messages.modpackNameLabel) }}</p>
<StyledInput
v-model="exportDescription"
multiline
:placeholder="formatMessage(messages.descriptionPlaceholder)"
v-model="nameInput"
:icon="PackageIcon"
type="text"
:placeholder="formatMessage(messages.modpackNamePlaceholder)"
clearable
/>
</div>
<Accordion
class="w-full bg-surface-4 border border-solid border-surface-5 rounded-2xl overflow-clip"
button-class="p-4 w-full border-b border-solid border-b-surface-5 bg-surface-2 -mb-px hover:brightness-[--hover-brightness] group"
>
<template #title>
<span class="flex items-center gap-3 text-contrast group-active:scale-[0.98]">
<WrenchIcon aria-hidden="true" class="size-5 text-secondary" />
Configure which files are included in this export
</span>
</template>
<div class="flex flex-col [&>*:nth-child(even)]:bg-surface-3">
<div v-for="[path, children] in folders" :key="path.name" class="flex flex-col">
<Accordion
class="flex flex-col"
button-class="flex gap-3 pr-4 hover:bg-surface-5 group"
<div class="labeled_input">
<p>{{ formatMessage(messages.versionNumberLabel) }}</p>
<StyledInput
v-model="versionInput"
:icon="VersionIcon"
type="text"
:placeholder="formatMessage(messages.versionNumberPlaceholder)"
clearable
/>
</div>
<div class="adjacent-input">
<div class="labeled_input">
<p>{{ formatMessage(commonMessages.descriptionLabel) }}</p>
<StyledInput
v-model="exportDescription"
multiline
:placeholder="formatMessage(messages.descriptionPlaceholder)"
/>
</div>
</div>
<div class="table">
<div class="table-head">
<div class="table-cell row-wise">
{{ formatMessage(messages.selectFilesLabel) }}
<Button
class="sleek-primary collapsed-button"
icon-only
@click="() => (showingFiles = !showingFiles)"
>
<template #title>
<PlusIcon v-if="!showingFiles" />
<XIcon v-else />
</Button>
</div>
</div>
<div v-if="showingFiles" class="table-content">
<div v-for="[path, children] in folders" :key="path.name" class="table-row">
<div class="table-cell file-entry">
<div class="file-primary">
<Checkbox
:model-value="children.every((child) => child.selected)"
:indeterminate="
!children.every((child) => child.selected) &&
children.some((child) => child.selected)
"
:description="formatMessage(messages.includeFile, { file: path.name })"
class="pl-4 py-2"
:label="path.name"
class="select-checkbox"
:disabled="children.every((x) => x.disabled)"
@update:model-value="
(newValue) => children.forEach((child) => (child.selected = newValue))
"
@click.stop
/>
<span class="ml-2 group-active:scale-95">{{ path.name }}/</span>
</template>
<div v-for="child in children" :key="child.path">
<Checkbox
v-model="child.selected"
:label="child.name"
class="w-full px-8 py-2 hover:bg-surface-4 text-primary"
:disabled="child.disabled"
v-model="path.showingMore"
class="select-checkbox dropdown"
collapsing-toggle-style
/>
</div>
</Accordion>
<div v-if="path.showingMore" class="file-secondary">
<div v-for="child in children" :key="child.path" class="file-secondary-row">
<Checkbox
v-model="child.selected"
:label="child.name"
class="select-checkbox"
:disabled="child.disabled"
/>
</div>
</div>
</div>
</div>
<div v-for="file in files" :key="file.path" class="table-row">
<div class="table-cell file-entry">
<div class="file-primary">
<Checkbox
v-model="file.selected"
:label="file.name"
:disabled="file.disabled"
class="select-checkbox"
/>
</div>
</div>
</div>
<Checkbox
v-for="file in files"
:key="file.path"
v-model="file.selected"
:label="file.name"
:disabled="file.disabled"
class="w-full px-4 py-2 hover:bg-surface-4 text-primary"
/>
</div>
</Accordion>
<div class="flex items-center justify-end gap-2">
<ButtonStyled type="outlined">
<button @click="exportModal.hide">
<XIcon />
{{ formatMessage(commonMessages.cancelButton) }}
</button>
</ButtonStyled>
<ButtonStyled color="brand">
<button @click="exportPack">
<PackageIcon />
{{ formatMessage(messages.exportButton) }}
</button>
</ButtonStyled>
</div>
<div class="button-row push-right">
<Button @click="exportModal.hide">
<XIcon />
{{ formatMessage(commonMessages.cancelButton) }}
</Button>
<Button color="primary" @click="exportPack">
<PackageIcon />
{{ formatMessage(messages.exportButton) }}
</Button>
</div>
</div>
</ModalWrapper>
</template>
<style scoped lang="scss">
.modal-body {
display: flex;
flex-direction: column;
gap: var(--gap-md);
}
.labeled_input {
display: flex;
flex-direction: column;
gap: var(--gap-sm);
p {
margin: 0;
}
}
.select-checkbox {
gap: var(--gap-sm);
button.checkbox {
border: none;
}
&.dropdown {
margin-left: auto;
}
}
.table-content {
max-height: 18rem;
overflow-y: auto;
}
.table {
border: 1px solid var(--color-bg);
}
.file-entry {
display: flex;
flex-direction: column;
gap: var(--gap-sm);
}
.file-primary {
display: flex;
align-items: center;
gap: var(--gap-sm);
}
.file-secondary {
margin-left: var(--gap-xl);
display: flex;
flex-direction: column;
gap: var(--gap-sm);
height: 100%;
vertical-align: center;
}
.file-secondary-row {
display: flex;
align-items: center;
gap: var(--gap-sm);
}
.button-row {
display: flex;
gap: var(--gap-sm);
align-items: center;
}
.row-wise {
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
gap: 1rem;
}
</style>
@@ -15,12 +15,10 @@
<span>{{ javaInstall.path }}</span>
</div>
<div class="table-cell table-text manage">
<ButtonStyled v-if="currentSelected.path === javaInstall.path">
<button disabled><CheckIcon /> Selected</button>
</ButtonStyled>
<ButtonStyled v-else>
<button @click="setJavaInstall(javaInstall)"><PlusIcon /> Select</button>
</ButtonStyled>
<Button v-if="currentSelected.path === javaInstall.path" disabled
><CheckIcon /> Selected</Button
>
<Button v-else @click="setJavaInstall(javaInstall)"><PlusIcon /> Select</Button>
</div>
</div>
<div v-if="chosenInstallOptions.length === 0" class="table-row entire-row">
@@ -28,19 +26,17 @@
</div>
</div>
<div class="input-group push-right">
<ButtonStyled type="outlined">
<button @click="$refs.detectJavaModal.hide()">
<XIcon />
Cancel
</button>
</ButtonStyled>
<Button @click="$refs.detectJavaModal.hide()">
<XIcon />
Cancel
</Button>
</div>
</div>
</ModalWrapper>
</template>
<script setup>
import { CheckIcon, PlusIcon, XIcon } from '@modrinth/assets'
import { ButtonStyled, injectNotificationManager } from '@modrinth/ui'
import { Button, injectNotificationManager } from '@modrinth/ui'
import { ref } from 'vue'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
@@ -17,45 +17,35 @@
"
/>
<span class="installation-buttons">
<ButtonStyled v-if="props.version">
<button :disabled="props.disabled || installingJava" @click="reinstallJava">
<DownloadIcon />
{{ installingJava ? 'Installing...' : 'Install recommended' }}
</button>
</ButtonStyled>
<ButtonStyled>
<button :disabled="props.disabled" @click="autoDetect">
<SearchIcon />
Detect
</button>
</ButtonStyled>
<ButtonStyled>
<button :disabled="props.disabled" @click="handleJavaFileInput()">
<FolderSearchIcon />
Browse
</button>
</ButtonStyled>
<ButtonStyled v-if="testingJava">
<button disabled>Testing...</button>
</ButtonStyled>
<ButtonStyled v-else-if="testingJavaSuccess === true">
<button disabled>
<CheckIcon />
Success
</button>
</ButtonStyled>
<ButtonStyled v-else-if="testingJavaSuccess === false">
<button disabled>
<XIcon />
Failed
</button>
</ButtonStyled>
<ButtonStyled v-else>
<button :disabled="props.disabled" @click="testJava">
<PlayIcon />
Test
</button>
</ButtonStyled>
<Button
v-if="props.version"
:disabled="props.disabled || installingJava"
@click="reinstallJava"
>
<DownloadIcon />
{{ installingJava ? 'Installing...' : 'Install recommended' }}
</Button>
<Button :disabled="props.disabled" @click="autoDetect">
<SearchIcon />
Detect
</Button>
<Button :disabled="props.disabled" @click="handleJavaFileInput()">
<FolderSearchIcon />
Browse
</Button>
<Button v-if="testingJava" disabled> Testing... </Button>
<Button v-else-if="testingJavaSuccess === true">
<CheckIcon class="test-success" />
Success
</Button>
<Button v-else-if="testingJavaSuccess === false">
<XIcon class="test-fail" />
Failed
</Button>
<Button v-else :disabled="props.disabled" @click="testJava">
<PlayIcon />
Test
</Button>
</span>
</div>
</template>
@@ -69,7 +59,7 @@ import {
SearchIcon,
XIcon,
} from '@modrinth/assets'
import { ButtonStyled, injectNotificationManager, StyledInput } from '@modrinth/ui'
import { Button, injectNotificationManager, StyledInput } from '@modrinth/ui'
import { open } from '@tauri-apps/plugin-dialog'
import { ref } from 'vue'
@@ -214,6 +204,10 @@ async function reinstallJava() {
align-items: center;
gap: 0.5rem;
margin: 0;
.btn {
width: max-content;
}
}
.test-success {
@@ -1,6 +1,6 @@
<script setup>
import { CheckIcon } from '@modrinth/assets'
import { Badge, ButtonStyled } from '@modrinth/ui'
import { Badge, Button } from '@modrinth/ui'
import { computed, ref } from 'vue'
import { SwapIcon } from '@/assets/icons/index.js'
@@ -74,18 +74,15 @@ const onHide = () => {
@click="$router.push(`/project/${version.project_id}/version/${version.id}`)"
>
<div class="table-cell table-text">
<ButtonStyled
circular
:color="version.id === installedVersion ? 'standard' : 'brand'"
<Button
:color="version.id === installedVersion ? '' : 'primary'"
icon-only
:disabled="inProgress || installing || version.id === installedVersion"
@click.stop="() => switchVersion(version.id)"
>
<button
:disabled="inProgress || installing || version.id === installedVersion"
@click.stop="() => switchVersion(version.id)"
>
<SwapIcon v-if="version.id !== installedVersion" />
<CheckIcon v-else />
</button>
</ButtonStyled>
<SwapIcon v-if="version.id !== installedVersion" />
<CheckIcon v-else />
</Button>
</div>
<div class="name-cell table-cell table-text">
<div class="version-link">
@@ -37,6 +37,6 @@ defineProps({
.progress-bar__fill {
height: 100%;
transition: width 0.3s ease-out;
transition: width 0.3s;
}
</style>
@@ -0,0 +1,476 @@
<template>
<div class="action-groups">
<ButtonStyled v-if="currentLoadingBars.length > 0" color="brand" type="transparent" circular>
<button ref="infoButton" @click="toggleCard()">
<DownloadIcon />
</button>
</ButtonStyled>
<div v-if="offline" class="status">
<UnplugIcon />
<div class="running-text">
<span> Offline </span>
</div>
</div>
<div v-if="selectedProcess" class="status">
<span class="circle running" />
<div ref="profileButton" class="running-text">
<router-link
class="text-primary"
:to="`/instance/${encodeURIComponent(selectedProcess.profile.path)}`"
>
{{ selectedProcess.profile.name }}
</router-link>
<div
v-if="currentProcesses.length > 1"
class="arrow button-base"
:class="{ rotate: showProfiles }"
@click="toggleProfiles()"
>
<DropdownIcon />
</div>
</div>
<Button
v-tooltip="'Stop instance'"
icon-only
class="icon-button stop"
@click="stop(selectedProcess)"
>
<StopCircleIcon />
</Button>
<Button v-tooltip="'View logs'" icon-only class="icon-button" @click="goToTerminal()">
<TerminalSquareIcon />
</Button>
</div>
<div v-else class="status">
<span class="circle stopped" />
<span class="running-text"> No instances running </span>
</div>
</div>
<transition name="download">
<Card v-if="showCard === true && currentLoadingBars.length > 0" ref="card" class="info-card">
<div v-for="loadingBar in currentLoadingBars" :key="loadingBar.id" class="info-text">
<h3 class="info-title">
{{ loadingBar.title }}
</h3>
<div class="flex flex-col gap-2 w-full">
<ProgressBar :progress="Math.floor((100 * loadingBar.current) / loadingBar.total)" />
<div class="row">
{{ Math.floor((100 * loadingBar.current) / loadingBar.total) }}%
{{ loadingBar.message }}
</div>
</div>
</div>
</Card>
</transition>
<transition name="download">
<Card
v-if="showProfiles === true && currentProcesses.length > 0"
ref="profiles"
class="profile-card"
>
<Button
v-for="process in currentProcesses"
:key="process.uuid"
class="profile-button"
@click="selectProcess(process)"
>
<div class="text"><span class="circle running" /> {{ process.profile.name }}</div>
<Button
v-tooltip="'Stop instance'"
icon-only
class="icon-button stop"
@click.stop="stop(process)"
>
<StopCircleIcon />
</Button>
<Button
v-tooltip="'View logs'"
icon-only
class="icon-button"
@click.stop="goToTerminal(process.profile.path)"
>
<TerminalSquareIcon />
</Button>
</Button>
</Card>
</transition>
</template>
<script setup>
import {
DownloadIcon,
DropdownIcon,
StopCircleIcon,
TerminalSquareIcon,
UnplugIcon,
} from '@modrinth/assets'
import { Button, ButtonStyled, Card, injectNotificationManager } from '@modrinth/ui'
import { onBeforeUnmount, onMounted, ref } from 'vue'
import { useRouter } from 'vue-router'
import ProgressBar from '@/components/ui/ProgressBar.vue'
import { trackEvent } from '@/helpers/analytics'
import { loading_listener, process_listener } from '@/helpers/events'
import { get_all as getRunningProcesses, kill as killProcess } from '@/helpers/process'
import { get_many } from '@/helpers/profile.js'
import { progress_bars_list } from '@/helpers/state.js'
const { handleError } = injectNotificationManager()
const router = useRouter()
const card = ref(null)
const profiles = ref(null)
const infoButton = ref(null)
const profileButton = ref(null)
const showCard = ref(false)
const showProfiles = ref(false)
const currentProcesses = ref([])
const selectedProcess = ref()
const refresh = async () => {
const processes = await getRunningProcesses().catch(handleError)
const profiles = await get_many(processes.map((x) => x.profile_path)).catch(handleError)
currentProcesses.value = processes.map((x) => ({
profile: profiles.find((prof) => x.profile_path === prof.path),
...x,
}))
if (!selectedProcess.value || !currentProcesses.value.includes(selectedProcess.value)) {
selectedProcess.value = currentProcesses.value[0]
}
}
await refresh()
const offline = ref(!navigator.onLine)
window.addEventListener('offline', () => {
offline.value = true
})
window.addEventListener('online', () => {
offline.value = false
})
const unlistenProcess = await process_listener(async () => {
await refresh()
})
const stop = async (process) => {
try {
await killProcess(process.uuid).catch(handleError)
trackEvent('InstanceStop', {
loader: process.profile.loader,
game_version: process.profile.game_version,
source: 'AppBar',
})
} catch (e) {
console.error(e)
}
await refresh()
}
const goToTerminal = (path) => {
router.push(`/instance/${encodeURIComponent(path ?? selectedProcess.value.profile.path)}/logs`)
}
const currentLoadingBars = ref([])
const refreshInfo = async () => {
const currentLoadingBarCount = currentLoadingBars.value.length
currentLoadingBars.value = Object.values(await progress_bars_list().catch(handleError))
.map((x) => {
if (x.bar_type.type === 'java_download') {
x.title = 'Downloading Java ' + x.bar_type.version
}
if (x.bar_type.profile_path) {
x.title = x.bar_type.profile_path
}
if (x.bar_type.pack_name) {
x.title = x.bar_type.pack_name
}
return x
})
.filter((bar) => bar?.bar_type?.type !== 'launcher_update')
currentLoadingBars.value.sort((a, b) => {
if (a.loading_bar_uuid < b.loading_bar_uuid) {
return -1
}
if (a.loading_bar_uuid > b.loading_bar_uuid) {
return 1
}
return 0
})
if (currentLoadingBars.value.length === 0) {
showCard.value = false
} else if (currentLoadingBarCount < currentLoadingBars.value.length) {
showCard.value = true
}
}
await refreshInfo()
const unlistenLoading = await loading_listener(async () => {
await refreshInfo()
})
const selectProcess = (process) => {
selectedProcess.value = process
showProfiles.value = false
}
const handleClickOutsideCard = (event) => {
const elements = document.elementsFromPoint(event.clientX, event.clientY)
if (
card.value &&
card.value.$el !== event.target &&
!elements.includes(card.value.$el) &&
infoButton.value &&
!infoButton.value.contains(event.target)
) {
showCard.value = false
}
}
const handleClickOutsideProfile = (event) => {
const elements = document.elementsFromPoint(event.clientX, event.clientY)
if (
profiles.value &&
profiles.value.$el !== event.target &&
!elements.includes(profiles.value.$el) &&
!profileButton.value.contains(event.target)
) {
showProfiles.value = false
}
}
const toggleCard = async () => {
showCard.value = !showCard.value
showProfiles.value = false
await refreshInfo()
}
const toggleProfiles = async () => {
if (currentProcesses.value.length === 1) return
showProfiles.value = !showProfiles.value
showCard.value = false
}
onMounted(() => {
window.addEventListener('click', handleClickOutsideCard)
window.addEventListener('click', handleClickOutsideProfile)
})
onBeforeUnmount(() => {
window.removeEventListener('click', handleClickOutsideCard)
window.removeEventListener('click', handleClickOutsideProfile)
unlistenProcess()
unlistenLoading()
})
</script>
<style scoped lang="scss">
.action-groups {
display: flex;
flex-direction: row;
align-items: center;
gap: var(--gap-md);
}
.arrow {
transition: transform 0.2s ease-in-out;
display: flex;
align-items: center;
&.rotate {
transform: rotate(180deg);
}
}
.status {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.5rem;
border-radius: var(--radius-md);
border: 1px solid var(--color-divider);
padding: var(--gap-sm) var(--gap-lg);
}
.running-text {
display: flex;
flex-direction: row;
gap: var(--gap-xs);
white-space: nowrap;
overflow: hidden;
-webkit-user-select: none; /* Safari */
-ms-user-select: none; /* IE 10 and IE 11 */
user-select: none;
&.clickable:hover {
cursor: pointer;
}
}
.circle {
width: 0.5rem;
height: 0.5rem;
border-radius: 50%;
display: inline-block;
margin-right: 0.25rem;
&.running {
background-color: var(--color-brand);
}
&.stopped {
background-color: var(--color-base);
}
}
.icon-button {
background-color: rgba(0, 0, 0, 0);
box-shadow: none;
width: 1.25rem !important;
height: 1.25rem !important;
svg {
min-width: 1.25rem;
}
&.stop {
color: var(--color-red);
}
}
.info-card {
position: absolute;
top: 3.5rem;
right: 2rem;
z-index: 9;
width: 20rem;
background-color: var(--color-raised-bg);
box-shadow: var(--shadow-raised);
display: flex;
flex-direction: column;
gap: 1rem;
overflow: auto;
transition: all 0.2s ease-in-out;
border: 1px solid var(--color-divider);
&.hidden {
transform: translateY(-100%);
}
}
.loading-option {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.5rem;
margin: 0;
padding: 0;
:hover {
background-color: var(--color-raised-bg-hover);
}
}
.loading-text {
display: flex;
flex-direction: column;
margin: 0;
padding: 0;
.row {
display: flex;
flex-direction: row;
align-items: center;
gap: 0.5rem;
}
}
.loading-icon {
width: 2.25rem;
height: 2.25rem;
display: block;
:deep(svg) {
left: 1rem;
width: 2.25rem;
height: 2.25rem;
}
}
.download-enter-active,
.download-leave-active {
transition: opacity 0.3s ease;
}
.download-enter-from,
.download-leave-to {
opacity: 0;
}
.progress-bar {
width: 100%;
}
.info-text {
display: flex;
flex-direction: column;
align-items: flex-start;
gap: 0.75rem;
margin: 0;
padding: 0;
}
.info-title {
margin: 0;
}
.profile-button {
display: flex;
flex-direction: row;
align-items: center;
gap: var(--gap-sm);
width: 100%;
background-color: var(--color-raised-bg);
box-shadow: none;
.text {
margin-right: auto;
}
}
.profile-card {
position: absolute;
top: 3.5rem;
right: 0.5rem;
z-index: 9;
background-color: var(--color-raised-bg);
box-shadow: var(--shadow-raised);
display: flex;
flex-direction: column;
overflow: auto;
transition: all 0.2s ease-in-out;
border: 1px solid var(--color-divider);
padding: var(--gap-md);
&.hidden {
transform: translateY(-100%);
}
}
.link {
display: flex;
flex-direction: row;
align-items: center;
gap: var(--gap-sm);
margin: 0;
color: var(--color-text);
text-decoration: none;
}
</style>
File diff suppressed because one or more lines are too long
@@ -1,5 +1,5 @@
<script setup>
import { ButtonStyled, injectNotificationManager, ProjectCard } from '@modrinth/ui'
import { Button, injectNotificationManager, ProjectCard } from '@modrinth/ui'
import { ref } from 'vue'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
@@ -12,6 +12,7 @@ const { install: installVersion } = injectContentInstall()
const confirmModal = ref(null)
const project = ref(null)
const version = ref(null)
const installing = ref(false)
defineExpose({
async show(event) {
@@ -69,9 +70,7 @@ async function install() {
</p>
</div>
<div class="button-group">
<ButtonStyled color="brand">
<button @click="install">Install</button>
</ButtonStyled>
<Button :loading="installing" color="primary" @click="install">Install</Button>
</div>
</div>
</div>
@@ -1,93 +0,0 @@
<template>
<section
v-if="showControls"
class="flex items-center gap-2 mr-1.5"
data-tauri-drag-region-exclude
>
<ButtonStyled type="transparent" circular>
<button class="relative expanded-button" @click="() => getCurrentWindow().minimize()">
<MinimizeIcon />
</button>
</ButtonStyled>
<ButtonStyled type="transparent" circular>
<button class="relative expanded-button" @click="() => getCurrentWindow().toggleMaximize()">
<RestoreIcon v-if="isMaximized" />
<MaximizeIcon v-else />
</button>
</ButtonStyled>
<ButtonStyled
type="transparent"
color="red"
color-fill="none"
hover-color-fill="background"
circular
>
<button class="relative expanded-button close-button" @click="handleClose">
<XIcon />
</button>
</ButtonStyled>
</section>
</template>
<script setup>
import { MaximizeIcon, MinimizeIcon, RestoreIcon, XIcon } from '@modrinth/assets'
import { ButtonStyled } from '@modrinth/ui'
import { getCurrentWindow } from '@tauri-apps/api/window'
import { saveWindowState, StateFlags } from '@tauri-apps/plugin-window-state'
import { computed, onMounted, onUnmounted, ref } from 'vue'
import { get as getSettings } from '@/helpers/settings.ts'
import { getOS } from '@/helpers/utils.js'
import { useTheming } from '@/store/state'
const themeStore = useTheming()
const nativeDecorations = ref(true)
const isMaximized = ref(false)
const os = ref('')
const alwaysShowAppControls = computed(() => themeStore.getFeatureFlag('always_show_app_controls'))
const showControls = computed(
() =>
alwaysShowAppControls.value ||
(!nativeDecorations.value && (os.value === 'Windows' || os.value === 'Linux')),
)
onMounted(async () => {
os.value = await getOS()
const settings = await getSettings()
nativeDecorations.value = settings.native_decorations
if (os.value !== 'MacOS') {
await getCurrentWindow().setDecorations(nativeDecorations.value)
}
isMaximized.value = await getCurrentWindow().isMaximized()
const unlisten = await getCurrentWindow().onResized(async () => {
isMaximized.value = await getCurrentWindow().isMaximized()
})
onUnmounted(() => {
unlisten()
})
})
const handleClose = async () => {
await saveWindowState(StateFlags.ALL)
await getCurrentWindow().close()
}
</script>
<style scoped>
.expanded-button::before {
inset: -9px -6px;
content: '';
position: absolute;
}
.expanded-button.close-button::before {
inset: -9px -9px -9px -6px;
}
</style>
@@ -288,7 +288,7 @@ const messages = defineMessages({
</div>
</div>
</ModalWrapper>
<div v-if="userCredentials && !loading" class="flex gap-1 items-center mb-3 -ml-1">
<div v-if="userCredentials && !loading" class="flex gap-1 items-center mb-3 ml-2 mr-1">
<template v-if="sortedFriends.length > 0">
<ButtonStyled circular type="transparent">
<button
@@ -309,7 +309,7 @@ const messages = defineMessages({
@keyup.esc="search = ''"
/>
</template>
<h3 v-else class="w-full text-base text-primary font-medium m-0">
<h3 v-else class="ml-2 w-full text-base text-primary font-medium m-0">
{{ formatMessage(messages.friends) }}
</h3>
<ButtonStyled v-if="incomingRequests.length > 0" circular type="transparent">
@@ -331,11 +331,11 @@ const messages = defineMessages({
</ButtonStyled>
</div>
<div class="flex flex-col gap-3">
<h3 v-if="loading" class="text-base text-primary font-medium m-0">
<h3 v-if="loading" class="ml-4 mr-1 text-base text-primary font-medium m-0">
{{ formatMessage(messages.friends) }}
</h3>
<template v-if="loading">
<div v-for="n in 5" :key="n" class="flex gap-2 items-center animate-pulse">
<div v-for="n in 5" :key="n" class="flex gap-2 items-center animate-pulse ml-4 mr-1">
<div class="min-w-9 min-h-9 bg-button-bg rounded-full"></div>
<div class="flex flex-col w-full">
<div class="h-3 bg-button-bg rounded-full w-1/2 mb-1"></div>
@@ -344,7 +344,7 @@ const messages = defineMessages({
</div>
</template>
<template v-else-if="sortedFriends.length === 0">
<div class="text-sm">
<div class="text-sm ml-4 mr-1">
<div v-if="!userCredentials">
<IntlFormatted :message-id="messages.signInToAddFriends">
<template #link="{ children }">
@@ -106,7 +106,7 @@ const messages = defineMessages({
:open-by-default="openByDefault"
:force-open="isSearching"
:button-class="
'flex w-full items-center bg-transparent border-0 p-0' +
'pl-4 pr-3 flex w-full items-center bg-transparent border-0 p-0' +
(isSearching
? ''
: ' cursor-pointer hover:brightness-[--hover-brightness] active:scale-[0.98] transition-all')
@@ -122,7 +122,7 @@ const messages = defineMessages({
<div
v-for="friend in friends"
:key="friend.username"
class="group grid items-center grid-cols-[auto_1fr_auto] gap-2 hover:bg-button-bg transition-colors rounded-full mr-1"
class="group grid items-center grid-cols-[auto_1fr_auto] gap-2 hover:bg-button-bg transition-colors rounded-full ml-4 mr-1"
@contextmenu.prevent.stop="
(event) => friendOptions?.showMenu(event, friend, createContextMenuOptions(friend))
"
@@ -34,14 +34,10 @@
</tbody>
</table>
<div class="button-group">
<ButtonStyled type="outlined">
<button @click="() => incompatibleModal.hide()"><XIcon />Cancel</button>
</ButtonStyled>
<ButtonStyled color="brand">
<button :disabled="installing" @click="install()">
<DownloadIcon /> {{ installing ? 'Installing' : 'Install' }}
</button>
</ButtonStyled>
<Button @click="() => incompatibleModal.hide()"><XIcon />Cancel</Button>
<Button color="primary" :disabled="installing" @click="install()">
<DownloadIcon /> {{ installing ? 'Installing' : 'Install' }}
</Button>
</div>
</div>
</ModalWrapper>
@@ -49,13 +45,7 @@
<script setup>
import { DownloadIcon, XIcon } from '@modrinth/assets'
import {
ButtonStyled,
Combobox,
formatLoader,
injectNotificationManager,
useVIntl,
} from '@modrinth/ui'
import { Button, Combobox, formatLoader, injectNotificationManager, useVIntl } from '@modrinth/ui'
import { computed, ref } from 'vue'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
@@ -117,7 +107,7 @@ defineExpose({
const install = async () => {
installing.value = true
await installMod(instance.value.path, selectedVersion.value.id, 'standalone').catch(handleError)
await installMod(instance.value.path, selectedVersion.value.id).catch(handleError)
installing.value = false
onInstall.value(selectedVersion.value.id)
incompatibleModal.value.hide()
@@ -0,0 +1,418 @@
<script setup>
import {
CheckIcon,
DownloadIcon,
PlusIcon,
RightArrowIcon,
SearchIcon,
UploadIcon,
XIcon,
} from '@modrinth/assets'
import { Avatar, Button, Card, injectNotificationManager, StyledInput } from '@modrinth/ui'
import { convertFileSrc } from '@tauri-apps/api/core'
import { open } from '@tauri-apps/plugin-dialog'
import { computed, ref } from 'vue'
import { useRouter } from 'vue-router'
import ModalWrapper from '@/components/ui/modal/ModalWrapper.vue'
import { trackEvent } from '@/helpers/analytics'
import { get_project_v3_many } from '@/helpers/cache.js'
import {
add_project_from_version as installMod,
check_installed,
create,
get,
list,
} from '@/helpers/profile'
import {
findPreferredVersion,
installVersionDependencies,
isVersionCompatible,
} from '@/store/install.js'
const { handleError } = injectNotificationManager()
const router = useRouter()
const versions = ref()
const project = ref()
const installModal = ref()
const searchFilter = ref('')
const showCreation = ref(false)
const icon = ref(null)
const name = ref(null)
const display_icon = ref(null)
const loader = ref(null)
const gameVersion = ref(null)
const creatingInstance = ref(false)
const profiles = ref([])
const shownProfiles = computed(() =>
profiles.value.filter((profile) => {
return profile.name.toLowerCase().includes(searchFilter.value.toLowerCase())
}),
)
const isProfileCompatible = (profile) =>
versions.value?.some((version) => isVersionCompatible(version, project.value, profile))
const onInstall = ref(() => {})
defineExpose({
show: async (projectVal, versionsVal, callback) => {
project.value = projectVal
versions.value = versionsVal
searchFilter.value = ''
showCreation.value = false
name.value = null
icon.value = null
display_icon.value = null
gameVersion.value = null
loader.value = null
onInstall.value = callback
const profilesVal = await list().catch(handleError)
for (const profile of profilesVal) {
profile.installing = false
profile.installedMod = await check_installed(profile.path, project.value.id).catch(
handleError,
)
}
const linkedProjectIds = profilesVal
.filter((p) => p.linked_data?.project_id)
.map((p) => p.linked_data.project_id)
if (linkedProjectIds.length > 0) {
const linkedProjects = await get_project_v3_many(linkedProjectIds, 'must_revalidate').catch(
() => [],
)
const serverProjectIds = new Set(
linkedProjects.filter((p) => p?.minecraft_server != null).map((p) => p.id),
)
for (const profile of profilesVal) {
profile.isServerInstance = serverProjectIds.has(profile.linked_data?.project_id)
}
}
profiles.value = profilesVal
installModal.value.show()
trackEvent('ProjectInstallStart', { source: 'ProjectInstallModal' })
},
})
async function install(instance) {
instance.installing = true
const version = findPreferredVersion(versions.value, project.value, instance)
if (!version) {
instance.installing = false
handleError('No compatible version found')
return
}
await installMod(instance.path, version.id).catch(handleError)
await installVersionDependencies(instance, version).catch(handleError)
instance.installedMod = true
instance.installing = false
trackEvent('ProjectInstall', {
loader: instance.loader,
game_version: instance.game_version,
id: project.value.id,
version_id: version.id,
project_type: project.value.project_type,
title: project.value.title,
source: 'ProjectInstallModal',
})
onInstall.value(version.id)
}
const toggleCreation = () => {
showCreation.value = !showCreation.value
name.value = null
icon.value = null
display_icon.value = null
gameVersion.value = null
loader.value = null
if (showCreation.value) {
trackEvent('InstanceCreateStart', { source: 'ProjectInstallModal' })
}
}
const upload_icon = async () => {
const res = await open({
multiple: false,
filters: [
{
name: 'Image',
extensions: ['png', 'jpeg'],
},
],
})
icon.value = res.path ?? res
if (!icon.value) return
display_icon.value = convertFileSrc(icon.value)
}
const reset_icon = () => {
icon.value = null
display_icon.value = null
}
const createInstance = async () => {
creatingInstance.value = true
const gameVersions = versions.value[0].game_versions
const gameVersion = gameVersions[0]
const loaders = versions.value[0].loaders
const loader = loaders.includes('fabric')
? 'fabric'
: loaders.includes('neoforge')
? 'neoforge'
: loaders.includes('forge')
? 'forge'
: loaders.includes('quilt')
? 'quilt'
: 'vanilla'
const id = await create(name.value, gameVersion, loader, 'latest', icon.value).catch(handleError)
await installMod(id, versions.value[0].id).catch(handleError)
await router.push(`/instance/${encodeURIComponent(id)}/`)
const instance = await get(id, true)
await installVersionDependencies(instance, versions.value[0]).catch(handleError)
trackEvent('InstanceCreate', {
profile_name: name.value,
game_version: versions.value[0].game_versions[0],
loader: loader,
loader_version: 'latest',
has_icon: !!icon.value,
source: 'ProjectInstallModal',
})
trackEvent('ProjectInstall', {
loader: loader,
game_version: versions.value[0].game_versions[0],
id: project.value,
version_id: versions.value[0].id,
project_type: project.value.project_type,
title: project.value.title,
source: 'ProjectInstallModal',
})
onInstall.value(versions.value[0].id)
if (installModal.value) installModal.value.hide()
creatingInstance.value = false
}
</script>
<template>
<ModalWrapper ref="installModal" header="Install project to instance" :on-hide="onInstall">
<div class="modal-body">
<StyledInput
v-model="searchFilter"
:icon="SearchIcon"
type="search"
placeholder="Search for an instance"
autocomplete="off"
/>
<div class="profiles" :class="{ 'hide-creation': !showCreation }">
<div v-for="profile in shownProfiles" :key="profile.name" class="option">
<router-link
class="btn btn-transparent profile-button"
:to="`/instance/${encodeURIComponent(profile.path)}`"
@click="installModal.hide()"
>
<Avatar
:src="profile.icon_path ? convertFileSrc(profile.icon_path) : null"
class="profile-image"
/>
{{ profile.name }}
</router-link>
<div
v-tooltip="
profile.linked_data?.locked && !profile.installedMod
? 'Unpair or unlock an instance to add mods.'
: ''
"
>
<Button
:disabled="
!isProfileCompatible(profile) || profile.installedMod || profile.installing
"
@click="install(profile)"
>
<DownloadIcon
v-if="isProfileCompatible(profile) && !profile.installedMod && !profile.installing"
/>
<CheckIcon v-else-if="profile.installedMod" />
{{
profile.installing
? 'Installing...'
: profile.installedMod
? 'Installed'
: !isProfileCompatible(profile)
? 'Incompatible'
: 'Install'
}}
</Button>
</div>
</div>
</div>
<Card v-if="showCreation" class="creation-card">
<div class="creation-container">
<div class="creation-icon">
<Avatar size="md" class="icon" :src="display_icon" />
<div class="creation-icon__description">
<Button @click="upload_icon()">
<UploadIcon />
<span class="no-wrap"> Select icon </span>
</Button>
<Button :disabled="!display_icon" @click="reset_icon()">
<XIcon />
<span class="no-wrap"> Remove icon </span>
</Button>
</div>
</div>
<div class="creation-settings">
<StyledInput
v-model="name"
autocomplete="off"
type="text"
placeholder="Name"
class="creation-input"
/>
<Button :disabled="creatingInstance === true || !name" @click="createInstance()">
<RightArrowIcon />
{{ creatingInstance ? 'Creating...' : 'Create' }}
</Button>
</div>
</div>
</Card>
<div class="input-group push-right">
<Button :color="showCreation ? '' : 'primary'" @click="toggleCreation()">
<PlusIcon />
{{ showCreation ? 'Hide New Instance' : 'Create new instance' }}
</Button>
<Button @click="installModal.hide()">Cancel</Button>
</div>
</div>
</ModalWrapper>
</template>
<style scoped lang="scss">
.creation-card {
display: flex;
flex-direction: column;
gap: 1rem;
margin: 0;
background-color: var(--color-bg);
}
.creation-container {
display: flex;
flex-direction: row;
gap: 1rem;
}
.creation-icon {
display: flex;
flex-direction: row;
gap: 1rem;
align-items: center;
flex-grow: 1;
.creation-icon__description {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
}
.creation-input {
width: 100%;
}
.no-wrap {
white-space: nowrap;
}
.creation-dropdown {
width: min-content !important;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.creation-settings {
width: 100%;
margin-left: 0.5rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
justify-content: center;
}
.modal-body {
display: flex;
flex-direction: column;
gap: 1rem;
min-width: 350px;
}
.profiles {
max-height: 12rem;
overflow-y: auto;
&.hide-creation {
max-height: 21rem;
}
}
.option {
width: calc(100%);
background: var(--color-raised-bg);
color: var(--color-base);
box-shadow: none;
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
gap: 0.5rem;
img {
margin-right: 0.5rem;
}
.name {
display: flex;
flex-direction: column;
justify-content: center;
}
.profile-button {
align-content: start;
padding: 0.5rem;
text-align: left;
}
}
.profile-image {
--size: 2rem !important;
}
</style>
@@ -1,140 +0,0 @@
<template>
<NewModal ref="modal" :header="formatMessage(messages.header)" :on-hide="reset">
<div class="max-w-[31rem] flex flex-col gap-6">
<Admonition
type="warning"
:header="formatMessage(messages.warningTitle)"
:body="formatMessage(messages.warningBody)"
/>
<div v-if="fileName" class="overflow-x-auto whitespace-nowrap text-sm text-secondary">
{{ fileName }}
</div>
<div>
<p class="mt-0 leading-tight">
{{ formatMessage(messages.body) }}
</p>
<p class="text-orange font-semibold mb-0 leading-tight">
{{ formatMessage(messages.malwareStatement) }}
</p>
</div>
<Checkbox v-model="dontShowAgain" :label="formatMessage(messages.dontShowAgain)" />
<div class="flex gap-2 justify-end">
<ButtonStyled type="outlined">
<button @click="cancel">
<XIcon />
{{ formatMessage(commonMessages.cancelButton) }}
</button>
</ButtonStyled>
<ButtonStyled color="orange">
<button :disabled="isProceeding" @click="proceed">
<SpinnerIcon v-if="isProceeding" class="animate-spin" />
<CircleArrowRightIcon v-else />
{{ formatMessage(messages.installAnyway) }}
</button>
</ButtonStyled>
</div>
</div>
</NewModal>
</template>
<script setup lang="ts">
import { CircleArrowRightIcon, SpinnerIcon, XIcon } from '@modrinth/assets'
import {
Admonition,
ButtonStyled,
Checkbox,
commonMessages,
defineMessages,
NewModal,
useVIntl,
} from '@modrinth/ui'
import { ref, useTemplateRef } from 'vue'
import { get as getSettings, set as setSettings } from '@/helpers/settings'
import { useTheming } from '@/store/state'
import type { FeatureFlag } from '@/store/theme.ts'
const { formatMessage } = useVIntl()
const themeStore = useTheming()
const skipUnknownPackWarningFeatureFlag = 'skip_unknown_pack_warning' as FeatureFlag
const dontShowAgain = ref(false)
const modal = useTemplateRef('modal')
const onProceed = ref<() => Promise<void>>()
const isProceeding = ref(false)
const fileName = ref('')
const messages = defineMessages({
header: {
id: 'unknown-pack-warning-modal.header',
defaultMessage: 'Confirm installation',
},
warningTitle: {
id: 'unknown-pack-warning-modal.warning.title',
defaultMessage: 'Unknown file warning',
},
warningBody: {
id: 'unknown-pack-warning-modal.warning.body',
defaultMessage: `We couldn't find this file on Modrinth. We strongly recommend only installing files from sources you trust.`,
},
body: {
id: 'unknown-pack-warning-modal.body',
defaultMessage: `A file is only reviewed if its uploaded to Modrinth, regardless of its file format (including .mrpack).`,
},
malwareStatement: {
id: 'unknown-pack-warning-modal.malware-statement',
defaultMessage: `Malware is often distributed through modpack files by sharing them on platforms like Discord.`,
},
dontShowAgain: {
id: 'unknown-pack-warning-modal.dont-show-again',
defaultMessage: `Don't show this warning again`,
},
installAnyway: {
id: 'unknown-pack-warning-modal.install-anyway',
defaultMessage: `Install anyway`,
},
})
function show(createInstance: () => Promise<void>, selectedFileName = '') {
onProceed.value = createInstance
fileName.value = selectedFileName
dontShowAgain.value = false
if (themeStore.getFeatureFlag(skipUnknownPackWarningFeatureFlag)) {
// noinspection ES6MissingAwait
createInstance()
return
}
modal.value?.show()
}
function reset() {
onProceed.value = undefined
fileName.value = ''
}
function cancel() {
modal.value?.hide()
}
async function proceed() {
if (!onProceed.value) {
return
}
if (dontShowAgain.value) {
themeStore.featureFlags[skipUnknownPackWarningFeatureFlag] = true
const settings = await getSettings()
settings.feature_flags[skipUnknownPackWarningFeatureFlag] = true
await setSettings(settings)
}
const createInstance = onProceed.value
modal.value?.hide()
// noinspection ES6MissingAwait
createInstance()
}
defineExpose({ show })
</script>
@@ -7,7 +7,7 @@
<template #actions>
<div class="flex gap-2 justify-end">
<ButtonStyled type="outlined">
<button @click="modal?.hide()">
<button class="!border !border-surface-4" @click="modal?.hide()">
<XIcon />
{{ formatMessage(commonMessages.cancelButton) }}
</button>
@@ -31,7 +31,7 @@ const props = defineProps({
const modal = useTemplateRef('modal')
defineExpose({
show: (e?: MouseEvent) => {
show: (e: MouseEvent) => {
modal.value?.show(e)
},
hide: () => {
@@ -11,7 +11,7 @@
<template #actions>
<div class="flex gap-2 justify-end">
<ButtonStyled type="outlined">
<button @click="handleCancel">
<button class="!border !border-surface-4" @click="handleCancel">
<XIcon />
{{ formatMessage(commonMessages.cancelButton) }}
</button>
@@ -1,106 +1,13 @@
<script setup lang="ts">
import { Combobox, defineMessages, ThemeSelector, Toggle, useVIntl } from '@modrinth/ui'
import { Combobox, ThemeSelector, Toggle } from '@modrinth/ui'
import { ref, watch } from 'vue'
import { get, set } from '@/helpers/settings.ts'
import { getOS } from '@/helpers/utils'
import { useTheming } from '@/store/state'
import type { ColorTheme, FeatureFlag } from '@/store/theme.ts'
import type { ColorTheme } from '@/store/theme.ts'
const themeStore = useTheming()
const { formatMessage } = useVIntl()
const worldsInHomeFeatureFlag = 'worlds_in_home' as FeatureFlag
const skipUnknownPackWarningFeatureFlag = 'skip_unknown_pack_warning' as FeatureFlag
const messages = defineMessages({
colorThemeTitle: {
id: 'app.appearance-settings.color-theme.title',
defaultMessage: 'Color theme',
},
colorThemeDescription: {
id: 'app.appearance-settings.color-theme.description',
defaultMessage: 'Select your preferred color theme for Modrinth App.',
},
advancedRenderingTitle: {
id: 'app.appearance-settings.advanced-rendering.title',
defaultMessage: 'Advanced rendering',
},
advancedRenderingDescription: {
id: 'app.appearance-settings.advanced-rendering.description',
defaultMessage:
'Enables advanced rendering such as blur effects that may cause performance issues without hardware-accelerated rendering.',
},
hideNametagTitle: {
id: 'app.appearance-settings.hide-nametag.title',
defaultMessage: 'Hide nametag',
},
hideNametagDescription: {
id: 'app.appearance-settings.hide-nametag.description',
defaultMessage: 'Disables the nametag above your player on the skins page.',
},
nativeDecorationsTitle: {
id: 'app.appearance-settings.native-decorations.title',
defaultMessage: 'Native decorations',
},
nativeDecorationsDescription: {
id: 'app.appearance-settings.native-decorations.description',
defaultMessage: 'Use system window frame (app restart required).',
},
minimizeLauncherTitle: {
id: 'app.appearance-settings.minimize-launcher.title',
defaultMessage: 'Minimize launcher',
},
minimizeLauncherDescription: {
id: 'app.appearance-settings.minimize-launcher.description',
defaultMessage: 'Minimize the launcher when a Minecraft process starts.',
},
defaultLandingPageTitle: {
id: 'app.appearance-settings.default-landing-page.title',
defaultMessage: 'Default landing page',
},
defaultLandingPageDescription: {
id: 'app.appearance-settings.default-landing-page.description',
defaultMessage: 'Change the page to which the launcher opens on.',
},
defaultLandingPageHome: {
id: 'app.appearance-settings.default-landing-page.home',
defaultMessage: 'Home',
},
defaultLandingPageLibrary: {
id: 'app.appearance-settings.default-landing-page.library',
defaultMessage: 'Library',
},
selectOption: {
id: 'app.appearance-settings.select-option',
defaultMessage: 'Select an option',
},
jumpBackIntoWorldsTitle: {
id: 'app.appearance-settings.jump-back-into-worlds.title',
defaultMessage: 'Jump back into worlds',
},
jumpBackIntoWorldsDescription: {
id: 'app.appearance-settings.jump-back-into-worlds.description',
defaultMessage: 'Includes recent worlds in the "Jump back in" section on the Home page.',
},
toggleSidebarTitle: {
id: 'app.appearance-settings.toggle-sidebar.title',
defaultMessage: 'Toggle sidebar',
},
toggleSidebarDescription: {
id: 'app.appearance-settings.toggle-sidebar.description',
defaultMessage: 'Enables the ability to toggle the sidebar.',
},
unknownPackWarningTitle: {
id: 'app.appearance-settings.unknown-pack-warning.title',
defaultMessage: 'Warn me before installing unknown modpacks',
},
unknownPackWarningDescription: {
id: 'app.appearance-settings.unknown-pack-warning.description',
defaultMessage:
"If you attempt to install a Modrinth Pack file (.mrpack) that isn't hosted on Modrinth, we'll make sure you understand the risks before installing it.",
},
})
const os = ref(await getOS())
const settings = ref(await get())
@@ -114,10 +21,8 @@ watch(
)
</script>
<template>
<h2 class="m-0 text-lg font-semibold text-contrast">
{{ formatMessage(messages.colorThemeTitle) }}
</h2>
<p class="m-0 mt-1">{{ formatMessage(messages.colorThemeDescription) }}</p>
<h2 class="m-0 text-lg font-semibold text-contrast">Color theme</h2>
<p class="m-0 mt-1">Select your preferred color theme for Modrinth App.</p>
<ThemeSelector
:update-color-theme="
@@ -133,11 +38,10 @@ watch(
<div class="mt-6 flex items-center justify-between">
<div>
<h2 class="m-0 text-lg font-semibold text-contrast">
{{ formatMessage(messages.advancedRenderingTitle) }}
</h2>
<h2 class="m-0 text-lg font-semibold text-contrast">Advanced rendering</h2>
<p class="m-0 mt-1">
{{ formatMessage(messages.advancedRenderingDescription) }}
Enables advanced rendering such as blur effects that may cause performance issues without
hardware-accelerated rendering.
</p>
</div>
@@ -155,94 +59,55 @@ watch(
<div class="mt-6 flex items-center justify-between">
<div>
<h2 class="m-0 text-lg font-semibold text-contrast">
{{ formatMessage(messages.hideNametagTitle) }}
</h2>
<p class="m-0 mt-1">{{ formatMessage(messages.hideNametagDescription) }}</p>
<h2 class="m-0 text-lg font-semibold text-contrast">Hide nametag</h2>
<p class="m-0 mt-1">Disables the nametag above your player on the skins page.</p>
</div>
<Toggle id="hide-nametag-skins-page" v-model="settings.hide_nametag_skins_page" />
</div>
<div v-if="os !== 'MacOS'" class="mt-6 flex items-center justify-between gap-4">
<div>
<h2 class="m-0 text-lg font-semibold text-contrast">
{{ formatMessage(messages.nativeDecorationsTitle) }}
</h2>
<p class="m-0 mt-1">{{ formatMessage(messages.nativeDecorationsDescription) }}</p>
<h2 class="m-0 text-lg font-semibold text-contrast">Native decorations</h2>
<p class="m-0 mt-1">Use system window frame (app restart required).</p>
</div>
<Toggle id="native-decorations" v-model="settings.native_decorations" />
</div>
<div class="mt-6 flex items-center justify-between">
<div>
<h2 class="m-0 text-lg font-semibold text-contrast">
{{ formatMessage(messages.minimizeLauncherTitle) }}
</h2>
<p class="m-0 mt-1">{{ formatMessage(messages.minimizeLauncherDescription) }}</p>
<h2 class="m-0 text-lg font-semibold text-contrast">Minimize launcher</h2>
<p class="m-0 mt-1">Minimize the launcher when a Minecraft process starts.</p>
</div>
<Toggle id="minimize-launcher" v-model="settings.hide_on_process_start" />
</div>
<div class="mt-6 flex items-center justify-between">
<div>
<h2 class="m-0 text-lg font-semibold text-contrast">
{{ formatMessage(messages.defaultLandingPageTitle) }}
</h2>
<p class="m-0 mt-1">{{ formatMessage(messages.defaultLandingPageDescription) }}</p>
<h2 class="m-0 text-lg font-semibold text-contrast">Default landing page</h2>
<p class="m-0 mt-1">Change the page to which the launcher opens on.</p>
</div>
<Combobox
id="opening-page"
v-model="settings.default_page"
name="Opening page dropdown"
class="max-w-40"
:options="[
{
value: 'Home',
label: formatMessage(messages.defaultLandingPageHome),
},
{
value: 'Library',
label: formatMessage(messages.defaultLandingPageLibrary),
},
]"
:options="['Home', 'Library'].map((v) => ({ value: v, label: v }))"
:display-value="settings.default_page ?? 'Select an option'"
/>
</div>
<div class="mt-6 flex items-center justify-between">
<div>
<h2 class="m-0 text-lg font-semibold text-contrast">
{{ formatMessage(messages.jumpBackIntoWorldsTitle) }}
</h2>
<p class="m-0 mt-1">{{ formatMessage(messages.jumpBackIntoWorldsDescription) }}</p>
<h2 class="m-0 text-lg font-semibold text-contrast">Jump back into worlds</h2>
<p class="m-0 mt-1">Includes recent worlds in the "Jump back in" section on the Home page.</p>
</div>
<Toggle
:model-value="themeStore.getFeatureFlag(worldsInHomeFeatureFlag)"
:model-value="themeStore.getFeatureFlag('worlds_in_home')"
@update:model-value="
() => {
const newValue = !themeStore.getFeatureFlag(worldsInHomeFeatureFlag)
themeStore.featureFlags[worldsInHomeFeatureFlag] = newValue
settings.feature_flags[worldsInHomeFeatureFlag] = newValue
}
"
/>
</div>
<div class="mt-6 flex items-center justify-between gap-4">
<div>
<h2 class="m-0 text-lg font-semibold text-contrast">
{{ formatMessage(messages.unknownPackWarningTitle) }}
</h2>
<p class="m-0 mt-1">{{ formatMessage(messages.unknownPackWarningDescription) }}</p>
</div>
<Toggle
:model-value="!themeStore.getFeatureFlag(skipUnknownPackWarningFeatureFlag)"
@update:model-value="
(e) => {
const warnBeforeUnknownPackInstall = !!e
const skipUnknownPackWarning = !warnBeforeUnknownPackInstall
themeStore.featureFlags[skipUnknownPackWarningFeatureFlag] = skipUnknownPackWarning
settings.feature_flags[skipUnknownPackWarningFeatureFlag] = skipUnknownPackWarning
const newValue = !themeStore.getFeatureFlag('worlds_in_home')
themeStore.featureFlags['worlds_in_home'] = newValue
settings.feature_flags['worlds_in_home'] = newValue
}
"
/>
@@ -250,10 +115,8 @@ watch(
<div class="mt-6 flex items-center justify-between">
<div>
<h2 class="m-0 text-lg font-semibold text-contrast">
{{ formatMessage(messages.toggleSidebarTitle) }}
</h2>
<p class="m-0 mt-1">{{ formatMessage(messages.toggleSidebarDescription) }}</p>
<h2 class="m-0 text-lg font-semibold text-contrast">Toggle sidebar</h2>
<p class="m-0 mt-1">Enables the ability to toggle the sidebar.</p>
</div>
<Toggle
id="toggle-sidebar"
@@ -1,6 +1,6 @@
<script setup>
import { BoxIcon, FolderSearchIcon, TrashIcon } from '@modrinth/assets'
import { ButtonStyled, injectNotificationManager, Slider, StyledInput } from '@modrinth/ui'
import { Button, injectNotificationManager, Slider, StyledInput } from '@modrinth/ui'
import { open } from '@tauri-apps/plugin-dialog'
import { ref, watch } from 'vue'
@@ -73,11 +73,9 @@ async function findLauncherDir() {
wrapper-class="w-full"
>
<template #right>
<ButtonStyled circular>
<button class="ml-1.5" @click="findLauncherDir">
<FolderSearchIcon />
</button>
</ButtonStyled>
<Button class="ml-1.5" @click="findLauncherDir">
<FolderSearchIcon />
</Button>
</template>
</StyledInput>
<p class="m-0 leading-tight text-secondary">
@@ -25,9 +25,7 @@
<div class="flex flex-col gap-4 w-full min-h-[20rem]">
<section>
<h2 class="text-base font-semibold mb-2">Texture</h2>
<ButtonStyled>
<button @click="openUploadSkinModal"><UploadIcon /> Replace texture</button>
</ButtonStyled>
<Button @click="openUploadSkinModal"> <UploadIcon /> Replace texture </Button>
</section>
<section>
@@ -81,7 +79,7 @@
</div>
<div class="flex gap-2 mt-12">
<ButtonStyled color="brand">
<ButtonStyled color="brand" :disabled="disableSave || isSaving">
<button v-tooltip="saveTooltip" :disabled="disableSave || isSaving" @click="save">
<SpinnerIcon v-if="isSaving" class="animate-spin" />
<CheckIcon v-else-if="mode === 'new'" />
@@ -89,9 +87,7 @@
{{ mode === 'new' ? 'Add skin' : 'Save skin' }}
</button>
</ButtonStyled>
<ButtonStyled type="outlined">
<button :disabled="isSaving" @click="hide"><XIcon />Cancel</button>
</ButtonStyled>
<Button :disabled="isSaving" @click="hide"><XIcon />Cancel</Button>
</div>
</ModalWrapper>
@@ -113,6 +109,7 @@ import {
XIcon,
} from '@modrinth/assets'
import {
Button,
ButtonStyled,
CapeButton,
CapeLikeTextButton,
@@ -79,7 +79,7 @@ watch([() => props.recentInstances, () => showWorlds.value], async () => {
})
})
await populateJumpBackIn()
populateJumpBackIn()
.catch(() => {
console.error('Failed to populate jump back in')
})
@@ -93,7 +93,7 @@ defineExpose({ show, hide })
<template #actions>
<div class="flex gap-2 justify-end">
<ButtonStyled type="outlined">
<button @click="hide()">
<button class="!border !border-surface-4" @click="hide()">
<XIcon />
{{ formatMessage(commonMessages.cancelButton) }}
</button>
@@ -106,7 +106,7 @@ const titleMessage = defineMessage({
<template #actions>
<div class="flex gap-2 justify-end">
<ButtonStyled type="outlined">
<button @click="hide()">
<button class="!border !border-surface-4" @click="hide()">
<XIcon />
{{ formatMessage(commonMessages.cancelButton) }}
</button>
@@ -1,332 +0,0 @@
import type { Labrinth } from '@modrinth/api-client'
import { CheckIcon, PlayIcon, PlusIcon, StopCircleIcon } from '@modrinth/assets'
import type { CardAction } from '@modrinth/ui'
import { commonMessages, defineMessages, useDebugLogger, useVIntl } from '@modrinth/ui'
import { openUrl } from '@tauri-apps/plugin-opener'
import type { ComputedRef, Ref } from 'vue'
import { onUnmounted, ref, shallowRef } from 'vue'
import type { Router } from 'vue-router'
import { process_listener } from '@/helpers/events'
import { get_by_profile_path } from '@/helpers/process'
import { kill, list as listInstances } from '@/helpers/profile.js'
import type { GameInstance } from '@/helpers/types'
import { add_server_to_profile, getServerLatency } from '@/helpers/worlds'
import { getServerAddress } from '@/store/install.js'
interface BrowseServerInstance {
name: string
path: string
}
interface ContextMenuHandle {
showMenu: (
event: MouseEvent,
result: Labrinth.Search.v2.ResultSearchProject | Labrinth.Search.v3.ResultSearchProject,
options: { name: string }[],
) => void
}
interface ContextMenuOptionClick {
option: 'open_link' | 'copy_link'
item: Labrinth.Search.v2.ResultSearchProject | Labrinth.Search.v3.ResultSearchProject
}
export interface UseAppServerBrowseOptions {
instance: Ref<BrowseServerInstance | null>
isFromWorlds: ComputedRef<boolean>
allInstalledIds: ComputedRef<Set<string>>
newlyInstalled: Ref<string[]>
installingServerProjects: Ref<string[]>
playServerProject: (projectId: string) => Promise<void>
showAddServerToInstanceModal: (serverName: string, serverAddress: string) => void
handleError: (error: unknown) => void
router: Router
}
const messages = defineMessages({
addToInstance: {
id: 'app.browse.add-to-instance',
defaultMessage: 'Add to instance',
},
addToInstanceName: {
id: 'app.browse.add-to-instance-name',
defaultMessage: 'Add to {instanceName}',
},
added: {
id: 'app.browse.added',
defaultMessage: 'Added',
},
alreadyAdded: {
id: 'app.browse.already-added',
defaultMessage: 'Already added',
},
})
export function useAppServerBrowse(options: UseAppServerBrowseOptions) {
const { formatMessage } = useVIntl()
const debugLog = useDebugLogger('BrowseServer')
const serverPings = shallowRef<Record<string, number | undefined>>({})
const serverPingCache = new Map<string, number | undefined>()
const pendingServerPings = new Map<string, Promise<number | undefined>>()
const runningServerProjects = ref<Record<string, string>>({})
const lastServerHits = shallowRef<Labrinth.Search.v3.ResultSearchProject[]>([])
const contextMenuRef = ref<ContextMenuHandle | null>(null)
let serverPingCacheActive = true
let unlistenProcesses: (() => void) | null = null
async function checkServerRunningStates(hits: Labrinth.Search.v3.ResultSearchProject[]) {
debugLog('checkServerRunningStates', { hitCount: hits.length })
const packs = await listInstances().catch((error) => {
options.handleError(error)
return []
})
const newRunning: Record<string, string> = {}
for (const hit of hits) {
const inst = packs.find(
(pack: GameInstance) => pack.linked_data?.project_id === hit.project_id,
)
if (inst) {
const processes = await get_by_profile_path(inst.path).catch(() => [])
if (Array.isArray(processes) && processes.length > 0) {
newRunning[hit.project_id] = inst.path
}
}
}
debugLog('runningServerProjects updated', newRunning)
runningServerProjects.value = newRunning
}
async function handleStopServerProject(projectId: string) {
debugLog('handleStopServerProject', projectId)
const instancePath = runningServerProjects.value[projectId]
if (!instancePath) return
await kill(instancePath).catch(() => {})
const { [projectId]: _, ...rest } = runningServerProjects.value
runningServerProjects.value = rest
}
async function handlePlayServerProject(projectId: string) {
debugLog('handlePlayServerProject', projectId)
await options.playServerProject(projectId)
checkServerRunningStates(lastServerHits.value)
}
async function handleAddServerToInstance(project: Labrinth.Search.v3.ResultSearchProject) {
debugLog('handleAddServerToInstance', { projectId: project.project_id, name: project.name })
const address = getServerAddress(project.minecraft_java_server)
if (!address) return
if (options.instance.value) {
try {
await add_server_to_profile(
options.instance.value.path,
project.name,
address,
'prompt',
project.project_id,
project.minecraft_java_server?.content?.kind,
)
options.newlyInstalled.value.push(project.project_id)
} catch (error) {
options.handleError(error)
}
} else {
options.showAddServerToInstanceModal(project.name, address)
}
}
async function pingServerHits(hits: Labrinth.Search.v3.ResultSearchProject[]) {
debugLog('pingServerHits', { hitCount: hits.length })
const pingsToFetch = hits.flatMap((hit) => {
const address = hit.minecraft_java_server?.address
if (!address) return []
return [{ hit, address }]
})
const nextPings = { ...serverPings.value }
for (const { hit, address } of pingsToFetch) {
if (serverPingCache.has(address)) {
nextPings[hit.project_id] = serverPingCache.get(address)
}
}
serverPings.value = nextPings
await Promise.all(
pingsToFetch.map(async ({ hit, address }) => {
if (serverPingCache.has(address)) return
let pending = pendingServerPings.get(address)
if (!pending) {
pending = getServerLatency(address)
.then((latency) => {
if (serverPingCacheActive) serverPingCache.set(address, latency)
return latency
})
.catch((error) => {
console.error(`Failed to ping server ${address}:`, error)
if (serverPingCacheActive) serverPingCache.set(address, undefined)
return undefined
})
.finally(() => {
pendingServerPings.delete(address)
})
pendingServerPings.set(address, pending)
}
const latency = await pending
if (!serverPingCacheActive) return
serverPings.value = { ...serverPings.value, [hit.project_id]: latency }
}),
)
}
function updateServerHits(hits: Labrinth.Search.v3.ResultSearchProject[]) {
lastServerHits.value = hits
pingServerHits(hits)
checkServerRunningStates(hits)
}
function getServerModpackContent(project: Labrinth.Search.v3.ResultSearchProject) {
const content = project.minecraft_java_server?.content
if (content?.kind === 'modpack') {
const { project_name, project_icon, project_id } = content
if (!project_name) return undefined
return {
name: project_name,
icon: project_icon ?? undefined,
onclick:
project_id !== project.project_id
? () => {
options.router.push(`/project/${project_id}`)
}
: undefined,
showCustomModpackTooltip: project_id === project.project_id,
}
}
return undefined
}
function getServerCardActions(
serverResult: Labrinth.Search.v3.ResultSearchProject,
): CardAction[] {
const isInstalled = options.allInstalledIds.value.has(serverResult.project_id)
if (options.isFromWorlds.value && options.instance.value) {
return [
{
key: 'add-to-instance',
label: formatMessage(isInstalled ? messages.added : messages.addToInstance),
icon: isInstalled ? CheckIcon : PlusIcon,
disabled: isInstalled,
color: 'brand',
type: 'outlined',
onClick: () => handleAddServerToInstance(serverResult),
},
]
}
const actions: CardAction[] = []
actions.push({
key: 'add',
label: '',
icon: isInstalled ? CheckIcon : PlusIcon,
disabled: isInstalled,
circular: true,
tooltip: isInstalled
? formatMessage(messages.alreadyAdded)
: options.instance.value
? formatMessage(messages.addToInstanceName, {
instanceName: options.instance.value.name,
})
: formatMessage(commonMessages.addServerToInstanceButton),
onClick: () => handleAddServerToInstance(serverResult),
})
if (runningServerProjects.value[serverResult.project_id]) {
actions.push({
key: 'stop',
label: formatMessage(commonMessages.stopButton),
icon: StopCircleIcon,
color: 'red',
type: 'outlined',
onClick: () => handleStopServerProject(serverResult.project_id),
})
} else {
const isInstalling = options.installingServerProjects.value.includes(serverResult.project_id)
actions.push({
key: 'play',
label: formatMessage(
isInstalling ? commonMessages.installingLabel : commonMessages.playButton,
),
icon: PlayIcon,
disabled: isInstalling,
color: 'brand',
type: 'outlined',
onClick: () => handlePlayServerProject(serverResult.project_id),
})
}
return actions
}
function handleRightClick(
event: MouseEvent,
result: Labrinth.Search.v2.ResultSearchProject | Labrinth.Search.v3.ResultSearchProject,
) {
contextMenuRef.value?.showMenu(event, result, [{ name: 'open_link' }, { name: 'copy_link' }])
}
function handleOptionsClick(args: ContextMenuOptionClick) {
const url = getProjectUrl(args.item)
switch (args.option) {
case 'open_link':
openUrl(url)
break
case 'copy_link':
navigator.clipboard.writeText(url)
break
}
}
process_listener((event: { event: string; profile_path_id: string }) => {
debugLog('process event', event)
if (event.event === 'finished') {
const projectId = Object.entries(runningServerProjects.value).find(
([, path]) => path === event.profile_path_id,
)?.[0]
if (projectId) {
const { [projectId]: _, ...rest } = runningServerProjects.value
runningServerProjects.value = rest
}
}
})
.then((unlisten) => {
unlistenProcesses = unlisten
})
.catch(options.handleError)
onUnmounted(() => {
serverPingCacheActive = false
unlistenProcesses?.()
serverPingCache.clear()
pendingServerPings.clear()
})
return {
serverPings,
contextMenuRef,
updateServerHits,
getServerModpackContent,
getServerCardActions,
handleRightClick,
handleOptionsClick,
}
}
function getProjectUrl(
item: Labrinth.Search.v2.ResultSearchProject | Labrinth.Search.v3.ResultSearchProject,
) {
const projectType = 'project_types' in item ? item.project_types?.[0] : item.project_type
return `https://modrinth.com/${projectType ?? 'project'}/${item.slug ?? item.project_id}`
}
@@ -1,121 +0,0 @@
import { computed, onUnmounted, ref } from 'vue'
import type { RouteLocationNormalizedLoaded } from 'vue-router'
interface ThemeStore {
toggleSidebar: boolean
$subscribe: (callback: () => void) => () => void
}
interface IntercomBubblePosition {
horizontalPadding: number
verticalPadding: number
}
const APP_LEFT_NAV_WIDTH = '4rem'
const APP_SIDEBAR_WIDTH = 300
const INTERCOM_BUBBLE_DEFAULT_PADDING = 20
const INTERCOM_BUBBLE_WIDTH = 72
const INTERCOM_BUBBLE_RIGHT_VAR = '--app-support-launcher-right'
const INTERCOM_BUBBLE_BOTTOM_VAR = '--app-support-launcher-bottom'
export function useIntercomPositioning({
route,
themeStore,
}: {
route: RouteLocationNormalizedLoaded
themeStore: ThemeStore
}) {
const sidebarToggled = ref(true)
const unsubscribeSidebarToggle = themeStore.$subscribe(() => {
sidebarToggled.value = !themeStore.toggleSidebar
})
onUnmounted(unsubscribeSidebarToggle)
const forceSidebar = computed(
() => route.path.startsWith('/browse') || route.path.startsWith('/project'),
)
const sidebarVisible = computed(() => sidebarToggled.value || forceSidebar.value)
const defaultIntercomBubbleHorizontalPadding = computed(() =>
sidebarVisible.value
? APP_SIDEBAR_WIDTH + INTERCOM_BUBBLE_DEFAULT_PADDING
: INTERCOM_BUBBLE_DEFAULT_PADDING,
)
const intercomBubbleRequestedHorizontalPadding = ref<number | null>(null)
const intercomBubbleHorizontalPadding = computed(
() =>
intercomBubbleRequestedHorizontalPadding.value ??
defaultIntercomBubbleHorizontalPadding.value,
)
const intercomBubbleVerticalClearance = ref<number | null>(null)
const intercomBubblePosition = computed(() => ({
horizontalPadding: intercomBubbleHorizontalPadding.value,
verticalPadding: intercomBubbleVerticalClearance.value ?? INTERCOM_BUBBLE_DEFAULT_PADDING,
}))
const intercomBubbleHorizontalPaddingRequests = new Map<symbol, number>()
const intercomBubbleClearanceRequests = new Map<symbol, number>()
function requestIntercomBubbleHorizontalPadding(id: symbol, padding: number | null) {
if (padding === null) {
intercomBubbleHorizontalPaddingRequests.delete(id)
} else {
intercomBubbleHorizontalPaddingRequests.set(id, padding)
}
intercomBubbleRequestedHorizontalPadding.value =
intercomBubbleHorizontalPaddingRequests.size > 0
? Math.max(...intercomBubbleHorizontalPaddingRequests.values())
: null
}
function requestIntercomBubbleVerticalClearance(id: symbol, clearance: number | null) {
if (clearance === null) {
intercomBubbleClearanceRequests.delete(id)
} else {
intercomBubbleClearanceRequests.set(id, clearance)
}
intercomBubbleVerticalClearance.value =
intercomBubbleClearanceRequests.size > 0
? Math.max(...intercomBubbleClearanceRequests.values())
: null
}
function updateIntercomBubbleStyles({
horizontalPadding,
verticalPadding,
}: IntercomBubblePosition) {
if (typeof document === 'undefined') return
document.documentElement.style.setProperty(INTERCOM_BUBBLE_RIGHT_VAR, `${horizontalPadding}px`)
document.documentElement.style.setProperty(INTERCOM_BUBBLE_BOTTOM_VAR, `${verticalPadding}px`)
}
function clearIntercomBubbleStyles() {
if (typeof document === 'undefined') return
document.documentElement.style.removeProperty(INTERCOM_BUBBLE_RIGHT_VAR)
document.documentElement.style.removeProperty(INTERCOM_BUBBLE_BOTTOM_VAR)
}
return {
sidebarToggled,
forceSidebar,
sidebarVisible,
intercomBubblePosition,
updateIntercomBubbleStyles,
clearIntercomBubbleStyles,
pageContext: {
floatingActionBarOffsets: {
left: ref(APP_LEFT_NAV_WIDTH),
right: computed(() => (sidebarVisible.value ? `${APP_SIDEBAR_WIDTH}px` : '0px')),
},
intercomBubble: {
width: ref(INTERCOM_BUBBLE_WIDTH),
horizontalPadding: intercomBubbleHorizontalPadding,
requestHorizontalPadding: requestIntercomBubbleHorizontalPadding,
requestVerticalClearance: requestIntercomBubbleVerticalClearance,
},
},
}
}
@@ -1,35 +0,0 @@
import { OverlayScrollbars, type PartialOptions } from 'overlayscrollbars'
import type { ObjectDirective } from 'vue'
const defaultOverlayScrollbarsOptions = Object.freeze<PartialOptions>({
scrollbars: {
theme: 'os-theme-dark',
autoHide: 'leave',
autoHideSuspend: true,
},
})
const mergeOptions = (options: PartialOptions = {}): PartialOptions => ({
...defaultOverlayScrollbarsOptions,
...options,
scrollbars: {
...defaultOverlayScrollbarsOptions.scrollbars,
...(options.scrollbars ?? {}),
},
})
export const overlayScrollbarsDirective: ObjectDirective<HTMLElement, PartialOptions | undefined> =
{
mounted(el, binding) {
OverlayScrollbars(el, mergeOptions(binding.value))
},
updated(el, binding) {
if (binding.value === binding.oldValue) return
const instance = OverlayScrollbars(el)
instance?.options(mergeOptions(binding.value))
},
unmounted(el) {
const instance = OverlayScrollbars(el)
instance?.destroy()
},
}
+10 -25
View File
@@ -8,7 +8,6 @@ interface PackProfileCreator {
gameVersion: string
modloader: InstanceLoader
loaderVersion: string | null
unknownFile: boolean
}
interface PackLocationVersionId {
@@ -70,10 +69,7 @@ export async function install_to_existing_profile(
return await invoke('plugin:pack|pack_install', { location, profile: profilePath })
}
export async function create_profile_and_install_from_file(
path: string,
showUnknownPackWarningModal?: (createProfile: () => Promise<void>, fileName: string) => void,
): Promise<void> {
export async function create_profile_and_install_from_file(path: string): Promise<void> {
const location: PackLocationFile = {
type: 'fromFile',
path,
@@ -82,24 +78,13 @@ export async function create_profile_and_install_from_file(
'plugin:pack|pack_get_profile_from_pack',
{ location },
)
const createProfile = async () => {
const profile = await create(
profile_creator.name,
profile_creator.gameVersion,
profile_creator.modloader,
profile_creator.loaderVersion,
null,
true,
)
await invoke('plugin:pack|pack_install', { location, profile })
}
if (profile_creator.unknownFile && showUnknownPackWarningModal) {
const splitPath = path.split(/[\\/]/)
const fileName = splitPath ? splitPath[splitPath.length - 1] : path
showUnknownPackWarningModal(createProfile, fileName)
} else {
await createProfile()
}
const profile = await create(
profile_creator.name,
profile_creator.gameVersion,
profile_creator.modloader,
profile_creator.loaderVersion,
null,
true,
)
return await invoke('plugin:pack|pack_install', { location, profile })
}
+2 -12
View File
@@ -184,18 +184,8 @@ export async function update_project(path: string, projectPath: string): Promise
// Add a project to a profile from a version
// Returns a path to the new project file
export type DownloadReason = 'standalone' | 'dependency' | 'modpack' | 'update'
export async function add_project_from_version(
path: string,
versionId: string,
reason: DownloadReason,
): Promise<string> {
return await invoke('plugin:profile|profile_add_project_from_version', {
path,
versionId,
reason,
})
export async function add_project_from_version(path: string, versionId: string): Promise<string> {
return await invoke('plugin:profile|profile_add_project_from_version', { path, versionId })
}
// Add a project to a profile from a path + project_type
@@ -1,83 +0,0 @@
import type { LocationQuery, LocationQueryRaw } from 'vue-router'
const MODRINTH_HOSTNAMES = new Set(['modrinth.com', 'www.modrinth.com'])
const SUPPORTED_PROJECT_TYPES = new Set([
'mod',
'modpack',
'resourcepack',
'datapack',
'plugin',
'shader',
'server',
'project',
])
export function parseModrinthLink(
href: string,
): { slug: string; pathSuffix: string; url: URL } | null {
let url: URL
try {
url = new URL(href)
} catch {
return null
}
if (!MODRINTH_HOSTNAMES.has(url.hostname.toLowerCase())) {
return null
}
const segments = url.pathname.split('/').filter((p) => p.length > 0)
if (segments.length < 2) {
return null
}
if (SUPPORTED_PROJECT_TYPES.has(segments[0].toLowerCase())) {
const slug = segments[1]
if (!slug) {
return null
}
const rest: string[] = segments.slice(2)
const pathSuffix = toValidAppSubpath(rest)
if (pathSuffix === null) {
return null
}
return { slug, pathSuffix, url }
} else {
return null
}
}
const SUPPORTED_SUBPATHS = ['versions', 'gallery']
function toValidAppSubpath(rest: string[]): string | null {
if (rest.length === 0) {
return ''
}
const subroute = rest[0].toLowerCase()
if (rest.length === 1 && SUPPORTED_SUBPATHS.includes(subroute)) {
return `/${subroute}`
}
if (rest.length === 2 && subroute === 'version') {
return `/version/${rest[1]}`
}
return null
}
export function mergeUrlQuery(routeQuery: LocationQuery, linkUrl: URL): LocationQueryRaw {
const newQuery: LocationQueryRaw = { ...routeQuery }
const keys = new Set<string>()
linkUrl.searchParams.forEach((_value, key) => {
keys.add(key)
})
for (const key of keys) {
const values = linkUrl.searchParams.getAll(key)
newQuery[key] = values.length === 1 ? values[0] : values
}
return newQuery
}
@@ -5,46 +5,15 @@
*/
import { invoke } from '@tauri-apps/api/core'
export interface LoadingBarType {
type?: string
version?: string
profile_path?: string
pack_name?: string
}
export interface LoadingBar {
id?: string | number
loading_bar_uuid?: string | number
title?: string
message?: string
current?: number
total?: number
bar_type?: LoadingBarType
}
export type OpeningCommandEvent =
| 'RunMRPack'
| 'InstallServer'
| 'InstallVersion'
| 'InstallMod'
| 'InstallModpack'
| string
export interface OpeningCommand {
event: OpeningCommandEvent
id?: string
path?: string
}
// Initialize the theseus API state
// This should be called during the initializion/opening of the launcher
export async function initialize_state() {
return await invoke<void>('initialize_state')
return await invoke('initialize_state')
}
// Gets active progress bars
export async function progress_bars_list() {
return await invoke<Record<string, LoadingBar>>('plugin:utils|progress_bars_list')
return await invoke('plugin:utils|progress_bars_list')
}
// Get opening command
@@ -52,5 +21,5 @@ export async function progress_bars_list() {
// This should be called once and only when the app is done booting up and ready to receive a command
// Returns a Command struct- see events.js
export async function get_opening_command() {
return await invoke<OpeningCommand | null>('plugin:utils|get_opening_command')
return await invoke('plugin:utils|get_opening_command')
}
-4
View File
@@ -22,10 +22,6 @@ export async function removeEnqueuedUpdate() {
return await invoke('remove_enqueued_update')
}
export async function setRestartAfterPendingUpdate(should_restart) {
return await invoke('set_restart_after_pending_update', { shouldRestart: should_restart })
}
// One of 'Windows', 'Linux', 'MacOS'
export async function getOS() {
return await invoke('plugin:utils|get_os')
+13 -115
View File
@@ -1,37 +1,10 @@
{
"app.action-bar.downloading-java": {
"message": "جاز تنزيل إصدار جافا {version}"
},
"app.action-bar.downloads": {
"message": "التنزيلات"
},
"app.auth-servers.unreachable.body": {
"message": "قد تكون خوادم مصادقة ماينكرافت معطلة حاليًا. تحقق من اتصالك بالإنترنت وحاول مرة أخرى لاحقًا."
},
"app.auth-servers.unreachable.header": {
"message": "تعذر الوصول إلى خوادم المصادقة"
},
"app.browse.add-to-instance": {
"message": "أضف للنموذج"
},
"app.browse.add-to-instance-name": {
"message": "أضف للنموذج {instanceName}"
},
"app.browse.added": {
"message": "مضاف"
},
"app.browse.already-added": {
"message": "مضاف فعلا"
},
"app.browse.discover-content": {
"message": "استكشف محتوى"
},
"app.browse.discover-servers": {
"message": "استكشف خوادم"
},
"app.browse.server.installing": {
"message": "جاري التثبيت"
},
"app.export-modal.description-placeholder": {
"message": "أدخل وصف التعديل..."
},
@@ -47,6 +20,9 @@
"app.export-modal.modpack-name-placeholder": {
"message": "إسم حزمة التعديل"
},
"app.export-modal.select-files-label": {
"message": "حدد الملفات والمجلدات المراد تضمينها في الحزمة"
},
"app.export-modal.version-number-label": {
"message": "رقم الإصدار"
},
@@ -54,28 +30,19 @@
"message": "1.0.0"
},
"app.instance.confirm-delete.admonition-body": {
"message": "سيتم حذف جميع البيانات الخاصة لنموذجك نهائيًا، بما في ذلك عوالمك والتكوينات وكل المحتوى المثبت."
"message": "سيتم حذف جميع البيانات الخاصة بمثيلك نهائيًا، بما في ذلك عوالمك والتكوينات وكل المحتوى المثبت."
},
"app.instance.confirm-delete.admonition-header": {
"message": "لا يمكن التراجع عن هذا الإجراء"
},
"app.instance.confirm-delete.delete-button": {
"message": "حذف النموذج"
"message": "حذف المثيل"
},
"app.instance.confirm-delete.header": {
"message": "حذف النموذج"
},
"app.instance.modpack-already-installed.body": {
"message": "حُزْمَة التعديل هذه مثبته فعلًا في نموذج <bold>{instanceName}</bold>. هل انت متأكد بإرادة نسخه؟"
},
"app.instance.modpack-already-installed.create": {
"message": "إنشاء"
"message": "حذف المثيل"
},
"app.instance.modpack-already-installed.header": {
"message": "حُزْمَة التعديل مثبتة بالفعل"
},
"app.instance.modpack-already-installed.instance": {
"message": "النموذج"
"message": "تم تثبيت حزمة التعديل بالفعل"
},
"app.instance.mods.content-type-project": {
"message": "مشروع"
@@ -84,7 +51,7 @@
"message": "تمت إضافة \"{name}\""
},
"app.instance.mods.projects-were-added": {
"message": "تمت إضافة {count} مشروع"
"message": "تمت إضافة {count} من المشاريع"
},
"app.instance.mods.share-text": {
"message": "تحقق من المشاريع التي أستخدمها في حزمة التعديل الخاص بي!"
@@ -95,51 +62,6 @@
"app.instance.mods.successfully-uploaded": {
"message": "تم الرفع بنجاح"
},
"app.instance.worlds.add-server": {
"message": "أضف خادم"
},
"app.instance.worlds.browse-servers": {
"message": "تصفح الخوادم"
},
"app.instance.worlds.delete-world-description": {
"message": "سيتم حذف '{name}' **نهائيا**, و لن هناك أي طريقة لاسترداده."
},
"app.instance.worlds.delete-world-title": {
"message": "هل أنت متيقِّن من رغبتك بحذف هذا العالم نهائيا؟"
},
"app.instance.worlds.filter-modded": {
"message": "معدّل"
},
"app.instance.worlds.filter-offline": {
"message": "مفصول"
},
"app.instance.worlds.filter-online": {
"message": "يعمل"
},
"app.instance.worlds.filter-vanilla": {
"message": "الأصلي"
},
"app.instance.worlds.no-worlds-description": {
"message": "أضف خادما أو تصفح لكي تبدأ"
},
"app.instance.worlds.no-worlds-heading": {
"message": "لم تتم إضافة أي من الخوادم أو العوالم"
},
"app.instance.worlds.remove-server-description": {
"message": "ستتم إزالة '{name}' من قائمتك, إضافة لما داخل اللعبة, و لن يكون هناك أي طريقة لاسترداده."
},
"app.instance.worlds.remove-server-description-with-address": {
"message": "ستتم إزالة '{name}' ({address}) من قائمتك, إضافة لما داخل اللعبة, و لن يكون هناك أي طريقة لاسترداده."
},
"app.instance.worlds.remove-server-title": {
"message": "هل أنت متيقِّن من رغبتك في إزالة {name}؟"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "ابحث بين ال{count} عوالم..."
},
"app.instance.worlds.this-server": {
"message": "هذا الخادم"
},
"app.modal.install-to-play.content-required": {
"message": "المحتوى مطلوب"
},
@@ -159,10 +81,10 @@
"message": "يتطلب هذا الخادم تعديلات للعب. انقر فوق \"تثبيت\" لإعداد الملفات المطلوبة من Modrinth، ثم قم بتشغيله مباشرة إلى الخادم."
},
"app.modal.install-to-play.shared-instance": {
"message": "النماذج المشتركة"
"message": "حزمة مشتركة"
},
"app.modal.install-to-play.shared-server-instance": {
"message": "نماذج الخادم مشتركة"
"message": "حزمة خادم مشتركة"
},
"app.modal.install-to-play.view-contents": {
"message": "عرض المحتويات"
@@ -174,7 +96,7 @@
"message": "يلزم التحديث"
},
"app.modal.update-to-play.update-required-description": {
"message": "هناك تحديث مطلوب للعب بـ {name}. الرجاء التحديث إلى آخر اصدار لتشغيل اللعبة."
"message": "هناك تحديث لازم للعب بـ {name}. الرجاء التحديث إلى آخر اصدار لتشغيل اللعبة."
},
"app.settings.developer-mode-enabled": {
"message": "تم تفعيل وضع المطوّر."
@@ -242,24 +164,6 @@
"app.update.reload-to-update": {
"message": "أعد التحميل لتثبيت التحديث"
},
"app.world.server-modal.placeholder-address": {
"message": "مثال.مودرنث.جج"
},
"app.world.server-modal.select-an-option": {
"message": "حدد خيارا"
},
"app.world.world-item.incompatible-version": {
"message": "إصدار غير مطابق ({version})"
},
"app.world.world-item.not-played-yet": {
"message": "لم يتم اللعب به"
},
"app.world.world-item.offline": {
"message": "مفصول"
},
"app.world.world-item.players-online": {
"message": "{count} متصل حاليا"
},
"friends.action.add-friend": {
"message": "إضافة صديق"
},
@@ -359,12 +263,6 @@
"instance.edit-world.title": {
"message": "تعديل العالم"
},
"instance.files.adding-files": {
"message": "إضافة ملفات ({completed}\\{total})"
},
"instance.files.save-as": {
"message": "حفظ ك..."
},
"instance.server-modal.address": {
"message": "العنوان"
},
@@ -402,7 +300,7 @@
"message": "نسخة النسخة"
},
"instance.settings.tabs.general.duplicate-instance.description": {
"message": "ينشئ نسخة من هذا النموذج شاملا عوالمه, تعديلاتها النصيه, إلخ..."
"message": "إنشاء."
},
"instance.settings.tabs.general.edit-icon": {
"message": "تعديل الأيقونة"
@@ -582,7 +480,7 @@
"message": "يقدمها الخادم"
},
"search.filter.locked.server-environment.title": {
"message": "يمكن إضافة التعديلات **المحليه** فقط إلى نموذج الخادم"
"message": "يمكن إضافة التعديلات من جانب العميل فقط إلى مثيل الخادم"
},
"search.filter.locked.server-game-version.title": {
"message": "يتم توفير نسخة اللعبة من قبل الخادم"
+2 -119
View File
@@ -5,129 +5,12 @@
"app.auth-servers.unreachable.header": {
"message": "Připojení k autorizačním serverům se nezdařilo"
},
"app.browse.add-to-instance": {
"message": "Přidat do instalace"
},
"app.browse.add-to-instance-name": {
"message": "Přidat do {instanceName}"
},
"app.browse.added": {
"message": "Přidáno"
},
"app.browse.already-added": {
"message": "Už přidáno"
},
"app.browse.discover-content": {
"message": "Prozkoumat obsah"
},
"app.browse.discover-servers": {
"message": "Prozkoumat servery"
},
"app.export-modal.description-placeholder": {
"message": "Přidej popis modpacku..."
},
"app.export-modal.export-button": {
"message": "Exportovat"
},
"app.export-modal.header": {
"message": "Exportovat modpack"
},
"app.export-modal.modpack-name-label": {
"message": "Jméno Modpacku"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Jméno modpacku"
},
"app.export-modal.version-number-label": {
"message": "Číslo verze"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Všechna data z instance budou navždy smazána, včetně světů, nastavení a všeho ostatního."
},
"app.instance.confirm-delete.admonition-header": {
"message": "Tato akce nemůže být vrácena"
},
"app.instance.confirm-delete.delete-button": {
"message": "Odstranit instanci"
},
"app.instance.confirm-delete.header": {
"message": "Odstanit instanci"
},
"app.instance.modpack-already-installed.body": {
"message": "Tento modpack je už nainstalovaný v instanci <bold>{instanceName}</bold>. Opravdu ho chceš duplikovat?"
},
"app.instance.modpack-already-installed.create": {
"message": "Vytvořit"
},
"app.instance.modpack-already-installed.header": {
"message": "Modpack už je nainstalovaný"
},
"app.instance.modpack-already-installed.instance": {
"message": "Instalace"
},
"app.instance.mods.content-type-project": {
"message": "projekt"
},
"app.instance.mods.project-was-added": {
"message": "\"{name}\" bylo přidáno"
},
"app.instance.mods.projects-were-added": {
"message": "{count} projektů bylo přidáno"
},
"app.instance.mods.share-text": {
"message": "Podívejte se na projekty co používám ve svém modpacku!"
},
"app.instance.mods.share-title": {
"message": "Sdílení obsahu modpacku"
},
"app.instance.mods.successfully-uploaded": {
"message": "Úspěšně nahráno"
},
"app.instance.worlds.add-server": {
"message": "Přidat server"
},
"app.instance.worlds.browse-servers": {
"message": "Procházet servery"
},
"app.instance.worlds.delete-world-description": {
"message": "\"{name}\" bude **navždy smazáno** a nebude způsob, jak to obnovit."
},
"app.instance.worlds.delete-world-title": {
"message": "Opravdu si jsi jistý, že chceš navždy smazat tenhle svět?"
},
"app.instance.worlds.filter-modded": {
"message": "Módováno"
},
"app.instance.worlds.filter-offline": {
"message": "Offline"
},
"app.instance.worlds.filter-online": {
"message": "Online"
},
"app.instance.worlds.filter-vanilla": {
"message": "Vanilla"
},
"app.instance.worlds.no-worlds-description": {
"message": "Přidej nebo procházej servery"
},
"app.instance.worlds.no-worlds-heading": {
"message": "Žádné servery nebo světy nebyly přidány"
},
"app.instance.worlds.remove-server-description": {
"message": "„{name}“ bude odstraněn z tvého seznamu, včetně hry, a nebude žádný způsob, jak ho obnovit."
},
"app.instance.worlds.remove-server-title": {
"message": "Opravdu chceš odstranit {name}?"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Hledat ve světech {count}..."
},
"app.instance.worlds.this-server": {
"message": "tento server"
},
"app.modal.install-to-play.header": {
"message": "Nainstaluj ke hraní"
},
@@ -198,7 +81,7 @@
"message": "Přidat přítele"
},
"friends.action.view-friend-requests": {
"message": "{count} přátelé {count, plural, one {request} other {requests}}"
"message": "{count} {count, plural, one {žádost} few {žádosti} other {žádostí}} o přátelství"
},
"friends.add-friend.submit": {
"message": "Poslat žádost o přátelství"
@@ -480,7 +363,7 @@
"message": "Můžeš rovnou skočit na server pouze v Minecraftu Alpha 1.0.5+"
},
"instance.worlds.no_singleplayer_quick_play": {
"message": "V Minecraftu 1.20+ se rovnou přeskočit pouze do singleplayerových světů"
"message": "Můžeš se rovnou připojit do světa jednoho hráče pouze v Minecraftu 1.20+"
},
"instance.worlds.play_instance": {
"message": "Hrát instanci"
+3 -105
View File
@@ -1,109 +1,10 @@
{
"app.action-bar.downloading-java": {
"message": "Downloader Java {version}"
},
"app.action-bar.downloads": {
"message": "Downloads"
},
"app.action-bar.hide-more-running-instances": {
"message": "Gem flere kørende instances"
},
"app.action-bar.make-primary-instance": {
"message": "Gør til primære instance"
},
"app.action-bar.no-instances-running": {
"message": "Ingen instances kørende"
},
"app.action-bar.offline": {
"message": "Offline"
},
"app.action-bar.primary-instance": {
"message": "Primære instance"
},
"app.action-bar.show-more-running-instances": {
"message": "Vis flere kørende instances"
},
"app.action-bar.stop-instance": {
"message": "Stop instance"
},
"app.action-bar.view-active-downloads": {
"message": "Vis aktive downloads"
},
"app.action-bar.view-instance": {
"message": "Vis instance"
},
"app.action-bar.view-logs": {
"message": "Vis logs"
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Avanceret rendering"
},
"app.appearance-settings.color-theme.description": {
"message": "Vælg dit foretrukne farvetema til Modrinth App."
},
"app.appearance-settings.color-theme.title": {
"message": "Farvetema"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Skift hvilken side launcheren åbner i."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Hjem"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Bibliotek"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Standard startside"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Slår nametagget over din spiller på skins siden fra."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Gem nametag"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Inkluderer de sidste verdener i afsnittet \"Hop tilbage\" på startsiden."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Hop tilbage ind i verdener"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Minimer launcheren når Minecraft starter."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Minimer launcher"
},
"app.appearance-settings.select-option": {
"message": "Vælg en mulighed"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Hvis du prøver at installere en Modrinth Pack fil (.mrpack) som ikke er hosted på Modrinth, så skal vi nok sikre os du forstår riskoen før du installere den."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "Advar mig før jeg installere en ukendt modpacks"
},
"app.auth-servers.unreachable.body": {
"message": "Minecraft authentication servere kan måske være nede lige nu. Tjek din internet forbindelse og prøv igen senere."
},
"app.auth-servers.unreachable.header": {
"message": "Kan ikke nå autentificeringsservere"
},
"app.browse.add-to-instance-name": {
"message": "Tilføjet til {instanceName}"
},
"app.browse.added": {
"message": "Tilføjet"
},
"app.browse.already-added": {
"message": "Allerede tilføjet"
},
"app.browse.discover-content": {
"message": "Opdag indhold"
},
"app.browse.discover-servers": {
"message": "Opdag servere"
},
"app.export-modal.description-placeholder": {
"message": "Indtast modpack beskrivelse..."
},
@@ -119,6 +20,9 @@
"app.export-modal.modpack-name-placeholder": {
"message": "Modpack navn"
},
"app.export-modal.select-files-label": {
"message": "Vælg filer og mapper til at inkludere i pakken"
},
"app.export-modal.version-number-label": {
"message": "Versionsnummer"
},
@@ -137,12 +41,6 @@
"app.instance.confirm-delete.header": {
"message": "Slet instance"
},
"app.instance.modpack-already-installed.body": {
"message": "Denne modpack er allerede installeret i <bold>{instanceName}</bold> instancen. Er du sikker på du vil duplikere den?"
},
"app.instance.modpack-already-installed.create": {
"message": "Opret"
},
"app.instance.mods.content-type-project": {
"message": "projekt"
},
+9 -171
View File
@@ -1,114 +1,15 @@
{
"app.action-bar.downloading-java": {
"message": "Java {version} wird heruntergeladen"
},
"app.action-bar.downloads": {
"message": "Downloads"
},
"app.action-bar.hide-more-running-instances": {
"message": "Weitere laufende Instanzen ausblenden"
},
"app.action-bar.make-primary-instance": {
"message": "Zur primären Instanz machen"
},
"app.action-bar.no-instances-running": {
"message": "Keine Instanzen laufen"
},
"app.action-bar.offline": {
"message": "Offline"
},
"app.action-bar.primary-instance": {
"message": "Primäre Instanz"
},
"app.action-bar.show-more-running-instances": {
"message": "Weitere laufende Instanzen anzeigen"
},
"app.action-bar.stop-instance": {
"message": "Instanz stoppen"
},
"app.action-bar.view-active-downloads": {
"message": "Aktive Downloads anzeigen"
},
"app.action-bar.view-instance": {
"message": "Instanz anzeigen"
},
"app.action-bar.view-logs": {
"message": "Protokolle anzeigen"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "Aktiviert erweiterte Rendering-Funktionen wie Unschärfeeffekte, welche ohne hardwarebeschleunigtes Rendering zu Leistungsproblemen führen können."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Erweitertes Rendering"
},
"app.appearance-settings.color-theme.description": {
"message": "Wähle dein bevorzugtes Farbschema für die Modrinth App."
},
"app.appearance-settings.color-theme.title": {
"message": "Farbschema"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Ändere die Seite, die beim Öffnen des Launchers angezeigt wird."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Start"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Bibliothek"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Standard-Startseite"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Deaktiviert das Namensschild über deinem Spieler auf der Skin-Seite."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Namensschild ausblenden"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Enthält zuletzt gespielte Welten im Abschnitt „Direkt weiterspielen“ auf der Startseite."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Springe zurück in Welten"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Den Launcher minimieren, wenn ein Minecraft-Prozess gestartet wird."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Launcher minimieren"
},
"app.appearance-settings.native-decorations.description": {
"message": "Systemfensterrahmen verwenden (Neustart der App erforderlich)."
},
"app.appearance-settings.native-decorations.title": {
"message": "Native Dekorationen"
},
"app.appearance-settings.select-option": {
"message": "Option wählen"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Ermöglicht das Umschalten der Seitenleiste."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "Seitenleiste umschalten"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Falls du versuchst, eine Modrinth-Pack-Datei (.mrpack) zu installieren, die nicht auf Modrinth gehostet wird, werden wir sicherstellen, dass du die Risiken vor der Installation verstehst."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "Warne mich, bevor unbekannte Modpacks installiert werden"
},
"app.auth-servers.unreachable.body": {
"message": "Die Authentifizierungsserver von Minecraft sind eventuell momentan nicht erreichbar. Überprüfe deine Internetverbindung und versuche es später erneut."
},
"app.auth-servers.unreachable.header": {
"message": "Authentifizierungsserver sind nicht erreichbar"
},
"app.browse.add-servers-to-instance": {
"app.browse.add-server-to-instance": {
"message": "Server zu Instanz hinzufügen"
},
"app.browse.add-to-an-instance": {
"message": "Zu Instanz hinzufügen"
"app.browse.add-servers-to-instance": {
"message": "Server zu deiner Instanz hinzufügen"
},
"app.browse.add-to-instance": {
"message": "Zu Instanz hinzufügen"
@@ -122,9 +23,6 @@
"app.browse.already-added": {
"message": "Bereits hinzugefügt"
},
"app.browse.back-to-instance": {
"message": "Zu Instanz zurückgehen"
},
"app.browse.discover-content": {
"message": "Inhalte entdecken"
},
@@ -132,22 +30,13 @@
"message": "Server entdecken"
},
"app.browse.hide-added-servers": {
"message": "Bereits hinzugefügte Server ausblenden"
"message": "Hinzugefügte Server ausblenden"
},
"app.browse.project-type.modpacks": {
"message": "Modpacks"
"app.browse.hide-installed-content": {
"message": "Installierte Inhalte ausblenden"
},
"app.browse.server-instance-content-warning": {
"message": "Das hinzufügen von Inhalten kann Kompatibilitätsprobleme beim beitreten eines Servers verursachen. Sämtliche hinzugefügte Inhalten gehen ausserdem beim aktualisieren der Server Instanz-Inhalte verloren."
},
"app.browse.server.installing": {
"message": "Wird installiert"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Modpack wird installiert..."
"app.browse.install-content-to-instance": {
"message": "Inhalt in Instanz installieren"
},
"app.export-modal.description-placeholder": {
"message": "Modpaketbeschreibung eingeben..."
@@ -158,9 +47,6 @@
"app.export-modal.header": {
"message": "Modpack exportieren"
},
"app.export-modal.include-file-accessibility-label": {
"message": "\"{file}\" einschliessen?"
},
"app.export-modal.modpack-name-label": {
"message": "Modpaketname"
},
@@ -168,7 +54,7 @@
"message": "Modpaketname"
},
"app.export-modal.select-files-label": {
"message": "Konfiguriere, welche Dateien in diesem Export miteinbezogen werden"
"message": "Wähle Dateien und Ordner zum hinzufügen im Paket aus"
},
"app.export-modal.version-number-label": {
"message": "Versionsnummer"
@@ -299,15 +185,6 @@
"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."
},
"app.project.install-button.already-installed": {
"message": "Dieses Projekt ist bereits installiert"
},
"app.project.install-context.back-to-browse": {
"message": "Zurück zum Durchstöbern"
},
"app.project.install-context.install-content-to-instance": {
"message": "Inhalt in Instanz installieren"
},
"app.settings.developer-mode-enabled": {
"message": "Entwicklermodus aktiviert."
},
@@ -698,24 +575,6 @@
"instance.worlds.world_in_use": {
"message": "Welt bereits in Benutzung"
},
"minecraft-account.add-account": {
"message": "Konto hinzufügen"
},
"minecraft-account.label": {
"message": "Minecraft-Konto"
},
"minecraft-account.not-signed-in": {
"message": "Nicht angemeldet"
},
"minecraft-account.remove-account": {
"message": "Konto entfernen"
},
"minecraft-account.select-account": {
"message": "Konto auswählen"
},
"minecraft-account.sign-in": {
"message": "In Minecraft anmelden"
},
"search.filter.locked.instance": {
"message": "Von der Instanz vorgegeben"
},
@@ -739,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "Loader wird vom Server bereitgestellt"
},
"unknown-pack-warning-modal.body": {
"message": "Eine Datei wird nur geprüft, wenn sie auf Modrinth hochgeladen wird, unabhängig von ihrem Dateiformat (auch .mrpack)."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "Diese Warnung nicht mehr anzeigen"
},
"unknown-pack-warning-modal.header": {
"message": "Installation bestätigen"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "Trotzdem installieren"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "Schadsoftware wird häufig über Modpack-Dateien verbreitet, indem diese auf Plattformen wie Discord geteilt werden."
},
"unknown-pack-warning-modal.warning.body": {
"message": "Wir konnten diese Datei auf Modrinth nicht finden. Wir empfehlen dringend, nur Dateien aus vertrauenswürdigen Quellen zu installieren."
},
"unknown-pack-warning-modal.warning.title": {
"message": "Warnung vor unbekannter Datei"
}
}
+11 -167
View File
@@ -1,117 +1,18 @@
{
"app.action-bar.downloading-java": {
"message": "Java {version} wird heruntergeladen"
},
"app.action-bar.downloads": {
"message": "Downloads"
},
"app.action-bar.hide-more-running-instances": {
"message": "Weitere laufende Instanzen ausblenden"
},
"app.action-bar.make-primary-instance": {
"message": "Zur primären Instanz machen"
},
"app.action-bar.no-instances-running": {
"message": "Keine aktiven Instanzen"
},
"app.action-bar.offline": {
"message": "Offline"
},
"app.action-bar.primary-instance": {
"message": "Primäre Instanz"
},
"app.action-bar.show-more-running-instances": {
"message": "Weitere laufende Instanzen anzeigen"
},
"app.action-bar.stop-instance": {
"message": "Instanz stoppen"
},
"app.action-bar.view-active-downloads": {
"message": "Aktive Downloads anzeigen"
},
"app.action-bar.view-instance": {
"message": "Instanz anzeigen"
},
"app.action-bar.view-logs": {
"message": "Protokolle anzeigen"
},
"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."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Erweitertes Rendering"
},
"app.appearance-settings.color-theme.description": {
"message": "Wähle dein bevorzugtes Farbschema für die Modrinth App."
},
"app.appearance-settings.color-theme.title": {
"message": "Farbschema"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Ändere die Seite, die beim Öffnen des Launchers angezeigt wird."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Start"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Bibliothek"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Standard-Startseite"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Deaktiviert das Namensschild über deinem Spieler auf der Skin-Seite."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Namensschild ausblenden"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Enthält zuletzt gespielte Welten im Abschnitt „Direkt weiterspielen“ auf der Startseite."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Direkt in Welten weiterspielen"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Den Launcher minimieren, wenn ein Minecraft-Prozess gestartet wird."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Launcher minimieren"
},
"app.appearance-settings.native-decorations.description": {
"message": "Fensterdekorationen des Systems verwenden (Neustart der App erforderlich)."
},
"app.appearance-settings.native-decorations.title": {
"message": "Native Dekorationen"
},
"app.appearance-settings.select-option": {
"message": "Wähle eine Option"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Ermöglicht das Umschalten der Seitenleiste."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "Seitenleiste umschalten"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Falls du versuchst, eine Modrinth-Pack-Datei (.mrpack) zu installieren, die nicht auf Modrinth gehostet wird, werden die Risiken vor der Installation bekannt gegeben."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "Warne mich, bevor unbekannte Modpacks installiert werden"
},
"app.auth-servers.unreachable.body": {
"message": "Die Authentifizierungsserver von Minecraft sind eventuell momentan nicht erreichbar. Überprüfe deine Internetverbindung und versuche es später erneut."
},
"app.auth-servers.unreachable.header": {
"message": "Authentifizierungsserver sind nicht erreichbar"
},
"app.browse.add-servers-to-instance": {
"app.browse.add-server-to-instance": {
"message": "Server zu Instanz hinzufügen"
},
"app.browse.add-to-an-instance": {
"message": "Zu Instanz hinzufügen"
"app.browse.add-servers-to-instance": {
"message": "Server zu deiner Instanz hinzufügen"
},
"app.browse.add-to-instance": {
"message": "Zur Instanz hinzufügen"
"message": "Zu Instanz hinzufügen"
},
"app.browse.add-to-instance-name": {
"message": "Zu {instanceName} hinzufügen"
@@ -122,9 +23,6 @@
"app.browse.already-added": {
"message": "Bereits hinzugefügt"
},
"app.browse.back-to-instance": {
"message": "Zurück zur Instanz"
},
"app.browse.discover-content": {
"message": "Inhalte entdecken"
},
@@ -132,19 +30,13 @@
"message": "Server entdecken"
},
"app.browse.hide-added-servers": {
"message": "Bereits hinzugefügte Server ausblenden"
"message": "Hinzugefügte Server ausblenden"
},
"app.browse.project-type.modpacks": {
"message": "Modpacks"
"app.browse.hide-installed-content": {
"message": "Installierte Inhalte ausblenden"
},
"app.browse.server.installing": {
"message": "Wird installiert"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Modpack wird installiert..."
"app.browse.install-content-to-instance": {
"message": "Inhalt in Instanz installieren"
},
"app.export-modal.description-placeholder": {
"message": "Beschreibung des Modpacks eingeben..."
@@ -155,9 +47,6 @@
"app.export-modal.header": {
"message": "Modpack exportieren"
},
"app.export-modal.include-file-accessibility-label": {
"message": "\"{file}\" einschließen?"
},
"app.export-modal.modpack-name-label": {
"message": "Modpackname"
},
@@ -165,7 +54,7 @@
"message": "Modpackname"
},
"app.export-modal.select-files-label": {
"message": "Konfiguriere, welche Dateien in diesen Export enthalten sind"
"message": "Wähle Dateien und Ordner aus, die in das Paket sollen"
},
"app.export-modal.version-number-label": {
"message": "Versionsnummer"
@@ -174,7 +63,7 @@
"message": "1.0.0"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Alle Daten deiner Instanz werden permanent gelöscht, einschließlich deiner Welten, Konfigurationen und allen installierten Inhalten."
"message": "Alle Daten für deine Instanz werden permanent gelöscht, einschließlich deiner Welten, Konfigurationen und allen installierten Inhalten."
},
"app.instance.confirm-delete.admonition-header": {
"message": "Diese Aktion kann nicht rückgängig gemacht werden"
@@ -296,12 +185,6 @@
"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."
},
"app.project.install-button.already-installed": {
"message": "Dieses Projekt ist bereits installiert"
},
"app.project.install-context.install-content-to-instance": {
"message": "Inhalt in Instanz installieren"
},
"app.settings.developer-mode-enabled": {
"message": "Entwicklermodus aktiviert."
},
@@ -692,24 +575,6 @@
"instance.worlds.world_in_use": {
"message": "Welt wird aktuell benutzt"
},
"minecraft-account.add-account": {
"message": "Konto hinzufügen"
},
"minecraft-account.label": {
"message": "Minecraft-Konto"
},
"minecraft-account.not-signed-in": {
"message": "Nicht angemeldet"
},
"minecraft-account.remove-account": {
"message": "Konto entfernen"
},
"minecraft-account.select-account": {
"message": "Konto auswählen"
},
"minecraft-account.sign-in": {
"message": "Bei Minecraft anmelden"
},
"search.filter.locked.instance": {
"message": "Von der Instanz vorgegeben"
},
@@ -733,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "Loader vom Server vorgegeben"
},
"unknown-pack-warning-modal.body": {
"message": "Eine Datei wird nur geprüft, wenn sie auf Modrinth hochgeladen wird, unabhängig von ihrem Dateiformat (auch .mrpack)."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "Diese Warnung nicht mehr anzeigen"
},
"unknown-pack-warning-modal.header": {
"message": "Installation bestätigen"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "Trotzdem installieren"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "Schadsoftware wird häufig über Modpack-Dateien verbreitet, indem diese auf Plattformen wie Discord geteilt werden."
},
"unknown-pack-warning-modal.warning.body": {
"message": "Wir konnten diese Datei auf Modrinth nicht finden. Wir empfehlen dringend, nur Dateien aus vertrauenswürdigen Quellen zu installieren."
},
"unknown-pack-warning-modal.warning.title": {
"message": "Warnung vor unbekannter Datei"
}
}
+10 -172
View File
@@ -1,114 +1,15 @@
{
"app.action-bar.downloading-java": {
"message": "Downloading Java {version}"
},
"app.action-bar.downloads": {
"message": "Downloads"
},
"app.action-bar.hide-more-running-instances": {
"message": "Hide more running instances"
},
"app.action-bar.make-primary-instance": {
"message": "Make primary instance"
},
"app.action-bar.no-instances-running": {
"message": "No instances running"
},
"app.action-bar.offline": {
"message": "Offline"
},
"app.action-bar.primary-instance": {
"message": "Primary instance"
},
"app.action-bar.show-more-running-instances": {
"message": "Show more running instances"
},
"app.action-bar.stop-instance": {
"message": "Stop instance"
},
"app.action-bar.view-active-downloads": {
"message": "View active downloads"
},
"app.action-bar.view-instance": {
"message": "View instance"
},
"app.action-bar.view-logs": {
"message": "View logs"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "Enables advanced rendering such as blur effects that may cause performance issues without hardware-accelerated rendering."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Advanced rendering"
},
"app.appearance-settings.color-theme.description": {
"message": "Select your preferred color theme for Modrinth App."
},
"app.appearance-settings.color-theme.title": {
"message": "Color theme"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Change the page to which the launcher opens on."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Home"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Library"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Default landing page"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Disables the nametag above your player on the skins page."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Hide nametag"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Includes recent worlds in the \"Jump back in\" section on the Home page."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Jump back into worlds"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Minimize the launcher when a Minecraft process starts."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Minimize launcher"
},
"app.appearance-settings.native-decorations.description": {
"message": "Use system window frame (app restart required)."
},
"app.appearance-settings.native-decorations.title": {
"message": "Native decorations"
},
"app.appearance-settings.select-option": {
"message": "Select an option"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Enables the ability to toggle the sidebar."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "Toggle sidebar"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "If you attempt to install a Modrinth Pack file (.mrpack) that isn't hosted on Modrinth, we'll make sure you understand the risks before installing it."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "Warn me before installing unknown modpacks"
},
"app.auth-servers.unreachable.body": {
"message": "Minecraft authentication servers may be down right now. Check your internet connection and try again later."
},
"app.auth-servers.unreachable.header": {
"message": "Cannot reach authentication servers"
},
"app.browse.add-servers-to-instance": {
"message": "Adding server to instance"
"app.browse.add-server-to-instance": {
"message": "Add server to instance"
},
"app.browse.add-to-an-instance": {
"message": "Add to an instance"
"app.browse.add-servers-to-instance": {
"message": "Add servers to your instance"
},
"app.browse.add-to-instance": {
"message": "Add to instance"
@@ -122,9 +23,6 @@
"app.browse.already-added": {
"message": "Already added"
},
"app.browse.back-to-instance": {
"message": "Back to instance"
},
"app.browse.discover-content": {
"message": "Discover content"
},
@@ -132,22 +30,13 @@
"message": "Discover servers"
},
"app.browse.hide-added-servers": {
"message": "Hide already added servers"
"message": "Hide added servers"
},
"app.browse.project-type.modpacks": {
"message": "Modpacks"
"app.browse.hide-installed-content": {
"message": "Hide installed content"
},
"app.browse.server-instance-content-warning": {
"message": "Adding content can break compatibility when joining the server. Any added content will also be lost when you update the server instance content."
},
"app.browse.server.installing": {
"message": "Installing"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Installing modpack..."
"app.browse.install-content-to-instance": {
"message": "Install content to instance"
},
"app.export-modal.description-placeholder": {
"message": "Enter modpack description..."
@@ -158,9 +47,6 @@
"app.export-modal.header": {
"message": "Export modpack"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Include \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Modpack Name"
},
@@ -168,7 +54,7 @@
"message": "Modpack name"
},
"app.export-modal.select-files-label": {
"message": "Configure which files are included in this export"
"message": "Select files and folders to include in pack"
},
"app.export-modal.version-number-label": {
"message": "Version number"
@@ -299,15 +185,6 @@
"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."
},
"app.project.install-button.already-installed": {
"message": "This project is already installed"
},
"app.project.install-context.back-to-browse": {
"message": "Back to discover"
},
"app.project.install-context.install-content-to-instance": {
"message": "Install content to instance"
},
"app.settings.developer-mode-enabled": {
"message": "Developer mode enabled."
},
@@ -698,24 +575,6 @@
"instance.worlds.world_in_use": {
"message": "World is in use"
},
"minecraft-account.add-account": {
"message": "Add account"
},
"minecraft-account.label": {
"message": "Minecraft account"
},
"minecraft-account.not-signed-in": {
"message": "Not signed in"
},
"minecraft-account.remove-account": {
"message": "Remove account"
},
"minecraft-account.select-account": {
"message": "Select account"
},
"minecraft-account.sign-in": {
"message": "Sign in to Minecraft"
},
"search.filter.locked.instance": {
"message": "Provided by the instance"
},
@@ -739,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "Loader is provided by the server"
},
"unknown-pack-warning-modal.body": {
"message": "A file is only reviewed if its uploaded to Modrinth, regardless of its file format (including .mrpack)."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "Don't show this warning again"
},
"unknown-pack-warning-modal.header": {
"message": "Confirm installation"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "Install anyway"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "Malware is often distributed through modpack files by sharing them on platforms like Discord."
},
"unknown-pack-warning-modal.warning.body": {
"message": "We couldn't find this file on Modrinth. We strongly recommend only installing files from sources you trust."
},
"unknown-pack-warning-modal.warning.title": {
"message": "Unknown file warning"
}
}
+35 -176
View File
@@ -1,111 +1,18 @@
{
"app.action-bar.downloading-java": {
"message": "Descargando Java {version}"
},
"app.action-bar.downloads": {
"message": "Descargas"
},
"app.action-bar.hide-more-running-instances": {
"message": "Ocultar más instancias en ejecución"
},
"app.action-bar.make-primary-instance": {
"message": "Hacer instancia principal"
},
"app.action-bar.no-instances-running": {
"message": "No hay instancias en ejecución"
},
"app.action-bar.offline": {
"message": "Desconectado"
},
"app.action-bar.primary-instance": {
"message": "Instancia principal"
},
"app.action-bar.show-more-running-instances": {
"message": "Mostrar más instancias en ejecución"
},
"app.action-bar.stop-instance": {
"message": "Detener instancia"
},
"app.action-bar.view-active-downloads": {
"message": "Ver descargas en curso"
},
"app.action-bar.view-instance": {
"message": "Ver instancia"
},
"app.action-bar.view-logs": {
"message": "Ver registros"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "Activa el renderizado avanzado, como los efectos de desenfoque, que pueden afectar el rendimiento sin aceleración por hardware."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Renderizado avanzado"
},
"app.appearance-settings.color-theme.description": {
"message": "Selecciona el tema de color que prefieras para la Modrinth App."
},
"app.appearance-settings.color-theme.title": {
"message": "Color de la interfaz"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Cambia la página en la que se abre el launcher."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Inicio"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Librería"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Página de inicio predeterminada"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Desactiva la etiqueta de nombre arriba de tu personaje en la página de skins."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Ocultar etiqueta de nombre"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Incluye los mundos recientes en la sección \"Volver a jugar\" de la página de inicio."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Volver a jugar mundos"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Minimiza el launcher al iniciar un proceso de Minecraft."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Minimizar launcher"
},
"app.appearance-settings.native-decorations.description": {
"message": "Usar el borde de ventana del sistema (requiere reiniciar la aplicación)."
},
"app.appearance-settings.native-decorations.title": {
"message": "Decoraciones nativas"
},
"app.appearance-settings.select-option": {
"message": "Selecciona una opción"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Permite mostrar u ocultar la barra lateral."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "Mostrar u ocultar la barra lateral"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Si intentas instalar un paquete de Modrinth (.mrpack) que no está alojado en Modrinth, te explicaremos los riesgos antes de instalarlo."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "Advertir antes de instalar modpacks desconocidos"
},
"app.auth-servers.unreachable.body": {
"message": "Los servidores de autenticación de Minecraft pueden no estar funcionando en este momento. Verifica tu conexión a internet e inténtalo de nuevo más tarde."
},
"app.auth-servers.unreachable.header": {
"message": "No se puede acceder a los servidores de autenticación"
},
"app.browse.add-server-to-instance": {
"message": "Añadir servidor a la instancia"
},
"app.browse.add-servers-to-instance": {
"message": "Añadir servidor a tu instancia"
},
"app.browse.add-to-instance": {
"message": "Añadir a instancia"
"message": "Añadir a la instancia"
},
"app.browse.add-to-instance-name": {
"message": "Añadir a {instanceName}"
@@ -114,7 +21,7 @@
"message": "Añadido"
},
"app.browse.already-added": {
"message": "Ya se ha añadido"
"message": "Ya está añadido"
},
"app.browse.discover-content": {
"message": "Descubrir contenido"
@@ -123,22 +30,16 @@
"message": "Descubrir servidores"
},
"app.browse.hide-added-servers": {
"message": "Ocultar servidores ya añadidos"
"message": "Ocultar servidores añadidos"
},
"app.browse.project-type.modpacks": {
"message": "Modpacks"
"app.browse.hide-installed-content": {
"message": "Ocultar contenido instalado"
},
"app.browse.server.installing": {
"message": "Instalando"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Instalando modpack..."
"app.browse.install-content-to-instance": {
"message": "Instalar contenido a una instancia"
},
"app.export-modal.description-placeholder": {
"message": "Introduce la descripción del modpack..."
"message": "Colocá la descripción del modpack..."
},
"app.export-modal.export-button": {
"message": "Exportar"
@@ -146,9 +47,6 @@
"app.export-modal.header": {
"message": "Exportar modpack"
},
"app.export-modal.include-file-accessibility-label": {
"message": "¿Incluir \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Nombre del modpack"
},
@@ -156,10 +54,10 @@
"message": "Nombre del modpack"
},
"app.export-modal.select-files-label": {
"message": "Configura que archivos incluir en esta exportación"
"message": "Selelecciona archivos y carpetas para incluir en el pack"
},
"app.export-modal.version-number-label": {
"message": "Número de la versión"
"message": "Nombre de la versión"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
@@ -177,13 +75,13 @@
"message": "Eliminar instancia"
},
"app.instance.modpack-already-installed.body": {
"message": "El modpack ya está instalado en la instancia <bold>{instanceName}</bold>. ¿Estás seguro de querer duplicarlo?"
"message": "Este modpack ya está instalado en la instancia <bold>{instanceName}</bold>. ¿Estás seguro qué quieres duplicarlo?"
},
"app.instance.modpack-already-installed.create": {
"message": "Crear"
},
"app.instance.modpack-already-installed.header": {
"message": "Este modpack ya está instalado"
"message": "Este modpack ya esta instalado"
},
"app.instance.modpack-already-installed.instance": {
"message": "Instancia"
@@ -192,19 +90,19 @@
"message": "proyecto"
},
"app.instance.mods.project-was-added": {
"message": "Se añadió \"{name}\""
"message": "\"{name}\" fue añadido"
},
"app.instance.mods.projects-were-added": {
"message": "Se añadieron {count} proyectos"
"message": "Se agregaron {count} proyectos"
},
"app.instance.mods.share-text": {
"message": Mira los proyectos que estoy usando en mi modpack!"
"message": Echa un vistazo a los proyectos que estoy usando en mi paquete de mods!"
},
"app.instance.mods.share-title": {
"message": "Compartiendo contenido del modpack"
},
"app.instance.mods.successfully-uploaded": {
"message": "Cargado correctamente"
"message": "Subido correctamente"
},
"app.instance.worlds.add-server": {
"message": "Añadir servidor"
@@ -213,13 +111,13 @@
"message": "Explorar servidores"
},
"app.instance.worlds.delete-world-description": {
"message": "\"{name}\" se **eliminará permanentemente** y no habrá forma de recuperarlo."
"message": "'{name}' será **permanentemente eliminado**, y habrá forma de recuperarlo."
},
"app.instance.worlds.delete-world-title": {
"message": "¿Estás seguro de que quieres eliminar este mundo de forma permanente?"
"message": "¿Estás seguro de qué quieres eliminar permanentemente este mundo?"
},
"app.instance.worlds.filter-modded": {
"message": "Con mods"
"message": "Modeado"
},
"app.instance.worlds.filter-offline": {
"message": "Sin conexión"
@@ -234,19 +132,19 @@
"message": "Añadir un servidor o explora para comenzar"
},
"app.instance.worlds.no-worlds-heading": {
"message": "No hay servidores ni mundos añadidos"
"message": "No hay servidores o mundos añadidos"
},
"app.instance.worlds.remove-server-description": {
"message": "\"{name}\" se elimina de tu lista, también dentro del juego, y no podrás recuperarlo."
"message": "'{name}' se eliminado de tu lista, incluyendo dentro del juego, y no habrá forma de recuperarlo."
},
"app.instance.worlds.remove-server-description-with-address": {
"message": "\"{name}\" ({address}) se elimina de tu lista, también dentro del juego, y no podrás recuperarlo."
"message": "'{name}' ({address}) se eliminado de tu lista, incluyendo dentro del juego, y no habrá forma de recuperarlo."
},
"app.instance.worlds.remove-server-title": {
"message": "¿Estás seguro de que quieres eliminar {name}?"
"message": "¿Estás seguro de qué quieres eliminar {name}?"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Buscar en {count} mundos..."
"message": "Buscar {count} mundos..."
},
"app.instance.worlds.this-server": {
"message": "este servidor"
@@ -255,7 +153,7 @@
"message": "Contenido requerido"
},
"app.modal.install-to-play.header": {
"message": "Instalar para jugar"
"message": "Instala para jugar"
},
"app.modal.install-to-play.install-button": {
"message": "Instalar"
@@ -267,7 +165,7 @@
"message": "Modpack requerido"
},
"app.modal.install-to-play.server-requires-mods": {
"message": "Este servidor requiere mods para poder jugar. Haz clic en Instalar para configurar los archivos requeridos desde Modrinth, después se ejecutará para entrar directamente al servidor."
"message": "Este servidor requiere mods para poder jugar. Haz click en Instalar para configurar los archivos requeridos desde Modrinth, después se ejecutará para entrar directamente al servidor."
},
"app.modal.install-to-play.shared-instance": {
"message": "Instancia compartida"
@@ -279,7 +177,7 @@
"message": "Ver contenidos"
},
"app.modal.update-to-play.header": {
"message": "Actualizar para jugar"
"message": "Actualiza para jugar"
},
"app.modal.update-to-play.update-required": {
"message": "Actualización requerida"
@@ -363,7 +261,7 @@
"message": "Versión {version} incompatible"
},
"app.world.world-item.not-played-yet": {
"message": "Aún no se ha jugado"
"message": "No se ha jugado aún"
},
"app.world.world-item.offline": {
"message": "Desconectado"
@@ -387,7 +285,7 @@
"message": "¡Podría ser distinto a su nombre de usuario de Minecraft!"
},
"friends.add-friend.username.placeholder": {
"message": "Introduce el nombre de usuario de Modrinth..."
"message": "Ingresa tu nombre de usuario de Modrinth..."
},
"friends.add-friend.username.title": {
"message": "¿Cuál es el nombre de usuario de Modrinth de tu amigo?"
@@ -677,24 +575,6 @@
"instance.worlds.world_in_use": {
"message": "El mundo ya está en uso"
},
"minecraft-account.add-account": {
"message": "Añadir cuenta"
},
"minecraft-account.label": {
"message": "Cuenta de Minecraft"
},
"minecraft-account.not-signed-in": {
"message": "No has inciado sesión"
},
"minecraft-account.remove-account": {
"message": "Eliminar cuenta"
},
"minecraft-account.select-account": {
"message": "Seleccionar cuenta"
},
"minecraft-account.sign-in": {
"message": "Inicia sesión en Minecraft"
},
"search.filter.locked.instance": {
"message": "Proporcionado por la instancia"
},
@@ -718,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "El loader es proporcionado por el servidor"
},
"unknown-pack-warning-modal.body": {
"message": "Un archivo solo es revisado si es subido a Modrinth, independientemente de su formato de archivo (incluyendo .mrpack)."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "No volver a mostrar esta advertencia"
},
"unknown-pack-warning-modal.header": {
"message": "Confirmar instalación"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "Instalar de todos modos"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "El malware a menudo es distribuido mediante modpacks compartidos en aplicaciones como Discord."
},
"unknown-pack-warning-modal.warning.body": {
"message": "No pudimos encontrar este archivo en Modrinth. Recomendamos solo instalar archivos de sitios de confianza."
},
"unknown-pack-warning-modal.warning.title": {
"message": "Advertencia de archivo desconocido"
}
}
+15 -132
View File
@@ -1,109 +1,16 @@
{
"app.action-bar.downloading-java": {
"message": "Descargando Java {version}"
},
"app.action-bar.downloads": {
"message": "Descargas"
},
"app.action-bar.hide-more-running-instances": {
"message": "Ocultar más instancias en ejecución"
},
"app.action-bar.make-primary-instance": {
"message": "Hacer instancia principal"
},
"app.action-bar.no-instances-running": {
"message": "Ninguna instancia en ejecución"
},
"app.action-bar.offline": {
"message": "Sin conexión"
},
"app.action-bar.primary-instance": {
"message": "Instancia principal"
},
"app.action-bar.show-more-running-instances": {
"message": "Mostrar mas instancias en ejecución"
},
"app.action-bar.stop-instance": {
"message": "Finalizar instancia"
},
"app.action-bar.view-active-downloads": {
"message": "Mostrar descargas activas"
},
"app.action-bar.view-instance": {
"message": "Mostrar instancia"
},
"app.action-bar.view-logs": {
"message": "Mostrar registros"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "Habilita el renderizado avanzado, como los efectos de desenfoque, que pueden causar problemas de rendimiento sin renderizado acelerado por hardware."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Renderizado avanzado"
},
"app.appearance-settings.color-theme.description": {
"message": "Seleccione su tema de color preferido para Modrinth en este dispositivo."
},
"app.appearance-settings.color-theme.title": {
"message": "Tema de color"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Cambia la página en la que el launcher se abre en."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Inicio"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Librería"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Página predeterminada"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Desactiva la etiqueta arriba de tu personaje en la página de skins."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Ocultar etiqueta"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Incluye los mundos más recientes en la sección \"Vuelve a jugar tus mundos\" en la página de inicio."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Vuelve a jugar tus mundos"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Minimiza el launcher cuando un proceso de Minecraft empieza."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Minimiza el launcher"
},
"app.appearance-settings.native-decorations.description": {
"message": "Usa los sistemas de frame de Windows (se requiere resetear la aplicación)."
},
"app.appearance-settings.native-decorations.title": {
"message": "Decoraciones nativas"
},
"app.appearance-settings.select-option": {
"message": "Selecciona una opción"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Activa la posibilidad de alternar la barra lateral."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "Alternar barra lateral"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Si intentas instalar un archivo de paquete de Modrinth (.mrpack) que no esté alojado en Modrinth, te advertiremos de los riesgos antes de instalarlo."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "Adviérteme antes de instalarme modpacks desconocidos"
},
"app.auth-servers.unreachable.body": {
"message": "Los servidores de autenticación de Minecraft pueden no estar funcionando en este momento. Verifica tu conexión a internet e inténtalo de nuevo más tarde."
},
"app.auth-servers.unreachable.header": {
"message": "No se puede conectar con los servidores de autenticación"
},
"app.browse.add-server-to-instance": {
"message": "Añadir servidor a la instancia"
},
"app.browse.add-servers-to-instance": {
"message": "Añadir servidor a tu instancia"
},
"app.browse.add-to-instance": {
"message": "Añadir a la instancia"
},
@@ -123,19 +30,13 @@
"message": "Descubrir servidores"
},
"app.browse.hide-added-servers": {
"message": "Ocultar servidores ya añadidos"
"message": "Ocultar servidores añadidos"
},
"app.browse.project-type.modpacks": {
"message": "Modpacks"
"app.browse.hide-installed-content": {
"message": "Ocultar contenido instalado"
},
"app.browse.server.installing": {
"message": "Instalando"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Instalando el modpack..."
"app.browse.install-content-to-instance": {
"message": "Instalar contenido a una instancia"
},
"app.export-modal.description-placeholder": {
"message": "Escribe la descripción del modpack..."
@@ -152,6 +53,9 @@
"app.export-modal.modpack-name-placeholder": {
"message": "Nombre del modpack"
},
"app.export-modal.select-files-label": {
"message": "Seleccione archivos y carpetas para incluir en el paquete"
},
"app.export-modal.version-number-label": {
"message": "Número de versión"
},
@@ -261,7 +165,7 @@
"message": "Modpack requerido"
},
"app.modal.install-to-play.server-requires-mods": {
"message": "Este servidor requiere ciertos mods. Pulsa Instalar para instalar los archivos requeridos de Modrinth y luego el launcher te enviara directo al servidor."
"message": "Este servidor requiere ciertos mods. Pulsa Instalar para instalar los archivos requeridos de Modrinth y luego el Launcher te enviara directo al servidor."
},
"app.modal.install-to-play.shared-instance": {
"message": "Instancia compartida"
@@ -694,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "El cargador lo proporciona el servidor"
},
"unknown-pack-warning-modal.body": {
"message": "Un archivo solo es revisado si es subido a Modrinth, independientemente de su formato de archivo (incluyendo .mrpack)."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "No mostrar esta advertencia otra vez"
},
"unknown-pack-warning-modal.header": {
"message": "Confirmar instalación"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "Instalar de todos modos"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "El malware es normalmente distribuido por archivos de modpack que son normalmente compartidas en aplicaciones como Discord."
},
"unknown-pack-warning-modal.warning.body": {
"message": "No pudimos encontrar este archivo en Modrinth. Recomendamos solo instalar archivos de sitios de confianza."
},
"unknown-pack-warning-modal.warning.title": {
"message": "Advertencia de archivo desconocido"
}
}
+6 -135
View File
@@ -5,38 +5,11 @@
"app.auth-servers.unreachable.header": {
"message": "Todennuspalvelimiin ei saada yhteyttä"
},
"app.browse.add-to-instance": {
"message": "Lisää instanssiin"
},
"app.browse.add-to-instance-name": {
"message": "Lisää instanssiin {instanceName}"
},
"app.browse.added": {
"message": "Lisätty"
},
"app.browse.already-added": {
"message": "On jo asennettu"
},
"app.browse.discover-content": {
"message": "Löydä sisältöä"
},
"app.browse.discover-servers": {
"message": "Löydä palvelimia"
},
"app.export-modal.description-placeholder": {
"message": "Lisää modipaketin kuvaus..."
},
"app.export-modal.export-button": {
"message": "Vie"
},
"app.export-modal.header": {
"message": "Vie modipaketti"
},
"app.export-modal.modpack-name-label": {
"message": "Modipaketin nimi"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Modipaketin nimi"
"message": "Modpack nimi"
},
"app.export-modal.select-files-label": {
"message": "Valitse tiedostot ja kansiot pakettiin"
},
"app.export-modal.version-number-label": {
"message": "Versio numero"
@@ -44,90 +17,12 @@
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Kaikki sinun instanssisi data poistetaan pysyvästi, sisältäen maailmasi, konfiguraatiosi ja asennetun sisällön."
},
"app.instance.confirm-delete.admonition-header": {
"message": "Tätä toimintoa ei voi peruuttaa"
},
"app.instance.confirm-delete.delete-button": {
"message": "Poista instannsi"
},
"app.instance.confirm-delete.header": {
"message": "Poista instanssi"
},
"app.instance.modpack-already-installed.body": {
"message": "Tämä modipaketti on jo asennettu instanssiin <bold>{instanceName}</bold>. Oletko varma että haluat kopioida sen?"
},
"app.instance.modpack-already-installed.create": {
"message": "Luo"
},
"app.instance.modpack-already-installed.header": {
"message": "Modipaketti on jo asennettu"
},
"app.instance.modpack-already-installed.instance": {
"message": "Instanssi"
},
"app.instance.mods.content-type-project": {
"message": "projekti"
},
"app.instance.mods.project-was-added": {
"message": "\"{name}\" lisättiin"
},
"app.instance.mods.projects-were-added": {
"message": "{count} projektia lisättiin"
},
"app.instance.mods.share-text": {
"message": "Tsekkaa projektit joita käytän minun modipaketissani!"
},
"app.instance.mods.successfully-uploaded": {
"message": "Onnistuneesti ladattu"
},
"app.instance.worlds.add-server": {
"message": "Lisää palvelin"
},
"app.instance.worlds.browse-servers": {
"message": "Selaa palvelimia"
},
"app.instance.worlds.delete-world-description": {
"message": "'{name}' tullaan **poistamaan pysyvästi**, eikä tule olemaan mitään tapaa palauttaa sitä."
},
"app.instance.worlds.delete-world-title": {
"message": "Oletko varma että haluat pysyvästi poistaa tämän maailman?"
},
"app.instance.worlds.filter-modded": {
"message": "Modattu"
},
"app.instance.worlds.filter-offline": {
"message": "Offline-tilassa"
},
"app.instance.worlds.filter-online": {
"message": "Online-tilassa"
},
"app.instance.worlds.filter-vanilla": {
"message": "Vanilla"
},
"app.instance.worlds.no-worlds-description": {
"message": "Lisää palvelin tai selaa aloittaaksesi"
},
"app.instance.worlds.no-worlds-heading": {
"message": "Ei palvelimia tai maailmoja lisättynä"
},
"app.instance.worlds.remove-server-description": {
"message": "'{name}' tullaan poistamaan sinun listaltasi, mukaan lukien pelin sisällä, eikä tule olemaan mitään tapaa palauttaa sitä."
},
"app.instance.worlds.remove-server-description-with-address": {
"message": "'{name}' ({address}) tullaan poistamaan sinun listaltasi, mukaan lukien pelin sisällä, eikä tule olemaan mitään tapaa palauttaa sitä."
},
"app.instance.worlds.remove-server-title": {
"message": "Oletko varma että haluat poistaa {name}?"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Hae {count} maailmasta..."
},
"app.instance.worlds.this-server": {
"message": "tämän palvelimen"
},
"app.modal.install-to-play.content-required": {
"message": "Sisältö vaaditaan"
},
@@ -138,7 +33,7 @@
"message": "Asenna"
},
"app.modal.install-to-play.mod-count": {
"message": "{count, plural, one {# mod} other {# modia}}"
"message": "one {{count, plural, one {# mod} other {# modia}}"
},
"app.modal.install-to-play.required-modpack": {
"message": "Vaadittu modipaketti"
@@ -230,24 +125,6 @@
"app.update.reload-to-update": {
"message": "Lataa uudelleen asentaaksesi päivityksen"
},
"app.world.server-modal.placeholder-address": {
"message": "example.modrinth.gg"
},
"app.world.server-modal.select-an-option": {
"message": "Valitse vaihtoehto"
},
"app.world.world-item.incompatible-version": {
"message": "Yhteensopimaton versio {version}"
},
"app.world.world-item.not-played-yet": {
"message": "Ei pelattu vielä"
},
"app.world.world-item.offline": {
"message": "Offline-tilassa"
},
"app.world.world-item.players-online": {
"message": "{count} paikalla"
},
"friends.action.add-friend": {
"message": "Lisää ystävä"
},
@@ -347,12 +224,6 @@
"instance.edit-world.title": {
"message": "Muokkaa maailmaa"
},
"instance.files.adding-files": {
"message": "Lisätään tiedostoja ({completed}/{total})"
},
"instance.files.save-as": {
"message": "Tallenna nimellä..."
},
"instance.server-modal.address": {
"message": "Osoite"
},
@@ -570,7 +441,7 @@
"message": "Palvelimen tarjoama"
},
"search.filter.locked.server-environment.title": {
"message": "Voit lisätä vain paikallisia modeja palvelin instanssiin"
"message": "Voit lisätä vain paikallisia modeja palvelinasennukseen"
},
"search.filter.locked.server-game-version.title": {
"message": "Peliversio on palvelimen tarjoama"
+5 -290
View File
@@ -1,256 +1,34 @@
{
"app.action-bar.downloading-java": {
"message": "Dina-download ang Java {version}"
},
"app.action-bar.downloads": {
"message": "Mga downloads"
},
"app.action-bar.hide-more-running-instances": {
"message": "Itago ang mas marami pang tumatakbong instansiya"
},
"app.action-bar.make-primary-instance": {
"message": "Gumawa ng pangunahing instansiya"
},
"app.action-bar.no-instances-running": {
"message": "Walang instansiya ang tumatakbo"
},
"app.action-bar.offline": {
"message": "Offline"
},
"app.action-bar.primary-instance": {
"message": "Pangunahing instansiya"
},
"app.action-bar.show-more-running-instances": {
"message": "Ipakita ang mas marami pang tumatakbong instansiya"
},
"app.action-bar.stop-instance": {
"message": "Itigil ang instansiya"
},
"app.action-bar.view-active-downloads": {
"message": "Tignan ang mga active downloads"
},
"app.action-bar.view-instance": {
"message": "Tignan ang instansiya"
},
"app.action-bar.view-logs": {
"message": "Tignan ang logs"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "Pagpapagana ng masalimuot na pagrerender katulad ng paglalabo na maaaring magdudulot ng mga isyu sa performance kapag walang hardware-acceleration."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Masalimuot na pagrerender"
},
"app.appearance-settings.color-theme.description": {
"message": "Piliin ang iyong mas gustong kulay para sa Modrinth app."
},
"app.appearance-settings.color-theme.title": {
"message": "Tema ng kulay"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Pagpapalit ng pahina na bubuksan ng launcher."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Tahanan"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Librarya"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Panimulang pahina ng paglapag"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Pagtatago ng nametag na nasa itaas ng iyong manlalaro sa loob ng pahina ng mga skin."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Itago ang nametag"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Pagsasali ng mga kamakailang mundo sa seksiyong \"Jump back in\" sa pahina ng Tahanan."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Bumalik sa mga mundo"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Liitan ang launcher kung nag-start ang isang proseso ng Minecraft."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Liitin ang launcher"
},
"app.appearance-settings.native-decorations.description": {
"message": "Gamitin ang system window frame (kailangan i-restart ang app)."
},
"app.appearance-settings.native-decorations.title": {
"message": "Native decorations"
},
"app.appearance-settings.select-option": {
"message": "Pumili ng opsiyon"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Pagpapagana na mata-toggle ang sidebar."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "I-toggle ang sidebar"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Kung susubukan mong mag-install ng Modrinth Pack file (.mrpack) na hindi naka-host sa Modrinth, titiyakin namin na nakaaalam ka sa mga panganib bago ito ma-install."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "Pakipaalala bago ko ma-install ang mga di-kilalang modpack"
},
"app.auth-servers.unreachable.body": {
"message": "Maaaring hindi maaabot ang mga authentication server ng Minecraft sa ngayon. Tingnan mo ang iyong internet connection at muling subukan mamaya."
},
"app.auth-servers.unreachable.header": {
"message": "Hindi maabot ang mga authentication server"
},
"app.browse.add-to-instance": {
"message": "Idagdag sa instansiya"
},
"app.browse.add-to-instance-name": {
"message": "Idagdag sa {instanceName}"
},
"app.browse.added": {
"message": "Dinagdag"
},
"app.browse.already-added": {
"message": "Nadagdag na"
},
"app.browse.discover-content": {
"message": "Tumuklas ng kontento"
},
"app.browse.discover-servers": {
"message": "Tumuklas ng mga server"
},
"app.browse.hide-added-servers": {
"message": "Itago ang mga nailagay na mga servers"
},
"app.browse.project-type.modpacks": {
"message": "Modpacks"
},
"app.browse.server.installing": {
"message": "Ini-install"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Ini-install ang modpack..."
},
"app.export-modal.description-placeholder": {
"message": "Ilagay ang paglalarawan ng modpack..."
},
"app.export-modal.export-button": {
"message": "Iluwas"
},
"app.export-modal.header": {
"message": "Iluwas ang modpack"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Salihin ang \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Pangalan ng Modpack"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Pangalan ng modpack"
},
"app.export-modal.select-files-label": {
"message": "Isaayos kung anong mga file ang isasali sa pagluwas"
},
"app.export-modal.version-number-label": {
"message": "Numero ng bersiyon"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Ang lahat ng data ng iyong instansiya ay tuluyang mawawala, kabilang na ang iyong mga mundo, kumpigurasyon, at lahat ng na-install na kontento."
},
"app.instance.confirm-delete.admonition-header": {
"message": "Hindi mababawi ang aksiyong ito"
},
"app.instance.confirm-delete.delete-button": {
"message": "Tanggalin ang instansiya"
},
"app.instance.confirm-delete.header": {
"message": "Tanggalin ang instansiya"
},
"app.instance.modpack-already-installed.body": {
"message": "Naka-install na ang modpack sa instansiyang <bold>{instanceName}</bold>. Sigurado ka ba sa pag-ulit nito?"
},
"app.instance.modpack-already-installed.create": {
"message": "Ilikha"
},
"app.instance.modpack-already-installed.header": {
"message": "Naka-install na ang modpack"
},
"app.instance.modpack-already-installed.instance": {
"message": "Instansiya"
},
"app.instance.mods.content-type-project": {
"message": "proyekto"
},
"app.instance.mods.project-was-added": {
"message": "Ang \"{name}\" ay nadagdag"
},
"app.instance.mods.projects-were-added": {
"message": "{count} proyekto ang nadagdag"
},
"app.instance.mods.share-text": {
"message": "Tingnan ang mga proyektong ginagamit ko sa aking modpack!"
},
"app.instance.mods.share-title": {
"message": "Binabahagi ang kontento ng modpack"
},
"app.instance.mods.successfully-uploaded": {
"message": "Matagumpay na na-upload"
},
"app.instance.worlds.add-server": {
"message": "Magdagdag ng server"
},
"app.instance.worlds.browse-servers": {
"message": "Mag-browse ng servers"
},
"app.instance.worlds.delete-world-description": {
"message": "'{name}' ay **permanenteng mabubura**, at walang paraan upang maibalik muli."
},
"app.instance.worlds.delete-world-title": {
"message": "Sigurado ka bang gusto mong permanenteng burahin ang world na ito?"
},
"app.instance.worlds.filter-modded": {
"message": "Modded"
},
"app.instance.worlds.filter-offline": {
"message": "Offline"
},
"app.instance.worlds.filter-online": {
"message": "Online"
},
"app.instance.worlds.filter-vanilla": {
"message": "Vanilla"
},
"app.instance.worlds.no-worlds-description": {
"message": "Maglagay ng server o mag-browse upang mag-simula"
},
"app.instance.worlds.no-worlds-heading": {
"message": "Walang servers o worlds ang nalalagay"
},
"app.instance.worlds.remove-server-description": {
"message": "'{name}' ay matatangal sa iyong listahan, pati sa loob ng laro, at walang paraan upang maibalik ito."
},
"app.instance.worlds.remove-server-description-with-address": {
"message": "'{name}' ({address}) ay matatangal sa iyong listahan, pati sa loob ng laro, at walang paraan upang maibalik ito."
},
"app.instance.worlds.remove-server-title": {
"message": "Sigurado ka bang gusto mong tanggalin ang {name}?"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Hanapin sa {count} mundo..."
},
"app.instance.worlds.this-server": {
"message": "server na ito"
},
"app.modal.install-to-play.content-required": {
"message": "Nangangailangan ng kontento"
},
@@ -288,7 +66,7 @@
"message": "Kailangang mag-update upang malaro ang {name}. Mangyaring mag-update sa pinakabagong bersiyon upang ma-launch ang laro."
},
"app.settings.developer-mode-enabled": {
"message": "Binuksan ang moda ng nagdi-develop."
"message": "Nakabukas ang moda ng nagdidibelop."
},
"app.settings.downloading": {
"message": "Dina-download ang v{version}"
@@ -353,24 +131,6 @@
"app.update.reload-to-update": {
"message": "Handang ma-install ang update"
},
"app.world.server-modal.placeholder-address": {
"message": "example.modrinth.gg"
},
"app.world.server-modal.select-an-option": {
"message": "Pumili ng opsiyon"
},
"app.world.world-item.incompatible-version": {
"message": "Di-magkatugmang bersiyong {version}"
},
"app.world.world-item.not-played-yet": {
"message": "Hindi pa nalalaro"
},
"app.world.world-item.offline": {
"message": "Offline"
},
"app.world.world-item.players-online": {
"message": "{count} online"
},
"friends.action.add-friend": {
"message": "Magdagdag ng kaibigan"
},
@@ -441,10 +201,10 @@
"message": "Idagdag ang server"
},
"instance.add-server.resource-pack.disabled": {
"message": "Tanggihan"
"message": "Hindi pinahihintulotan"
},
"instance.add-server.resource-pack.enabled": {
"message": "Payagan"
"message": "Pinahihintulotan"
},
"instance.add-server.resource-pack.prompt": {
"message": "Magpahintulot"
@@ -456,7 +216,7 @@
"message": "Baguhin ang server"
},
"instance.edit-world.hide-from-home": {
"message": "Itago sa pahina ng Tahanan"
"message": "Huwag ipakita sa Home na pahina"
},
"instance.edit-world.name": {
"message": "Pangalan"
@@ -470,12 +230,6 @@
"instance.edit-world.title": {
"message": "Baguhin ang mundo"
},
"instance.files.adding-files": {
"message": "Idinadagdag ang mga file ({completed}/{total})"
},
"instance.files.save-as": {
"message": "I-save bilang..."
},
"instance.server-modal.address": {
"message": "Adres"
},
@@ -645,7 +399,7 @@
"message": "Kopyahin ang adres"
},
"instance.worlds.dont_show_on_home": {
"message": "Huwag ipakita sa Tahanan"
"message": "Huwag ipakita sa Home"
},
"instance.worlds.game_already_open": {
"message": "Bukas naman ang instansiya"
@@ -677,24 +431,6 @@
"instance.worlds.world_in_use": {
"message": "Ginagamit ang mundo"
},
"minecraft-account.add-account": {
"message": "Maglagay ng account"
},
"minecraft-account.label": {
"message": "Minecraft account"
},
"minecraft-account.not-signed-in": {
"message": "Hindi pa naka sign in"
},
"minecraft-account.remove-account": {
"message": "Itanggal ang account"
},
"minecraft-account.select-account": {
"message": "Pumili ng account"
},
"minecraft-account.sign-in": {
"message": "Mag sign in kay Minecraft"
},
"search.filter.locked.instance": {
"message": "Sagot na ng instansiya"
},
@@ -718,26 +454,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "Ang loader ay handog na ng server"
},
"unknown-pack-warning-modal.body": {
"message": "Ang file ay nasusuri lamang kapag ito ay na-upload sa Modrinth, walang pili sa file format nito (kabilang na ang .mrpack)."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "Huwag ipakita ang babalang ito ulit"
},
"unknown-pack-warning-modal.header": {
"message": "Kumpirmahin ang installation"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "I-install parin"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "Ang malware ay madalas naidadala sa mga modpack files sa pamamagitan ng pag-bigay ng mga ito sa mga platforms kagaya ng Discord."
},
"unknown-pack-warning-modal.warning.body": {
"message": "Hindi namin mahanap ang file na ito sa Modrinth. Mahalagang mag-install ka lamang ng files galing sa mga mapagkakatiwalang sources."
},
"unknown-pack-warning-modal.warning.title": {
"message": "Hindi kilalang file"
}
}
+16 -178
View File
@@ -1,114 +1,15 @@
{
"app.action-bar.downloading-java": {
"message": "Java version {version} en cours de téléchargement"
},
"app.action-bar.downloads": {
"message": "Téléchargements"
},
"app.action-bar.hide-more-running-instances": {
"message": "Masquer plus d'instances en exécution"
},
"app.action-bar.make-primary-instance": {
"message": "Définir en tante qu'instance première"
},
"app.action-bar.no-instances-running": {
"message": "Aucune instance en exécution"
},
"app.action-bar.offline": {
"message": "Hors ligne"
},
"app.action-bar.primary-instance": {
"message": "Instance première"
},
"app.action-bar.show-more-running-instances": {
"message": "Montrer plus d'instances en exécution"
},
"app.action-bar.stop-instance": {
"message": "Arrêter l'instance"
},
"app.action-bar.view-active-downloads": {
"message": "Voir les téléchargements actifs"
},
"app.action-bar.view-instance": {
"message": "Voir l'instance"
},
"app.action-bar.view-logs": {
"message": "Voir les journaux"
},
"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."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Rendu avancé"
},
"app.appearance-settings.color-theme.description": {
"message": "Sélectionnez votre couleur préférée pour le thème de Modrinth App."
},
"app.appearance-settings.color-theme.title": {
"message": "Thème couleur"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Modifier la page sur laquelle le lancheur s'ouvre."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Acceuil"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Bibliothèque"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Page d'ouverture"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Désactive le nom au-dessus du joueur sur la page skins."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Cacher le pseudo"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Inclut les mondes récents dans la section « Partie rapide » sur la page d'accueil."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Mondes sur partie rapide"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Minimiser le launcher quand Minecraft démarre."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Minimiser le launcher"
},
"app.appearance-settings.native-decorations.description": {
"message": "Utiliser le cadre fenêtre du système (redémarrage de l'application requis)."
},
"app.appearance-settings.native-decorations.title": {
"message": "Décorations natives"
},
"app.appearance-settings.select-option": {
"message": "Sélectionnez une option"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Permet d'ouvrir de de fermer la barre latérale."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "Tiroir latéral"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Si vous essayez d'installer un fichier Modrinth Pack (.mrpack) qui n'est pas hébergé sur Modrinth, nous nous assurerons que vous comprenez les risques avant de l'installer."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "M'avertir avant d'installer des modpacks inconnus"
},
"app.auth-servers.unreachable.body": {
"message": "Les serveurs d'authentification de Minecraft sont peut-être actuellement hors ligne. Vérifiez votre connexion Internet et essayez à nouveau dans quelques instants."
},
"app.auth-servers.unreachable.header": {
"message": "Impossible de contacter les serveurs d'authentification"
},
"app.browse.add-servers-to-instance": {
"message": "Ajouter le serveur à l'instance"
"app.browse.add-server-to-instance": {
"message": "Ajouter le serveur a l'instance"
},
"app.browse.add-to-an-instance": {
"message": "Ajouter à une instance"
"app.browse.add-servers-to-instance": {
"message": "Ajouter des serveurs a votre instance"
},
"app.browse.add-to-instance": {
"message": "Ajouter à l'instance"
@@ -122,9 +23,6 @@
"app.browse.already-added": {
"message": "Déjà ajouté"
},
"app.browse.back-to-instance": {
"message": "Retour à l'instance"
},
"app.browse.discover-content": {
"message": "Découvrir du contenu"
},
@@ -132,22 +30,13 @@
"message": "Découvrir des serveurs"
},
"app.browse.hide-added-servers": {
"message": "Masquer les serveurs déjà ajoutés"
"message": "Masquer les serveurs ajoutés"
},
"app.browse.project-type.modpacks": {
"message": "Modpacks"
"app.browse.hide-installed-content": {
"message": "Masquer le contenu installé"
},
"app.browse.server-instance-content-warning": {
"message": "Ajouter du contenu peut briser la comptabilité en rejoignant le serveur. Tout contenu en plus sera également perdu lorsque vous mettrez à jour le contenu de l'instance du serveur."
},
"app.browse.server.installing": {
"message": "Installation en cours"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Installation du modpack..."
"app.browse.install-content-to-instance": {
"message": "Installer du contenu à l'instance"
},
"app.export-modal.description-placeholder": {
"message": "Saisir la description du modpack..."
@@ -158,9 +47,6 @@
"app.export-modal.header": {
"message": "Exporter le modpack"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Inclure « {file} » ?"
},
"app.export-modal.modpack-name-label": {
"message": "Nom du modpack"
},
@@ -168,7 +54,7 @@
"message": "Nom du modpack"
},
"app.export-modal.select-files-label": {
"message": "Configurez quels fichiers sont inclus dans cette exportation"
"message": "Sélectionnez des fichiers et des dossiers à inclure dans le pack"
},
"app.export-modal.version-number-label": {
"message": "Numéro de version"
@@ -177,7 +63,7 @@
"message": "1.0.0"
},
"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é."
"message": "Toutes les données pour votre instance seront supprimée à jamais, y comprit vos mondes, configurations, et contenu supprimé."
},
"app.instance.confirm-delete.admonition-header": {
"message": "Cette action est irréversible"
@@ -189,7 +75,7 @@
"message": "Supprimer l'instance"
},
"app.instance.modpack-already-installed.body": {
"message": "Ce modpack est déjà installé sur l'instance <bold>{instanceName}</bold>. Êtes-vous sûr·e de vouloir le dupliquer ?"
"message": "Ce modpack est déjà installé sur l'instance <bold>{instanceName}</bold>. Êtes-vous sûr.e de vouloir le dupliquer ?"
},
"app.instance.modpack-already-installed.create": {
"message": "Créer"
@@ -213,7 +99,7 @@
"message": "Jette un coup d'œil aux projets que j'utilise dans mon modpack !"
},
"app.instance.mods.share-title": {
"message": "Le contenu de mon modpack"
"message": "Partagez le contenu de votre modpack"
},
"app.instance.mods.successfully-uploaded": {
"message": "Mis en ligne avec succès"
@@ -228,7 +114,7 @@
"message": "« {name} » sera supprimé **pour toujours**, et il sera impossible de le récupérer."
},
"app.instance.worlds.delete-world-title": {
"message": "Êtes-vous sûr·e de vouloir supprimer ce monde pour toujours ?"
"message": "Étes-vous sûr.e de vouloir supprimer ce monde pour toujours ?"
},
"app.instance.worlds.filter-modded": {
"message": "Moddé"
@@ -255,7 +141,7 @@
"message": "« {name} » ({address}) sera retiré de votre liste, y compris en jeu, et il sera impossible de le récupérer."
},
"app.instance.worlds.remove-server-title": {
"message": "Êtes-vous sûr·e de vouloir retirer {name} ?"
"message": "Êtes-vous sûr.e de vouloir retirer {name} ?"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Rechercher {count} mondes..."
@@ -299,15 +185,6 @@
"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."
},
"app.project.install-button.already-installed": {
"message": "Ce projet a déjà été installé"
},
"app.project.install-context.back-to-browse": {
"message": "Retour à la navigation"
},
"app.project.install-context.install-content-to-instance": {
"message": "Installer du contenu à l'instance"
},
"app.settings.developer-mode-enabled": {
"message": "Mode développeur activé."
},
@@ -333,7 +210,7 @@
"message": "Gestion des ressources"
},
"app.update-popup.body": {
"message": "Modrinth App v{version} est prête à être installée ! Relancez l'application pour faire la mise à jour maintenant, ou automatiquement à la fermeture de Modrinth App."
"message": "Modrinth App v{version} est prête à être installée ! Rechargez pour mettre à jour maintenant, ou automatiquement quand vous fermez Modrinth App."
},
"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."
@@ -698,24 +575,6 @@
"instance.worlds.world_in_use": {
"message": "Le monde en cours d'utilisation"
},
"minecraft-account.add-account": {
"message": "Ajouter un compte"
},
"minecraft-account.label": {
"message": "Compte Minecraft"
},
"minecraft-account.not-signed-in": {
"message": "Pas connecté"
},
"minecraft-account.remove-account": {
"message": "Retirer le compte"
},
"minecraft-account.select-account": {
"message": "Sélectionner un compte"
},
"minecraft-account.sign-in": {
"message": "Se connecter à Minecraft"
},
"search.filter.locked.instance": {
"message": "Procuré par l'instance"
},
@@ -739,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "Le loader est procuré par le serveur"
},
"unknown-pack-warning-modal.body": {
"message": "Un fichier nest révisé que sil est téléchargé sur Modrinth, quel que soit son format de fichier (y compris .mrpack)."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "Ne plus m'avertir à ce sujet"
},
"unknown-pack-warning-modal.header": {
"message": "Confirmer l'installation"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "Installer tout de même"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "Les logiciels malveillants sont souvent distribués via des fichiers modpack en les partageant sur des plateformes comme Discord."
},
"unknown-pack-warning-modal.warning.body": {
"message": "Nous ne pouvions pas trouver ce fichier sur Modrinth. Nous vous recommandons fortement de n'installer que des fichiers de sources de confiance."
},
"unknown-pack-warning-modal.warning.title": {
"message": "Avertissement fichier inconnu"
}
}
+5 -83
View File
@@ -5,23 +5,8 @@
"app.auth-servers.unreachable.header": {
"message": "לא ניתן לגשת לשרתי האימות"
},
"app.browse.add-to-instance": {
"message": וספה להתקנה"
},
"app.browse.add-to-instance-name": {
"message": "הוסף אל {instanceName}"
},
"app.browse.added": {
"message": "נוסף"
},
"app.browse.already-added": {
"message": "כבר נוסף"
},
"app.browse.discover-content": {
"message": "גלה תוכן"
},
"app.browse.discover-servers": {
"message": "גלה שרתים"
"app.browse.hide-installed-content": {
"message": סתר תוכן מותקן"
},
"app.export-modal.description-placeholder": {
"message": "הזן את תיאור חבילת המודים..."
@@ -38,6 +23,9 @@
"app.export-modal.modpack-name-placeholder": {
"message": "שם חבילת המודים"
},
"app.export-modal.select-files-label": {
"message": "בחר קבצים ותיקיות להכללה בחבילה הזו"
},
"app.export-modal.version-number-label": {
"message": "מספר גרסה"
},
@@ -56,18 +44,9 @@
"app.instance.confirm-delete.header": {
"message": "מחיקת התקנה"
},
"app.instance.modpack-already-installed.body": {
"message": "חבילת המודים הזו כבר מותקנת בתוך ההתקנה <bold>{instanceName}</bold>. האם אתה בטוח שברצונך לשכפל אותה?"
},
"app.instance.modpack-already-installed.create": {
"message": "צור"
},
"app.instance.modpack-already-installed.header": {
"message": "חבילת המודים הזאת כבר מותקנת"
},
"app.instance.modpack-already-installed.instance": {
"message": "התקנה"
},
"app.instance.mods.content-type-project": {
"message": "פרויקט"
},
@@ -89,48 +68,12 @@
"app.instance.worlds.add-server": {
"message": "הוסף שרת"
},
"app.instance.worlds.browse-servers": {
"message": "עיון בשרתים"
},
"app.instance.worlds.delete-world-description": {
"message": "'{name}' יימחק לצמיתות, ולא תהיה דרך לשחזר אותו."
},
"app.instance.worlds.delete-world-title": {
"message": "האם אתה בטוח שברצונך למחוק לצמיתות את העולם הזה?"
},
"app.instance.worlds.filter-modded": {
"message": "עם מודים"
},
"app.instance.worlds.filter-offline": {
"message": "לא מקוון"
},
"app.instance.worlds.filter-online": {
"message": "מחובר"
},
"app.instance.worlds.filter-vanilla": {
"message": "ונילה"
},
"app.instance.worlds.no-worlds-description": {
"message": "הוספת שרת או עיון כדי להתחיל"
},
"app.instance.worlds.no-worlds-heading": {
"message": "אין שרתים אן עולמות שנוספו"
},
"app.instance.worlds.remove-server-description": {
"message": "'{name}' יוסר מהרשימה שלך, כולל מתוך המשחק, ולא תהיה דרך לשחזר אותו."
},
"app.instance.worlds.remove-server-description-with-address": {
"message": "'{name}' ({address}) יוסר מהרשימה שלך, כולל מתוך המשחק, ולא תהיה דרך לשחזר אותו."
},
"app.instance.worlds.remove-server-title": {
"message": "אתה בטוח שאתה רוצה להסיר {name}?"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "חיפוש ב-{count} עולמות..."
},
"app.instance.worlds.this-server": {
"message": "השרת הזה"
},
"app.modal.install-to-play.content-required": {
"message": "תוכן נדרש"
},
@@ -233,24 +176,6 @@
"app.update.reload-to-update": {
"message": "צריך לרענן כדי להתקין את העדכון"
},
"app.world.server-modal.placeholder-address": {
"message": "example.modrinth.gg"
},
"app.world.server-modal.select-an-option": {
"message": "בחר אופציה"
},
"app.world.world-item.incompatible-version": {
"message": "גרסה לא תואמת: {version}"
},
"app.world.world-item.not-played-yet": {
"message": "עדיין לא שוחק"
},
"app.world.world-item.offline": {
"message": "לא מקוון"
},
"app.world.world-item.players-online": {
"message": "{count} מחוברים"
},
"friends.action.add-friend": {
"message": "הוספת חבר"
},
@@ -350,9 +275,6 @@
"instance.edit-world.title": {
"message": "ערוך עולם"
},
"instance.files.adding-files": {
"message": "הוספת קבצים ({completed}/{total})"
},
"instance.files.save-as": {
"message": "שמור כ..."
},
+23 -80
View File
@@ -1,46 +1,16 @@
{
"app.action-bar.downloading-java": {
"message": "A Java {version} letöltése"
},
"app.action-bar.downloads": {
"message": "Letöltések"
},
"app.action-bar.hide-more-running-instances": {
"message": "További futó profilok elrejtése"
},
"app.action-bar.make-primary-instance": {
"message": "Beállítás elsődleges profilként"
},
"app.action-bar.no-instances-running": {
"message": "Nincsenek futó profilok"
},
"app.action-bar.offline": {
"message": "Offline"
},
"app.action-bar.primary-instance": {
"message": "Elsődleges profil"
},
"app.action-bar.stop-instance": {
"message": "Profil megállítása"
},
"app.action-bar.view-logs": {
"message": "Naplók megtekintése"
},
"app.appearance-settings.color-theme.title": {
"message": "Téma"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Ha olyan Modrinth Csomagfájlt (.mrpack) próbálsz telepíteni, amely nem a Modrinth szerverén található, a telepítés előtt gondoskodunk arról, hogy tisztában legyél a kockázatokkal."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "Figyelmeztess, mielőtt ismeretlen modcsomagokat telepítenék"
},
"app.auth-servers.unreachable.body": {
"message": "A Minecraft hitelesítő szerverek lehet, hogy nem üzemelnek. Bizonyosodj meg róla, hogy van internetkapcsolatod és próbáld meg újra."
},
"app.auth-servers.unreachable.header": {
"message": "Nem lehet elérni a hitelesítési kiszolgálókat"
},
"app.browse.add-server-to-instance": {
"message": "Szerver hozzáadása a profilhoz"
},
"app.browse.add-servers-to-instance": {
"message": "Szerverek hozzáadása a profilodhoz"
},
"app.browse.add-to-instance": {
"message": "Hozzáadás a profilhoz"
},
@@ -53,9 +23,6 @@
"app.browse.already-added": {
"message": "Már hozzá van adva"
},
"app.browse.back-to-instance": {
"message": "Vissza a profilhoz"
},
"app.browse.discover-content": {
"message": "Tartalom böngészése"
},
@@ -63,19 +30,13 @@
"message": "Szerverek böngészése"
},
"app.browse.hide-added-servers": {
"message": "Már hozzáadott szerverek elrejtése"
"message": "Hozzáadott szerverek elrejtése"
},
"app.browse.project-type.modpacks": {
"message": "Modcsomagok"
"app.browse.hide-installed-content": {
"message": "A telepített tartalmak elrejtése"
},
"app.browse.server.installing": {
"message": "Letöltés..."
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Modcsomag telepítése..."
"app.browse.install-content-to-instance": {
"message": "Tartalom letöltése a profilhoz"
},
"app.export-modal.description-placeholder": {
"message": "Írd be a modcsomag leírását..."
@@ -92,6 +53,9 @@
"app.export-modal.modpack-name-placeholder": {
"message": "A modcsomag neve"
},
"app.export-modal.select-files-label": {
"message": "Válaszd ki a csomagba felveendő fájlokat és mappákat"
},
"app.export-modal.version-number-label": {
"message": "Verziószám"
},
@@ -170,12 +134,6 @@
"app.instance.worlds.no-worlds-heading": {
"message": "Nincs szerver vagy világ"
},
"app.instance.worlds.remove-server-description": {
"message": "'{name}' eltávolításra kerül a listádról, beleértve a játékon belülieket is. Ezt a lépést nem tudod visszavonni."
},
"app.instance.worlds.remove-server-description-with-address": {
"message": "'{name}' ({address}) eltávolításra kerül a listádról, beleértve a játékon belülieket is. Ezt a lépést nem tudod visszavonni."
},
"app.instance.worlds.remove-server-title": {
"message": "Biztosan el akarod távolítani ezt: {name}?"
},
@@ -221,12 +179,6 @@
"app.modal.update-to-play.update-required-description": {
"message": "\nFrissítés szükséges ehhez: {name}. Kérjük, frissíts a legújabb verzióra a játék elindításához"
},
"app.project.install-context.back-to-browse": {
"message": "Vissza a böngészéshez"
},
"app.project.install-context.install-content-to-instance": {
"message": "Tartalom telepítése a profilba"
},
"app.settings.developer-mode-enabled": {
"message": "Fejlesztői mód bekapcsolva."
},
@@ -252,10 +204,10 @@
"message": "Erőforráskezelés"
},
"app.update-popup.body": {
"message": "A Modrinth App v{version} telepítésre kész! Frissítéshez válaszd ki a Frissítés opciót, vagy az alkalmazás a bezárásakor automatikusan frissül."
"message": "A Modrinth App v{version} telepítésre kész! Frissítéshez Töltsd újra az oldalt, vagy a Modrinth App bezárásakor automatikusan frissül."
},
"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."
"message": "A Modrinth App v{version} letöltése befejeződött. Frissítéshez Töltsd újra az oldalt, vagy a Modrinth App bezárásakor automatikusan frissül."
},
"app.update-popup.body.linux": {
"message": "A Modrinth App v{version} elérhető. Használd a csomagkezelőt a legújabb funkciók és javítások frissítéséhez!"
@@ -270,10 +222,10 @@
"message": "Letöltés ({size})"
},
"app.update-popup.download-complete": {
"message": "Sikeres letöltés"
"message": "Letöltés sikeres"
},
"app.update-popup.reload": {
"message": "Frissítés"
"message": "Újratöltés"
},
"app.update-popup.title": {
"message": "Frissítés elérhető"
@@ -294,7 +246,7 @@
"message": "A telepítéshez újraindítás szükséges"
},
"app.world.server-modal.placeholder-address": {
"message": "pelda.modrinth.gg"
"message": "example.modrinth.gg"
},
"app.world.server-modal.select-an-option": {
"message": "Válassz egy lehetőséget"
@@ -594,13 +546,13 @@
"message": "Hardcore mód"
},
"instance.worlds.incompatible_server": {
"message": "A szerver nem kompatibilis"
"message": "A Szerver nem kompatibilis"
},
"instance.worlds.linked_server": {
"message": "A szerver projektje által kezelt"
"message": "Szerverprojekt által kezelt"
},
"instance.worlds.no_contact": {
"message": "A szerverrel nem lehet kapcsolatot létesíteni"
"message": "Nem lehet kapcsolatot létesíteni a szerverrel"
},
"instance.worlds.no_server_quick_play": {
"message": "Csak Minecraft Alpha 1.0.5+-tól tudsz egyből szerverhez csatlakozni"
@@ -639,15 +591,6 @@
"message": "A játékverziót a szerver biztosítja"
},
"search.filter.locked.server-loader.title": {
"message": "A betöltőt a szerver biztosítja"
},
"unknown-pack-warning-modal.header": {
"message": "Telepítés megerősítése"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "Letöltés mindenképpen"
},
"unknown-pack-warning-modal.warning.body": {
"message": "Ezt a fájlt nem találtuk meg a Modrinthon. Határozottan javasoljuk, hogy kizárólag megbízható forrásokból származó fájlokat telepíts."
"message": "A betöltő a szerver által van megadva"
}
}
+1 -196
View File
@@ -1,124 +1,10 @@
{
"app.action-bar.downloading-java": {
"message": "Mengunduh Java {version}"
},
"app.action-bar.downloads": {
"message": "Unduhan"
},
"app.action-bar.hide-more-running-instances": {
"message": "Sembunyikan lebih banyak instans yang sedang berjalan"
},
"app.action-bar.make-primary-instance": {
"message": "Jadikan sebagai instans utama"
},
"app.action-bar.no-instances-running": {
"message": "Tidak ada instans yang sedang berjalan"
},
"app.action-bar.offline": {
"message": "Luring"
},
"app.action-bar.primary-instance": {
"message": "Instans utama"
},
"app.action-bar.show-more-running-instances": {
"message": "Tampilkan lebih banyak instans yang sedang berjalan"
},
"app.action-bar.stop-instance": {
"message": "Hentikan instans"
},
"app.action-bar.view-active-downloads": {
"message": "Lihat pengunduhan berlangsung"
},
"app.action-bar.view-instance": {
"message": "Lihat instans"
},
"app.action-bar.view-logs": {
"message": "Lihat catatan"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "Menghidupkan renderasi tingkat lanjut seperti efek buram yang dapat menyebabkan masalah kinerja tanpa renderasi yang dipercepat perangkat keras."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Renderasi tingkat lanjut"
},
"app.appearance-settings.color-theme.description": {
"message": "Pilih tema warna pilihan Anda untuk Modrinth App."
},
"app.appearance-settings.color-theme.title": {
"message": "Tema warna"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Ubah halaman utama yang dibuka oleh peluncur."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Beranda"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Pustaka"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Mematikan label nama di atas wujud pemain Anda pada halaman rupa."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Sembunyikan label nama"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Kecilkan pluncur ketika proses Minecraft berjalan."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Kecilkan peluncur"
},
"app.appearance-settings.select-option": {
"message": "Pilih opsi"
},
"app.auth-servers.unreachable.body": {
"message": "Server autentikasi Minecraft mungkin sedang tidak tersedia saat ini. Periksa koneksi internet Anda dan coba lagi nanti."
},
"app.auth-servers.unreachable.header": {
"message": "Tidak dapat terhubung ke server autentikasi"
},
"app.browse.add-servers-to-instance": {
"message": "Menambah server ke instans"
},
"app.browse.add-to-an-instance": {
"message": "Tambah ke instans"
},
"app.browse.add-to-instance": {
"message": "Tambah ke instans"
},
"app.browse.add-to-instance-name": {
"message": "Tambah ke {instanceName}"
},
"app.browse.added": {
"message": "Ditambahkan"
},
"app.browse.already-added": {
"message": "Telah ditambahkan"
},
"app.browse.back-to-instance": {
"message": "Kembali ke instans"
},
"app.browse.discover-content": {
"message": "Temukan konten"
},
"app.browse.discover-servers": {
"message": "Temukan server"
},
"app.browse.hide-added-servers": {
"message": "Sembunyikan server yang sudah ditambah"
},
"app.browse.project-type.modpacks": {
"message": "Paket Mod"
},
"app.browse.server.installing": {
"message": "Memasang"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Memasang paket mod..."
},
"app.export-modal.description-placeholder": {
"message": "Masukkan deskripsi paket mod..."
},
@@ -128,9 +14,6 @@
"app.export-modal.header": {
"message": "Ekspor paket mod"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Sertakan \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Nama Paket Mod"
},
@@ -138,7 +21,7 @@
"message": "Nama paket mod"
},
"app.export-modal.select-files-label": {
"message": "Konfigurasikan berkas mana yang disertakan dalam pengeksporan ini"
"message": "Pilih berkas dan folder yang ingin dimasukkan ke paket"
},
"app.export-modal.version-number-label": {
"message": "Nomor versi"
@@ -158,18 +41,9 @@
"app.instance.confirm-delete.header": {
"message": "Hapus instans"
},
"app.instance.modpack-already-installed.body": {
"message": "Paket mod ini telah terpasang di instans <bold>{instanceName}</bold>. Apakah Anda yakin ingin menggandakannya?"
},
"app.instance.modpack-already-installed.create": {
"message": "Buat"
},
"app.instance.modpack-already-installed.header": {
"message": "Paket mod telah terpasang"
},
"app.instance.modpack-already-installed.instance": {
"message": "Instans"
},
"app.instance.mods.content-type-project": {
"message": "proyek"
},
@@ -188,51 +62,6 @@
"app.instance.mods.successfully-uploaded": {
"message": "Berhasil diunggah"
},
"app.instance.worlds.add-server": {
"message": "Tambah server"
},
"app.instance.worlds.browse-servers": {
"message": "Telusuri server"
},
"app.instance.worlds.delete-world-description": {
"message": "'{name}' akan **dihapus secara permanen**, dan Anda tidak akan dapat memulihkannya."
},
"app.instance.worlds.delete-world-title": {
"message": "Apakah Anda yakin ingin menghapus dunia ini secara permanen?"
},
"app.instance.worlds.filter-modded": {
"message": "Dimodifikasi"
},
"app.instance.worlds.filter-offline": {
"message": "Luring"
},
"app.instance.worlds.filter-online": {
"message": "Daring"
},
"app.instance.worlds.filter-vanilla": {
"message": "Vanila"
},
"app.instance.worlds.no-worlds-description": {
"message": "Tambah server atau telusuri untuk memulai"
},
"app.instance.worlds.no-worlds-heading": {
"message": "Tidak ada server atau dunia yang ditambahkan"
},
"app.instance.worlds.remove-server-description": {
"message": "'{name}' akan dihapus dari daftar Anda, termasuk di dalam permainan, dan Anda tidak akan dapat memulihkannya."
},
"app.instance.worlds.remove-server-description-with-address": {
"message": "'{name}' ({address}) akan dihapus dari daftar Anda, termasuk di dalam permainan, dan Anda tidak akan dapat memulihkannya."
},
"app.instance.worlds.remove-server-title": {
"message": "Apakah Anda yakin ingin menghapus {name}?"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Cari {count} dunia..."
},
"app.instance.worlds.this-server": {
"message": "server ini"
},
"app.modal.install-to-play.content-required": {
"message": "Konten diperlukan"
},
@@ -335,24 +164,6 @@
"app.update.reload-to-update": {
"message": "Muat ulang untuk memasang pembaruan"
},
"app.world.server-modal.placeholder-address": {
"message": "example.modrinth.gg"
},
"app.world.server-modal.select-an-option": {
"message": "Pilih opsi"
},
"app.world.world-item.incompatible-version": {
"message": "Versi {version} tidak cocok"
},
"app.world.world-item.not-played-yet": {
"message": "Belum pernah dimainkan"
},
"app.world.world-item.offline": {
"message": "Luring"
},
"app.world.world-item.players-online": {
"message": "{count} orang daring"
},
"friends.action.add-friend": {
"message": "Tambah teman"
},
@@ -452,12 +263,6 @@
"instance.edit-world.title": {
"message": "Sunting dunia"
},
"instance.files.adding-files": {
"message": "Menambahkan berkas ({completed}/{total})"
},
"instance.files.save-as": {
"message": "Simpan sebagai..."
},
"instance.server-modal.address": {
"message": "Alamat"
},
+20 -182
View File
@@ -1,114 +1,15 @@
{
"app.action-bar.downloading-java": {
"message": "Java {version}"
},
"app.action-bar.downloads": {
"message": "Download"
},
"app.action-bar.hide-more-running-instances": {
"message": "Mostra meno istanze in esecuzione"
},
"app.action-bar.make-primary-instance": {
"message": "Rendi primaria"
},
"app.action-bar.no-instances-running": {
"message": "Nessuna istanza in esecuzione"
},
"app.action-bar.offline": {
"message": "Offline"
},
"app.action-bar.primary-instance": {
"message": "Primaria"
},
"app.action-bar.show-more-running-instances": {
"message": "Mostra più istanze in esecuzione"
},
"app.action-bar.stop-instance": {
"message": "Ferma l'istanza"
},
"app.action-bar.view-active-downloads": {
"message": "Mostra i download attivi"
},
"app.action-bar.view-instance": {
"message": "Mostra l'istanza"
},
"app.action-bar.view-logs": {
"message": "Mostra i log"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "Abilita alcuni effetti come la sfocatura, ma può causare problemi di prestazioni senza accelerazione hardware."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Rendering avanzato"
},
"app.appearance-settings.color-theme.description": {
"message": "Scegli il tema che Modrinth App userà su questo dispositivo."
},
"app.appearance-settings.color-theme.title": {
"message": "Tema"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Imposta la pagina che si aprirà all'avvio del launcher."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Home"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Libreria"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Pagina di avvio"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Rimuove il nametag sopra la testa del giocatore nella pagina delle skin."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Nascondi il nome"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Elenca i mondi recenti nella sezione \"Avvio rapido\" della pagina Home."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Avvio rapido nei mondi"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Riduci il launcher a icona quando si avvia Minecraft."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Riduci a icona"
},
"app.appearance-settings.native-decorations.description": {
"message": "Usa la cornice di sistema (riavvio necessario)."
},
"app.appearance-settings.native-decorations.title": {
"message": "Decorazioni native"
},
"app.appearance-settings.select-option": {
"message": "Scegli una pagina"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Scegli se mostrare o nascondere la barra laterale."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "Abilita la barra laterale"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Visti i rischi nell'installare un file Modrinth Pack (.mrpack) non proveniente da Modrinth, mostriamo un avvertimento quando tenti di fare ciò."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "Avvisami se 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."
},
"app.auth-servers.unreachable.header": {
"message": "Impossibile raggiungere i server di autenticazione"
},
"app.browse.add-servers-to-instance": {
"message": "Aggiungendo il server all'istanza"
"app.browse.add-server-to-instance": {
"message": "Aggiungi server all'istanza"
},
"app.browse.add-to-an-instance": {
"message": "Aggiungi a un'istanza"
"app.browse.add-servers-to-instance": {
"message": "Aggiungi server alla tua istanza"
},
"app.browse.add-to-instance": {
"message": "Aggiungi all'istanza"
@@ -122,32 +23,20 @@
"app.browse.already-added": {
"message": "Già aggiunto"
},
"app.browse.back-to-instance": {
"message": "Torna all'istanza"
},
"app.browse.discover-content": {
"message": "Esplora i contenuti"
"message": "Esplora contenuti"
},
"app.browse.discover-servers": {
"message": "Esplora i server"
},
"app.browse.hide-added-servers": {
"message": "Nascondi server già aggiunti"
"message": "Nascondi server aggiunti"
},
"app.browse.project-type.modpacks": {
"message": "Pacchetti di mod"
"app.browse.hide-installed-content": {
"message": "Nascondi contenuti installati"
},
"app.browse.server-instance-content-warning": {
"message": "Aggiungere dei contenuti potrebbe portare problemi entrando nel server. Qualsiasi contenuto aggiunto sarà anche perso aggiornando i contenuti dell'istanza del server."
},
"app.browse.server.installing": {
"message": "Installazione"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Installando il pacchetto..."
"app.browse.install-content-to-instance": {
"message": "Installa nella istanza"
},
"app.export-modal.description-placeholder": {
"message": "Inserisci descrizione del pacchetto..."
@@ -158,9 +47,6 @@
"app.export-modal.header": {
"message": "Esporta pacchetto"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Includere \"{file}\" nell'esportazione?"
},
"app.export-modal.modpack-name-label": {
"message": "Nome del pacchetto"
},
@@ -168,7 +54,7 @@
"message": "Nome del pacchetto"
},
"app.export-modal.select-files-label": {
"message": "Seleziona i file da includere in questa esportazione"
"message": "Seleziona i file e le cartelle da includere nel pacchetto"
},
"app.export-modal.version-number-label": {
"message": "Numero di versione"
@@ -225,10 +111,10 @@
"message": "Esplora i server"
},
"app.instance.worlds.delete-world-description": {
"message": "\"{name}\" verrà **eliminato permanentemente** e non ci sarà modo di recuperarlo."
"message": "\"{name}\" verrà eliminato permanentemente e non ci sarà modo di recuperarlo."
},
"app.instance.worlds.delete-world-title": {
"message": "Vuoi davvero eliminare questo mondo per sempre?"
"message": "Vuoi davvero eliminare permanentemente questo mondo?"
},
"app.instance.worlds.filter-modded": {
"message": "Moddato"
@@ -246,13 +132,13 @@
"message": "Inizia esplorando o aggiungendo un server"
},
"app.instance.worlds.no-worlds-heading": {
"message": "Nessun server o mondo aggiunto"
"message": "Nessun server o mondi aggiunti"
},
"app.instance.worlds.remove-server-description": {
"message": "\"{name}\" sarà rimosso dalla tua lista, inclusa quella nel gioco, e non ci sarà modo di recuperarlo."
"message": "\"{name}\" sarà rimosso dalla tua lista, inclusa quella in-gioco, e non ci sarà modo di recuperarlo."
},
"app.instance.worlds.remove-server-description-with-address": {
"message": "\"{name}\" ({address}) sarà rimosso dalla tua lista, inclusa quella nel gioco, e non ci sarà modo di recuperarlo."
"message": "\"{name}\" ({address}) sarà rimosso dalla tua lista, inclusa quella in-gioco, e non ci sarà modo di recuperarlo."
},
"app.instance.worlds.remove-server-title": {
"message": "Vuoi davvero rimuovere {name}?"
@@ -299,15 +185,6 @@
"app.modal.update-to-play.update-required-description": {
"message": "{name} richiede degli aggiornamenti. Installa l'ultima versione per poter giocare."
},
"app.project.install-button.already-installed": {
"message": "Questo progetto è già stato installato"
},
"app.project.install-context.back-to-browse": {
"message": "Torna su esplora"
},
"app.project.install-context.install-content-to-instance": {
"message": "Installa il contenuto nell'istanza"
},
"app.settings.developer-mode-enabled": {
"message": "Modalità sviluppatore attiva."
},
@@ -369,7 +246,7 @@
"message": "Scarica aggiornamento"
},
"app.update.downloading-update": {
"message": "Scaricando l'aggiornamento ({percent}%)"
"message": "Scaricando aggiornamento ({percent}%)"
},
"app.update.reload-to-update": {
"message": "Ricarica per installare l'aggiornamento"
@@ -447,7 +324,7 @@
"message": "Nessuna amicizia corrisponde a ''{query}''"
},
"friends.search-friends-placeholder": {
"message": "Cerca tra le amicizie..."
"message": "Cerca amicizie..."
},
"friends.section.heading": {
"message": "{title} - {count}"
@@ -486,7 +363,7 @@
"message": "Mondo di Minecraft"
},
"instance.edit-world.reset-icon": {
"message": "Ripristina icona"
"message": "Resetta icona"
},
"instance.edit-world.title": {
"message": "Modifica mondo"
@@ -546,7 +423,7 @@
"message": "Cambia icona"
},
"instance.settings.tabs.general.edit-icon.select": {
"message": "Scegli un'icona"
"message": "Seleziona icona"
},
"instance.settings.tabs.general.library-groups": {
"message": "Gruppi della libreria"
@@ -698,24 +575,6 @@
"instance.worlds.world_in_use": {
"message": "Mondo già in uso"
},
"minecraft-account.add-account": {
"message": "Aggiungi account"
},
"minecraft-account.label": {
"message": "Account di Minecraft"
},
"minecraft-account.not-signed-in": {
"message": "Accesso non effettuato"
},
"minecraft-account.remove-account": {
"message": "Rimuovi account"
},
"minecraft-account.select-account": {
"message": "Seleziona un account"
},
"minecraft-account.sign-in": {
"message": "Accedi a Minecraft"
},
"search.filter.locked.instance": {
"message": "Determinato dall'istanza"
},
@@ -739,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "Il loader è determinato dal server"
},
"unknown-pack-warning-modal.body": {
"message": "Solo i file caricati su Modrinth vengono esaminati, qualunque sia il loro formato (.mrpack inclusi)."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "Non mostrare più questo avviso"
},
"unknown-pack-warning-modal.header": {
"message": "Conferma l'installazione"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "Installa comunque"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "Spesso i malware vengono nascosti nei pacchetti di mod, poi distribuiti su piattaforme come Discord."
},
"unknown-pack-warning-modal.warning.body": {
"message": "Non è stato possibile trovare questo file su Modrinth. Consigliamo di installare file solo da fonti attendibili."
},
"unknown-pack-warning-modal.warning.title": {
"message": "Tipo di file sconosciuto"
}
}
+17 -152
View File
@@ -1,109 +1,16 @@
{
"app.action-bar.downloading-java": {
"message": "Java {version} をダウンロード中"
},
"app.action-bar.downloads": {
"message": "ダウンロード"
},
"app.action-bar.hide-more-running-instances": {
"message": "実行中のインスタンスの一部を非表示"
},
"app.action-bar.make-primary-instance": {
"message": "デフォルトのインスタンスを作成"
},
"app.action-bar.no-instances-running": {
"message": "実行中のインスタンスはありません"
},
"app.action-bar.offline": {
"message": "オフライン"
},
"app.action-bar.primary-instance": {
"message": "デフォルトのインスタンス"
},
"app.action-bar.show-more-running-instances": {
"message": "実行中のインスタンスをさらに表示"
},
"app.action-bar.stop-instance": {
"message": "インスタンスを停止"
},
"app.action-bar.view-active-downloads": {
"message": "進行中のダウンロードを表示"
},
"app.action-bar.view-instance": {
"message": "インスタンスを表示"
},
"app.action-bar.view-logs": {
"message": "ログを表示"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "ぼかし効果などの高度なレンダリングを有効にします。グラフィックアクセラレーションが使用できない場合は、パフォーマンスが低下する可能性があります。"
},
"app.appearance-settings.advanced-rendering.title": {
"message": "高度なレンダリング"
},
"app.appearance-settings.color-theme.description": {
"message": "Modrinth Appでのお好みのテーマを選択してください"
},
"app.appearance-settings.color-theme.title": {
"message": "テーマ"
},
"app.appearance-settings.default-landing-page.description": {
"message": "ランチャー起動時に表示するページを変更します"
},
"app.appearance-settings.default-landing-page.home": {
"message": "ホーム"
},
"app.appearance-settings.default-landing-page.library": {
"message": "ライブラリ"
},
"app.appearance-settings.default-landing-page.title": {
"message": "デフォルトの起動ページ"
},
"app.appearance-settings.hide-nametag.description": {
"message": "スキンページで、プレイヤー名の上にある名前タグを無効にします。"
},
"app.appearance-settings.hide-nametag.title": {
"message": "名札を非表示にする"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "ホームページの「ジャンプバック」セクションには、最近追加されたワールドが含まれています。"
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "再び世界へ飛び込もう"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Minecraftが起動した時、ランチャーを最小化します"
},
"app.appearance-settings.minimize-launcher.title": {
"message": "ランチャーを最小化"
},
"app.appearance-settings.native-decorations.description": {
"message": "OSデフォルトのウィンドウUIを使用します(アプリの再起動が必要です)"
},
"app.appearance-settings.native-decorations.title": {
"message": "OSのウィンドウUIを使用"
},
"app.appearance-settings.select-option": {
"message": "オプションを選択してください"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "サイドバーの表示/非表示を切り替える機能を有効にします。"
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "サイドバーの表示/非表示を切り替える"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Modrinth上にホストされていないModrinth Packファイル(.mrpack)をインストールしようとした場合、インストール前にそのリスクを理解していただけるよう確認します。"
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "未知のMODパックをインストールする前に警告してください"
},
"app.auth-servers.unreachable.body": {
"message": "Minecraftの認証サーバーは現在停止している可能性があります。インターネット接続を確認し、しばらくしてからもう一度お試しください。"
},
"app.auth-servers.unreachable.header": {
"message": "認証サーバーにアクセスできません"
},
"app.browse.add-server-to-instance": {
"message": "サーバーをインスタンスに追加"
},
"app.browse.add-servers-to-instance": {
"message": "サーバーを自身のインスタンスに追加"
},
"app.browse.add-to-instance": {
"message": "インスタンスに追加"
},
@@ -123,19 +30,13 @@
"message": "サーバーを探す"
},
"app.browse.hide-added-servers": {
"message": "既に追加済みのサーバーを非表示にする"
"message": "追加済みのサーバーを隠す"
},
"app.browse.project-type.modpacks": {
"message": "Modパック"
"app.browse.hide-installed-content": {
"message": "インストール済みのコンテンツを隠す"
},
"app.browse.server.installing": {
"message": "インストール"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Modパックをインストール中..."
"app.browse.install-content-to-instance": {
"message": "コンテンツをインスタンスにインストールする"
},
"app.export-modal.description-placeholder": {
"message": "Modパックの説明を入力…"
@@ -152,6 +53,9 @@
"app.export-modal.modpack-name-placeholder": {
"message": "Modパック名"
},
"app.export-modal.select-files-label": {
"message": "パックに含めるファイルとフォルダーを選択"
},
"app.export-modal.version-number-label": {
"message": "バージョン番号"
},
@@ -222,7 +126,7 @@
"message": "オンライン"
},
"app.instance.worlds.filter-vanilla": {
"message": "バニラ"
"message": "バニラ(Mod非導入)"
},
"app.instance.worlds.no-worlds-description": {
"message": "サーバーを追加、またはブラウズして始める"
@@ -240,7 +144,7 @@
"message": "本当に {name} を削除しますか?"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "{count} 個のワールドを検索"
"message": "{count} 個のワールドを検索..."
},
"app.instance.worlds.this-server": {
"message": "このサーバー"
@@ -468,7 +372,7 @@
"message": "ファイルを追加中 ({completed}/{total})"
},
"instance.files.save-as": {
"message": "名前をつけて保存"
"message": "名前をつけて保存..."
},
"instance.server-modal.address": {
"message": "アドレス"
@@ -671,24 +575,6 @@
"instance.worlds.world_in_use": {
"message": "ワールドは使用中"
},
"minecraft-account.add-account": {
"message": "アカウントを追加"
},
"minecraft-account.label": {
"message": "Minecraftアカウント"
},
"minecraft-account.not-signed-in": {
"message": "サインインしていません"
},
"minecraft-account.remove-account": {
"message": "アカウントを一覧から削除"
},
"minecraft-account.select-account": {
"message": "アカウントを選択"
},
"minecraft-account.sign-in": {
"message": "Minecraftにサインイン"
},
"search.filter.locked.instance": {
"message": "インスタンスによる条件"
},
@@ -712,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "ローダーはサーバーによる条件です"
},
"unknown-pack-warning-modal.body": {
"message": "ファイル形式に関わらず、Modrinthにアップロードされたファイルのみが確認されます。(.mrpackを含む)"
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "この警告を次回から表示しない"
},
"unknown-pack-warning-modal.header": {
"message": "インストールの確認"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "インストールを続行"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "一般的にマルウェアは、Discord等のプラットフォーム上でModパックファイルを配布して拡散されます"
},
"unknown-pack-warning-modal.warning.body": {
"message": "このファイルをModrinth上で見つけることができませんでした。信頼できるソースからインストールすることを強くお勧めします。"
},
"unknown-pack-warning-modal.warning.title": {
"message": "不明なファイルの警告"
}
}
+14 -155
View File
@@ -1,109 +1,16 @@
{
"app.action-bar.downloading-java": {
"message": "Java {version} 다운로드 중"
},
"app.action-bar.downloads": {
"message": "다운로드"
},
"app.action-bar.hide-more-running-instances": {
"message": "실행 중인 인스턴스 숨기기"
},
"app.action-bar.make-primary-instance": {
"message": "기본 인스턴스로 지정"
},
"app.action-bar.no-instances-running": {
"message": "실행 중인 인스턴스 없음"
},
"app.action-bar.offline": {
"message": "오프라인"
},
"app.action-bar.primary-instance": {
"message": "기본 인스턴스"
},
"app.action-bar.show-more-running-instances": {
"message": "실행 중인 인스턴스 보이기"
},
"app.action-bar.stop-instance": {
"message": "인스턴스 중지"
},
"app.action-bar.view-active-downloads": {
"message": "다운로드 목록 보기"
},
"app.action-bar.view-instance": {
"message": "인스턴스 보기"
},
"app.action-bar.view-logs": {
"message": "로그 보기"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "블러 효과와 같은 고급 렌더링 기능을 활성화합니다. 하드웨어 가속 없이는 성능 저하가 발생할 수 있습니다."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "고급 렌더링"
},
"app.appearance-settings.color-theme.description": {
"message": "Modrinth App에서 선호하는 색상 테마를 선택합니다."
},
"app.appearance-settings.color-theme.title": {
"message": "색상 테마"
},
"app.appearance-settings.default-landing-page.description": {
"message": "런처의 기본 시작 화면을 변경합니다."
},
"app.appearance-settings.default-landing-page.home": {
"message": "홈"
},
"app.appearance-settings.default-landing-page.library": {
"message": "라이브러리"
},
"app.appearance-settings.default-landing-page.title": {
"message": "기본 시작 화면"
},
"app.appearance-settings.hide-nametag.description": {
"message": "스킨 화면에서 플레이어 위에 있는 이름표를 비활성화합니다."
},
"app.appearance-settings.hide-nametag.title": {
"message": "이름표 숨기기"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "홈 화면의 \"바로 입장\" 부분에 최근 플레이한 월드를 표시합니다."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "세계로 바로 입장"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "마인크래프트 실행 시 런처를 최소화합니다."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "런처 최소화"
},
"app.appearance-settings.native-decorations.description": {
"message": "시스템 창 테두리 (앱 재시작 필요)."
},
"app.appearance-settings.native-decorations.title": {
"message": "네이티브 제목 표시줄"
},
"app.appearance-settings.select-option": {
"message": "옵션 선택"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "사이드바를 접거나 펼칠 수 있는 기능을 활성화합니다."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "사이드바 토글"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Modrinth 외부에서 가져온 모드팩 파일(.mrpack)을 설치할 때, 사용자가 위험성을 인지할 수 있도록 경고를 표시합니다."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "출처를 알 수 없는 모드팩 설치 전 경고"
},
"app.auth-servers.unreachable.body": {
"message": "Minecraft 인증 서버가 일시적으로 중단되었을 수 있습니다. 인터넷 연결을 확인한 후 나중에 다시 시도하세요."
},
"app.auth-servers.unreachable.header": {
"message": "인증 서버에 연결할 수 없습니다"
},
"app.browse.add-server-to-instance": {
"message": "인스턴스에 서버 추가"
},
"app.browse.add-servers-to-instance": {
"message": "인스턴스에 서버 추가"
},
"app.browse.add-to-instance": {
"message": "인스턴스에 추가"
},
@@ -123,19 +30,13 @@
"message": "서버 탐색하기"
},
"app.browse.hide-added-servers": {
"message": "이미 추가된 서버 숨기기"
"message": "추가된 서버 숨기기"
},
"app.browse.project-type.modpacks": {
"message": "모드팩"
"app.browse.hide-installed-content": {
"message": "설치된 콘텐츠 숨기기"
},
"app.browse.server.installing": {
"message": "설치"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "모드팩 설치중..."
"app.browse.install-content-to-instance": {
"message": "인스턴스에 콘텐츠 설치"
},
"app.export-modal.description-placeholder": {
"message": "모드팩 설명 입력..."
@@ -146,9 +47,6 @@
"app.export-modal.header": {
"message": "모드팩 내보내기"
},
"app.export-modal.include-file-accessibility-label": {
"message": "\"{file}\"(을)를 포함할까요?"
},
"app.export-modal.modpack-name-label": {
"message": "모드팩 이름"
},
@@ -156,7 +54,7 @@
"message": "모드팩 이름"
},
"app.export-modal.select-files-label": {
"message": "내보내기에 어느 파일이 포함될지 구성"
"message": "팩에 포함할 파일과 폴더 선택"
},
"app.export-modal.version-number-label": {
"message": "버전 구분"
@@ -318,10 +216,10 @@
"message": "Modrinth App v{version} 다운로드가 완료되었습니다. 새로고침하거나 Modrinth App을 종료하면 자동으로 업데이트됩니다."
},
"app.update-popup.body.linux": {
"message": "Modrinth v{version}을 사용할 수 있습니다. 최신 기능과 오류 수정을 적용하려면 패키지 관리자를 통해 업데이트하세요!"
"message": "Modrinth App v{version}을 사용할 수 있습니다. 최신 기능과 오류 수정을 적용하려면 패키지 관리자를 통해 업데이트하세요!"
},
"app.update-popup.body.metered": {
"message": "Modrinth v{version}을 지금 사용할 수 있습니다! 데이터 통신 연결을 사용 중이므로, 자동으로 다운로드하지 않았습니다."
"message": "Modrinth App v{version}을 지금 사용할 수 있습니다! 데이터 통신 연결을 사용 중이므로, 자동으로 다운로드하지 않았습니다."
},
"app.update-popup.changelog": {
"message": "변경 내역"
@@ -677,24 +575,6 @@
"instance.worlds.world_in_use": {
"message": "사용 중인 세계"
},
"minecraft-account.add-account": {
"message": "계정 추가"
},
"minecraft-account.label": {
"message": "마인크래프트 계정"
},
"minecraft-account.not-signed-in": {
"message": "로그인하지 않음"
},
"minecraft-account.remove-account": {
"message": "계정 제거"
},
"minecraft-account.select-account": {
"message": "계정 선택"
},
"minecraft-account.sign-in": {
"message": "마인크래프트 계정으로 로그인"
},
"search.filter.locked.instance": {
"message": "인스턴스에서 관리"
},
@@ -718,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "로더가 서버에 의해 제공됩니다"
},
"unknown-pack-warning-modal.body": {
"message": "모든 파일은 형식(.mrpack 포함)에 무관하게 Modrinth에 업로드되어야만 검수를 거칩니다."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "이 경고를 다시 표시하지 않음"
},
"unknown-pack-warning-modal.header": {
"message": "설치 확인"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "무시하고 설치"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "악성코드는 흔히 디스코드와 같은 플랫폼을 통해 모드팩 파일을 공유하는 방식으로 유포됩니다."
},
"unknown-pack-warning-modal.warning.body": {
"message": "이 파일을 Modrinth에서 찾을 수 없습니다. 신뢰할 수 있는 출처의 파일만 설치하는 것을 권장합니다."
},
"unknown-pack-warning-modal.warning.title": {
"message": "출처를 알 수 없는 파일 경고"
}
}
+10 -172
View File
@@ -1,114 +1,15 @@
{
"app.action-bar.downloading-java": {
"message": "Sedang memuat turun Java {version}"
},
"app.action-bar.downloads": {
"message": "Muat Turun"
},
"app.action-bar.hide-more-running-instances": {
"message": "Sembunyikan lebih banyak pemasangan yang berjalan"
},
"app.action-bar.make-primary-instance": {
"message": "Jadikan pemasangan utama"
},
"app.action-bar.no-instances-running": {
"message": "Tiada pemasangan yang berjalan"
},
"app.action-bar.offline": {
"message": "Luar Talian"
},
"app.action-bar.primary-instance": {
"message": "Pemasangan utama"
},
"app.action-bar.show-more-running-instances": {
"message": "Tunjukkan lebih banyak pemasangan yang berjalan"
},
"app.action-bar.stop-instance": {
"message": "Hentikan pemasangan"
},
"app.action-bar.view-active-downloads": {
"message": "Lihat muat turun aktif"
},
"app.action-bar.view-instance": {
"message": "Lihat pemasangan"
},
"app.action-bar.view-logs": {
"message": "Lihat log"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "Mendayakan pemaparan lanjutan seperti kesan kabur yang boleh menyebabkan masalah prestasi tanpa pemaparan dipercepatkan perkakasan."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Pemaparan lanjutan"
},
"app.appearance-settings.color-theme.description": {
"message": "Pilih tema warna pilihan anda untuk Modrinth App."
},
"app.appearance-settings.color-theme.title": {
"message": "Tema warna"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Tukar laman utama yang dibuka oleh pelancar."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Laman utama"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Pustaka"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Laman pendaratan lalai"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Menyahdayakan tanda nama di atas pemain anda pada halaman kekulit."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Sembunyikan tanda nama"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Sertakan dunia terkini dalam bahagian \"Lompat kembali\" pada Laman Utama."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Lompat kembali ke dalam dunia"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Meminimumkan pelancar apabila proses Minecraft bermula."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Minimumkan pelancar"
},
"app.appearance-settings.native-decorations.description": {
"message": "Gunakan bingkai tetingkap sistem (aplikasi perlu dimulakan semula)."
},
"app.appearance-settings.native-decorations.title": {
"message": "Hiasan asli"
},
"app.appearance-settings.select-option": {
"message": "Pilih satu pilihan"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Membolehkan keupayaan untuk menogol bar sisi."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "Togol bar sisi"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Jika anda cuba memasang fail Modrinth Pack (.mrpack) yang tidak dihoskan pada Modrinth, kami akan memastikan anda memahami risikonya sebelum memasangnya."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "Beri saya amaran sebelum memasang pek mod yang tidak diketahui"
},
"app.auth-servers.unreachable.body": {
"message": "Pelayan pengesahan Minecraft mungkin sedang tergendala sekarang. Periksa sambungan internet anda dan cuba lagi kemudian."
},
"app.auth-servers.unreachable.header": {
"message": "Tidak dapat mencapai pelayan pengesahan"
},
"app.browse.add-servers-to-instance": {
"message": "Menambah pelayan ke dalam pemasangan"
"app.browse.add-server-to-instance": {
"message": "Tambahkan pelayan ke dalam pemasangan"
},
"app.browse.add-to-an-instance": {
"message": "Tambahkan ke dalam pemasangan"
"app.browse.add-servers-to-instance": {
"message": "Tambahkan pelayan ke dalam pemasangan anda"
},
"app.browse.add-to-instance": {
"message": "Tambahkan ke dalam pemasangan"
@@ -122,9 +23,6 @@
"app.browse.already-added": {
"message": "Sudah ditambah"
},
"app.browse.back-to-instance": {
"message": "Kembali ke pemasangan"
},
"app.browse.discover-content": {
"message": "Temui kandungan"
},
@@ -132,22 +30,13 @@
"message": "Temui pelayan"
},
"app.browse.hide-added-servers": {
"message": "Sembunyikan pelayan yang sudah ditambah"
"message": "Sembunyikan pelayan yang ditambah"
},
"app.browse.project-type.modpacks": {
"message": "Pek Mod"
"app.browse.hide-installed-content": {
"message": "Sembunyikan kandungan yang dipasang"
},
"app.browse.server-instance-content-warning": {
"message": "Menambah kandungan boleh merosakkan keserasian apabila menyertai pelayan. Sebarang kandungan yang ditambah juga akan hilang apabila anda mengemas kini kandungan pemasangan pelayan."
},
"app.browse.server.installing": {
"message": "Sedang memasang"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Sedang memasang pek mod..."
"app.browse.install-content-to-instance": {
"message": "Pasang kandungan ke dalam pemasangan"
},
"app.export-modal.description-placeholder": {
"message": "Masukkan keterangan pek mod..."
@@ -158,9 +47,6 @@
"app.export-modal.header": {
"message": "Eksport pek mod"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Sertakan \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Nama Pek Mod"
},
@@ -168,7 +54,7 @@
"message": "Nama pek mod"
},
"app.export-modal.select-files-label": {
"message": "Konfigurasikan fail yang disertakan dalam eksport ini"
"message": "Pilih fail dan folder untuk disertakan dalam pek mod"
},
"app.export-modal.version-number-label": {
"message": "Nombor versi"
@@ -299,15 +185,6 @@
"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"
},
"app.project.install-context.back-to-browse": {
"message": "Kembali melayar"
},
"app.project.install-context.install-content-to-instance": {
"message": "Pasang kandungan ke dalam pemasangan"
},
"app.settings.developer-mode-enabled": {
"message": "Mod pembangun didayakan."
},
@@ -698,24 +575,6 @@
"instance.worlds.world_in_use": {
"message": "Dunia sedang digunakan"
},
"minecraft-account.add-account": {
"message": "Tambah akaun"
},
"minecraft-account.label": {
"message": "Akaun Minecraft"
},
"minecraft-account.not-signed-in": {
"message": "Tidak didaftar masuk"
},
"minecraft-account.remove-account": {
"message": "Alih keluar akaun"
},
"minecraft-account.select-account": {
"message": "Pilih akaun"
},
"minecraft-account.sign-in": {
"message": "Daftar masuk ke dalam Minecraft"
},
"search.filter.locked.instance": {
"message": "Disediakan oleh pemasangan ini"
},
@@ -739,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "Pemuat adalah disediakan oleh pelayan"
},
"unknown-pack-warning-modal.body": {
"message": "Sesuatu fail hanya disemak jika ia dimuat naik ke Modrinth, tanpa mengira format failnya (termasuk .mrpack)."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "Jangan tunjukkan amaran ini lagi"
},
"unknown-pack-warning-modal.header": {
"message": "Sahkan pemasangan"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "Pasangkan juga"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "Perisian hasad sering diedarkan melalui fail pek mod dengan berkongsinya di platform seperti Discord."
},
"unknown-pack-warning-modal.warning.body": {
"message": "Kami tidak dapat menemui fail ini di Modrinth. Kami sangat mengesyorkan anda untuk hanya memasang fail daripada sumber yang anda percayai."
},
"unknown-pack-warning-modal.warning.title": {
"message": "Amaran fail tidak diketahui"
}
}
+5 -278
View File
@@ -1,154 +1,10 @@
{
"app.action-bar.downloading-java": {
"message": "Java {version} aan het downloaden"
},
"app.action-bar.downloads": {
"message": "Downloads"
},
"app.action-bar.hide-more-running-instances": {
"message": "Verberg meer actieve instanties"
},
"app.action-bar.make-primary-instance": {
"message": "Maak primaire instantie"
},
"app.action-bar.no-instances-running": {
"message": "Geen actieve instanties"
},
"app.action-bar.offline": {
"message": "Offline"
},
"app.action-bar.primary-instance": {
"message": "Primaire instantie"
},
"app.action-bar.show-more-running-instances": {
"message": "Toon meer actieve instanties"
},
"app.action-bar.stop-instance": {
"message": "Stop instantie"
},
"app.action-bar.view-active-downloads": {
"message": "Bekijk actieve downloads"
},
"app.action-bar.view-instance": {
"message": "Bekijk instantie"
},
"app.action-bar.view-logs": {
"message": "Bekijk logs"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "Activeert geavanceerde weergaves zoals blur effecten die mogelijke prestatieproblemen opleveren zonder hardware-versnelde weergeving."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Geavanceerde weergave"
},
"app.appearance-settings.color-theme.description": {
"message": "Selecteer je voorkeur kleurenthema voor de Modrinth App."
},
"app.appearance-settings.color-theme.title": {
"message": "Kleurenthema"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Wijzig de pagina waarop de launcher opent."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Home"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Bibliotheek"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Standaard openingspagina"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Schakelt het nametag boven jouw speler op de skins pagina uit."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Verberg nametag"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Inclusief recente werelden in het gedeelte \"Ga terug\" op de startpagina."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Ga terug in werelden"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Minimaliseer de launcher als een Minecraft proces wordt gestart."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Minimaliseer launcher"
},
"app.appearance-settings.native-decorations.description": {
"message": "Gebruik systeem venster frame (app opnieuw starten vereist)."
},
"app.appearance-settings.native-decorations.title": {
"message": "Oorspronkelijke versieringen"
},
"app.appearance-settings.select-option": {
"message": "Selecteer een optie"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Schakelt de mogelijkheid om de zijbalk in- of uit te schakelen in."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "Schakel zijbalk"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Als je probeert een Modrinth Pack-bestand (.mrpack) te installeren dat niet op Modrinth zelf wordt gehost, zorgen we ervoor dat je de risico's begrijpt voordat je het installeert."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "Waarschuw mij voordat ik onbekende modpacks installeer"
},
"app.auth-servers.unreachable.body": {
"message": "Minecraft authenticatie servers zijn mogelijk offline. Controleer je internetverbinding en probeer opnieuw later."
},
"app.auth-servers.unreachable.header": {
"message": "Authenticatieservers kunnen niet worden bereikt"
},
"app.browse.add-servers-to-instance": {
"message": "Server toevoegen aan instantie"
},
"app.browse.add-to-an-instance": {
"message": "Voeg toe aan een instantie"
},
"app.browse.add-to-instance": {
"message": "Voeg aan instantie toe"
},
"app.browse.add-to-instance-name": {
"message": "Voeg aan {instanceName} toe"
},
"app.browse.added": {
"message": "Toegevoegd"
},
"app.browse.already-added": {
"message": "Al toegevoegd"
},
"app.browse.back-to-instance": {
"message": "Terug naar instantie"
},
"app.browse.discover-content": {
"message": "Ontdek content"
},
"app.browse.discover-servers": {
"message": "Ontdek servers"
},
"app.browse.hide-added-servers": {
"message": "Verberg al toegevoegde servers"
},
"app.browse.project-type.modpacks": {
"message": "Modpacks"
},
"app.browse.server-instance-content-warning": {
"message": "Het toevoegen van content kan de compatibiliteit verbreken bij het verbinden met de server. Alle toegevoegde inhoud gaat ook verloren wanneer u de content van de serverinstantie bijwerkt."
},
"app.browse.server.installing": {
"message": "Installeren"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Modpack aan het installeren..."
},
"app.export-modal.description-placeholder": {
"message": "Voeg modpack beschrijving in..."
},
@@ -158,9 +14,6 @@
"app.export-modal.header": {
"message": "Exporteer modpack"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Betrek \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Modpack Naam"
},
@@ -168,7 +21,7 @@
"message": "Modpack naam"
},
"app.export-modal.select-files-label": {
"message": "Configureer welke bestanden bij deze export zijn betrokken"
"message": "Selecteer bestanden en mappen om toe te voegen aan pack"
},
"app.export-modal.version-number-label": {
"message": "Versie nummer"
@@ -188,18 +41,9 @@
"app.instance.confirm-delete.header": {
"message": "Verwijder instantie"
},
"app.instance.modpack-already-installed.body": {
"message": "Deze modpakket is al in de <bold>{instanceName}<bold> instantie geïnstalleerd. Ben je zeker dat je het geen wil dupliceren?"
},
"app.instance.modpack-already-installed.create": {
"message": "Maak"
},
"app.instance.modpack-already-installed.header": {
"message": "Modpack is al geïnstalleerd"
},
"app.instance.modpack-already-installed.instance": {
"message": "Instantie"
},
"app.instance.mods.content-type-project": {
"message": "project"
},
@@ -207,7 +51,7 @@
"message": "\"{name}\" was toegevoegd"
},
"app.instance.mods.projects-were-added": {
"message": "{count} Projecten waren toegevoegd"
"message": "{count} projecten waren toegevoegd"
},
"app.instance.mods.share-text": {
"message": "Bekijk de projecten die ik in mijn modpack gebruik!"
@@ -218,51 +62,6 @@
"app.instance.mods.successfully-uploaded": {
"message": "Succesvol geüpload"
},
"app.instance.worlds.add-server": {
"message": "Voeg server toe"
},
"app.instance.worlds.browse-servers": {
"message": "Zoek servers"
},
"app.instance.worlds.delete-world-description": {
"message": "{name} Zal **permanent verwijderd** worden en kan niet hersteld worden."
},
"app.instance.worlds.delete-world-title": {
"message": "Weet je zeker dat je deze wereld definitief wilt verwijderen?"
},
"app.instance.worlds.filter-modded": {
"message": "Gemod"
},
"app.instance.worlds.filter-offline": {
"message": "Offline"
},
"app.instance.worlds.filter-online": {
"message": "Online"
},
"app.instance.worlds.filter-vanilla": {
"message": "Vanilla"
},
"app.instance.worlds.no-worlds-description": {
"message": "Voeg of zoek een server om te beginnen"
},
"app.instance.worlds.no-worlds-heading": {
"message": "Noch servers noch werelden toegevoegd"
},
"app.instance.worlds.remove-server-description": {
"message": "'{name}' wordt uit je lijst verwijderd, ook in de game, en kan op geen enkele manier worden hersteld."
},
"app.instance.worlds.remove-server-description-with-address": {
"message": "'{name}' ({address}) wordt uit je lijst verwijderd, ook in de game, en kan op geen enkele manier worden hersteld."
},
"app.instance.worlds.remove-server-title": {
"message": "Ben je zeker dat je {name} wil verwijderen?"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Zoek werelden"
},
"app.instance.worlds.this-server": {
"message": "deze server"
},
"app.modal.install-to-play.content-required": {
"message": "Content vereist"
},
@@ -299,15 +98,6 @@
"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"
},
"app.project.install-context.back-to-browse": {
"message": "Terug naar browsen"
},
"app.project.install-context.install-content-to-instance": {
"message": "Installeer content naar instantie"
},
"app.settings.developer-mode-enabled": {
"message": "Ontwikkelaarsmodus ingeschakeld."
},
@@ -374,24 +164,6 @@
"app.update.reload-to-update": {
"message": "Herlaad om de update te installeren"
},
"app.world.server-modal.placeholder-address": {
"message": "voorbeeld.modrinth.gg"
},
"app.world.server-modal.select-an-option": {
"message": "Kies een keuze"
},
"app.world.world-item.incompatible-version": {
"message": "Incompatibele versie{version}"
},
"app.world.world-item.not-played-yet": {
"message": "Nog niet gespeeld"
},
"app.world.world-item.offline": {
"message": "Offline"
},
"app.world.world-item.players-online": {
"message": "{count} online"
},
"friends.action.add-friend": {
"message": "Voeg een vriend toe"
},
@@ -491,12 +263,6 @@
"instance.edit-world.title": {
"message": "Wereld bewerken"
},
"instance.files.adding-files": {
"message": "Bestanden toevoegen ({completed}/{total})"
},
"instance.files.save-as": {
"message": "Opslaan als..."
},
"instance.server-modal.address": {
"message": "Adres"
},
@@ -579,7 +345,7 @@
"message": "Uitgevoerd nadat het spel is afgesloten."
},
"instance.settings.tabs.hooks.post-exit.enter": {
"message": "Voer een opdracht na het afsluiten in..."
"message": "Voer na-afsluitcommando in..."
},
"instance.settings.tabs.hooks.pre-launch": {
"message": "Voor het opstarten"
@@ -645,7 +411,7 @@
"message": "De hoogte van het spelvenster wanneer opgestart."
},
"instance.settings.tabs.window.height.enter": {
"message": "Voer de lengte in..."
"message": "Vul hoogte in..."
},
"instance.settings.tabs.window.width": {
"message": "Breedte"
@@ -687,7 +453,7 @@
"message": "Je kan alleen direct de servers in springen in Minecraft Alpha 1.0.5+"
},
"instance.worlds.no_singleplayer_quick_play": {
"message": "Je kan alleen direct je eigen werelden in springen in Minecraft 1,20+"
"message": "Je kan alleen direct je eigen werelden in springen in Minecraft 1.20+"
},
"instance.worlds.play_instance": {
"message": "Speel instantie"
@@ -698,24 +464,6 @@
"instance.worlds.world_in_use": {
"message": "Wereld wordt gebruikt"
},
"minecraft-account.add-account": {
"message": "Voeg account toe"
},
"minecraft-account.label": {
"message": "Minecraft account"
},
"minecraft-account.not-signed-in": {
"message": "Niet ingelogd"
},
"minecraft-account.remove-account": {
"message": "Verwijder account"
},
"minecraft-account.select-account": {
"message": "Selecteer account"
},
"minecraft-account.sign-in": {
"message": "Log in bij Minecraft"
},
"search.filter.locked.instance": {
"message": "Aangeboden door de instantie"
},
@@ -739,26 +487,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "Loader is gegeven door de server"
},
"unknown-pack-warning-modal.body": {
"message": "Een bestand wordt alleen beoordeeld als het naar Modrinth is geüpload, ongeacht het bestandsformaat (inclusief .mrpack)."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "Toon deze waarschuwing niet opnieuw"
},
"unknown-pack-warning-modal.header": {
"message": "Bevestig installatie"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "Installeer toch"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "Malware wordt vaak verspreid via modpack-bestanden door ze te delen op platforms zoals Discord."
},
"unknown-pack-warning-modal.warning.body": {
"message": "We konden dit bestand niet vinden op Modrinth. We raden ten zeerste aan om alleen bestanden te installeren van bronnen die u vertrouwt."
},
"unknown-pack-warning-modal.warning.title": {
"message": "Waarschuwing voor onbekend bestand"
}
}
+13 -163
View File
@@ -1,114 +1,15 @@
{
"app.action-bar.downloading-java": {
"message": "Pobieranie Java {version}"
},
"app.action-bar.downloads": {
"message": "Pobrania"
},
"app.action-bar.hide-more-running-instances": {
"message": "Ukryj włączone instancje"
},
"app.action-bar.make-primary-instance": {
"message": "Ustaw jako główną instancję"
},
"app.action-bar.no-instances-running": {
"message": "Żadna instancja nie jest włączona"
},
"app.action-bar.offline": {
"message": "Offline"
},
"app.action-bar.primary-instance": {
"message": "Główna instancja"
},
"app.action-bar.show-more-running-instances": {
"message": "Pokaż więcej włączonych instancji"
},
"app.action-bar.stop-instance": {
"message": "Zatrzymaj instancję"
},
"app.action-bar.view-active-downloads": {
"message": "Pokaż aktualnie pobierane"
},
"app.action-bar.view-instance": {
"message": "Pokaż instancję"
},
"app.action-bar.view-logs": {
"message": "Pokaż logi"
},
"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."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Zaawansowane renderowanie"
},
"app.appearance-settings.color-theme.description": {
"message": "Wybierz preferowany motyw w Modrinth App."
},
"app.appearance-settings.color-theme.title": {
"message": "Motyw"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Ustaw stronę, która pojawia się po włączeniu launchera."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Strona główna"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Biblioteka"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Domyślna strona główna"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Wyłącza nazwę użytkownika na stronie skórek."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Schowaj nazwę"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Pokazuje ostatnie światy w sekcji \"Wskocz z powrotem do światów\" na stronie głównej."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Wskocz z powrotem do światów"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Minimalizuj launcher po włączeniu procesu Minecraft."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Minimalizuj launcher"
},
"app.appearance-settings.native-decorations.description": {
"message": "Używaj systemowej ramki okna (wymaga ponownego uruchomienia)."
},
"app.appearance-settings.native-decorations.title": {
"message": "Systemowe dekoracje"
},
"app.appearance-settings.select-option": {
"message": "Wybierz opcję"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Umożliwia przełączenie paska bocznego."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "Przełącz pasek boczny"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Jeżeli spróbujesz zainstalować plik Modrinth Pack (.mrpack) którego nie można znaleźć na Modrinth, poinformujemy cię o możliwym ryzyku, zanim go zainstalujesz."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "Ostrzegaj mnie przed instalowaniem nieznanych paczek modów"
},
"app.auth-servers.unreachable.body": {
"message": "Serwery uwierzytelniania Minecraft mogą aktualnie nie działać. Sprawdź swoje połączenie z internetem i spróbuj ponownie później."
},
"app.auth-servers.unreachable.header": {
"message": "Nie udało się połączyć się z serwerami uwierzytelniania"
},
"app.browse.add-servers-to-instance": {
"message": "Dodawanie serwera do instancji"
"app.browse.add-server-to-instance": {
"message": "Dodaj serwer do instancji"
},
"app.browse.add-to-an-instance": {
"message": "Dodaj do instancji"
"app.browse.add-servers-to-instance": {
"message": "Dodaj serwery do swojej instancji"
},
"app.browse.add-to-instance": {
"message": "Dodaj do instancji"
@@ -122,9 +23,6 @@
"app.browse.already-added": {
"message": "Już dodano"
},
"app.browse.back-to-instance": {
"message": "Powrót do instancji"
},
"app.browse.discover-content": {
"message": "Odkrywaj zawartość"
},
@@ -132,19 +30,13 @@
"message": "Odkryj serwery"
},
"app.browse.hide-added-servers": {
"message": "Ukryj już dodane serwery"
"message": "Ukryj dodane serwery"
},
"app.browse.project-type.modpacks": {
"message": "Paczki modów"
"app.browse.hide-installed-content": {
"message": "Ukryj zainstalowane zasoby"
},
"app.browse.server.installing": {
"message": "Instalowanie"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Instalowanie paczki modów..."
"app.browse.install-content-to-instance": {
"message": "Zainstaluj zasoby do instancji"
},
"app.export-modal.description-placeholder": {
"message": "Wprowadź opis paczki modów..."
@@ -161,6 +53,9 @@
"app.export-modal.modpack-name-placeholder": {
"message": "Nazwa paczki modów"
},
"app.export-modal.select-files-label": {
"message": "Wybierz pliki i foldery, które mają znaleźć się w paczce"
},
"app.export-modal.version-number-label": {
"message": "Numer wersji"
},
@@ -216,7 +111,7 @@
"message": "Szukaj serwerów"
},
"app.instance.worlds.delete-world-description": {
"message": "'{name}' zostanie **permanentnie usunięty** i nie ma możliwości go odzyskać."
"message": "'{name}' zostanie **permanentnie usunięty**, i nie ma możliwości go odzyskać."
},
"app.instance.worlds.delete-world-title": {
"message": "Czy na pewno chcesz trwale usunąć ten świat?"
@@ -290,15 +185,6 @@
"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"
},
"app.project.install-context.back-to-browse": {
"message": "Powrót do przeglądania"
},
"app.project.install-context.install-content-to-instance": {
"message": "Zainstaluj zasoby do instancji"
},
"app.settings.developer-mode-enabled": {
"message": "Tryb dewelopera włączony."
},
@@ -689,21 +575,6 @@
"instance.worlds.world_in_use": {
"message": "Świat jest w użytku"
},
"minecraft-account.add-account": {
"message": "Dodaj konto"
},
"minecraft-account.label": {
"message": "Konto Minecraft"
},
"minecraft-account.remove-account": {
"message": "Usuń konto"
},
"minecraft-account.select-account": {
"message": "Wybierz konto"
},
"minecraft-account.sign-in": {
"message": "Zaloguj się do Minecraft"
},
"search.filter.locked.instance": {
"message": "Podane przez instancję"
},
@@ -727,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "Loader jest dostarczony przez serwer"
},
"unknown-pack-warning-modal.body": {
"message": "Plik jest sprawdzony tylko, jeżeli został przesłany na Modrinth, niezależnie od formatu (w tym pliki .mrpack)."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "Nie pokazuj ponownie"
},
"unknown-pack-warning-modal.header": {
"message": "Potwierdź instalację"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "Instaluj mimo to"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "Wirusy są często kryte w plikach paczek modów przesyłanych na platformach takich jak Discord."
},
"unknown-pack-warning-modal.warning.body": {
"message": "Nie mogliśmy znaleźć tego pliku na Modrinth. Stanowczo zalecamy instalowanie plików tylko ze źródeł, którym ufasz."
},
"unknown-pack-warning-modal.warning.title": {
"message": "Ostrzeżenie o nieznanym pliku"
}
}
+14 -176
View File
@@ -1,114 +1,15 @@
{
"app.action-bar.downloading-java": {
"message": "Baixando java {version}"
},
"app.action-bar.downloads": {
"message": "Downloads"
},
"app.action-bar.hide-more-running-instances": {
"message": "Ocultar mais instâncias em execução"
},
"app.action-bar.make-primary-instance": {
"message": "Criar instância primária"
},
"app.action-bar.no-instances-running": {
"message": "Nenhuma instância em execução"
},
"app.action-bar.offline": {
"message": "Offline"
},
"app.action-bar.primary-instance": {
"message": "Instância primária"
},
"app.action-bar.show-more-running-instances": {
"message": "Mostrar mais instâncias em execução"
},
"app.action-bar.stop-instance": {
"message": "Parar instância"
},
"app.action-bar.view-active-downloads": {
"message": "Ver downloads ativos"
},
"app.action-bar.view-instance": {
"message": "Ver instância"
},
"app.action-bar.view-logs": {
"message": "Ver logs"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "Ativa a renderização avançada, como efeitos de desfoque que podem causar problemas de desempenho sem a renderização acelerada de hardware."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Renderização avançada"
},
"app.appearance-settings.color-theme.description": {
"message": "Selecione seu tema de cores preferido para o Modrinth App."
},
"app.appearance-settings.color-theme.title": {
"message": "Tema de Cores"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Alterar a página em que o launcher é aberto."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Início"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Biblioteca"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Página inicial padrão"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Desativa o nome acima do seu jogador na página de skins."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Ocultar nome"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Inclui mundos recentes na seçã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": "Minimize o launcher quando um processo do Minecraft for iniciado."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Minimizar launcher"
},
"app.appearance-settings.native-decorations.description": {
"message": "Usar molduras de janela do sistema (requer reiniciar o aplicativo)."
},
"app.appearance-settings.native-decorations.title": {
"message": "Decorações nativas"
},
"app.appearance-settings.select-option": {
"message": "Selecione uma opção"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Ativa a capacidade de alternar a visibilidade da barra lateral."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "Alternar barra lateral"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Se você tentar instalar um arquivo Modrinth Pack (.mrpack) que não esteja hospedado no Modrinth, garantiremos que você entenda os riscos antes de instalá-lo."
},
"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 podem estar indisponíveis no momento. Verifique sua conexão com a rede e tente novamente mais tarde."
"message": "Os servidores de autenticação do Minecraft podem estar indisponíveis no momento. Verifique sua conexão com a internet e tente novamente mais tarde."
},
"app.auth-servers.unreachable.header": {
"message": "Não foi possível acessar os servidores de autenticação"
},
"app.browse.add-servers-to-instance": {
"message": "Adicionando servidor à instância"
"app.browse.add-server-to-instance": {
"message": "Adicionar servidor à instância"
},
"app.browse.add-to-an-instance": {
"message": "Adicionar a uma instância"
"app.browse.add-servers-to-instance": {
"message": "Adicionar servidores à sua instância"
},
"app.browse.add-to-instance": {
"message": "Adicionar à instância"
@@ -122,9 +23,6 @@
"app.browse.already-added": {
"message": "Já adicionado"
},
"app.browse.back-to-instance": {
"message": "Voltar a instância"
},
"app.browse.discover-content": {
"message": "Descubra conteúdo"
},
@@ -132,25 +30,16 @@
"message": "Descubra servidores"
},
"app.browse.hide-added-servers": {
"message": "Ocultar servidores adicionados"
"message": "Ocultar servidores adicionados"
},
"app.browse.project-type.modpacks": {
"message": "Pacotes de mods"
"app.browse.hide-installed-content": {
"message": "Ocultar conteúdo instalado"
},
"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.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Instalando pacote de mods..."
"app.browse.install-content-to-instance": {
"message": "Instalar conteúdo na instância"
},
"app.export-modal.description-placeholder": {
"message": "Insira uma descrição para o pacote de mods..."
"message": "Insira a descrição do pacote de mods..."
},
"app.export-modal.export-button": {
"message": "Exportar"
@@ -158,9 +47,6 @@
"app.export-modal.header": {
"message": "Exportar pacote de mods"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Incluir \"{file}\"?"
},
"app.export-modal.modpack-name-label": {
"message": "Nome do pacote de mods"
},
@@ -168,7 +54,7 @@
"message": "Nome do pacote de mods"
},
"app.export-modal.select-files-label": {
"message": "Configure quais arquivos serão incluídos nessa exportação"
"message": "Selecione arquivos e pastas para incluir no pacote"
},
"app.export-modal.version-number-label": {
"message": "Número da versão"
@@ -216,7 +102,7 @@
"message": "Compartilhando conteúdo do pacote de mods\n\n\n \t\t\t\t\t\t\n \t\t\t\t\t\t\t\n \t\t\t\t\t\t\n \t\t\t\t\t\t"
},
"app.instance.mods.successfully-uploaded": {
"message": "Adicionado com sucesso"
"message": "Enviado com sucesso"
},
"app.instance.worlds.add-server": {
"message": "Adicionar servidor"
@@ -299,15 +185,6 @@
"app.modal.update-to-play.update-required-description": {
"message": "É necessária uma atualização 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"
},
"app.project.install-context.back-to-browse": {
"message": "Voltar ao explorar"
},
"app.project.install-context.install-content-to-instance": {
"message": "Instalar conteúdo para a instância"
},
"app.settings.developer-mode-enabled": {
"message": "Modo de desenvolvedor ativado."
},
@@ -687,7 +564,7 @@
"message": "Você só pode entrar diretamente em servidores a partir do Minecraft 1.0.5"
},
"instance.worlds.no_singleplayer_quick_play": {
"message": "Você só pode entrar diretamente em mundos de um jogador a partir do Minecraft 1.20+"
"message": "Você só pode entrar diretamente em mundos de um jogador a partir do Minecraft 1.20"
},
"instance.worlds.play_instance": {
"message": "Jogar na instância"
@@ -698,24 +575,6 @@
"instance.worlds.world_in_use": {
"message": "Mundo em uso"
},
"minecraft-account.add-account": {
"message": "Adicionar conta"
},
"minecraft-account.label": {
"message": "Conta do minecraft"
},
"minecraft-account.not-signed-in": {
"message": "Não conectado"
},
"minecraft-account.remove-account": {
"message": "Remover conta"
},
"minecraft-account.select-account": {
"message": "Selecionar conta"
},
"minecraft-account.sign-in": {
"message": "Faça login no Minecraft"
},
"search.filter.locked.instance": {
"message": "Fornecido pela instância"
},
@@ -739,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "O carregador é fornecido pelo servidor"
},
"unknown-pack-warning-modal.body": {
"message": "Um arquivo só é revisado se for enviado para o Modrinth, não importa o seu formato de arquivo (incluindo .mrpack)."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "Não mostrar este aviso novamente"
},
"unknown-pack-warning-modal.header": {
"message": "Confirmar instalação"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "Instalar mesmo assim"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "Malware é frequentemente distribuído através de arquivos de pacotes de mods compartilhados em plataformas como o Discord."
},
"unknown-pack-warning-modal.warning.body": {
"message": "Não foi possível encontrar este arquivo no Modrinth. Recomendamos fortemente que você instale apenas arquivos de fontes confiáveis."
},
"unknown-pack-warning-modal.warning.title": {
"message": "Aviso de arquivo desconhecido"
}
}
@@ -5,6 +5,12 @@
"app.auth-servers.unreachable.header": {
"message": "Não foi possível alcançar os servidores de autenticação"
},
"app.browse.add-server-to-instance": {
"message": "Adicionar servidor à instância"
},
"app.browse.add-servers-to-instance": {
"message": "Adicionar servidores à tua instância"
},
"app.browse.add-to-instance": {
"message": "Adicionar à instância"
},
@@ -23,6 +29,15 @@
"app.browse.discover-servers": {
"message": "Descobrir servidores"
},
"app.browse.hide-added-servers": {
"message": "Esconder servidores adicionados"
},
"app.browse.hide-installed-content": {
"message": "Esconder conteúdo instalado"
},
"app.browse.install-content-to-instance": {
"message": "Instalar conteúdo à instância"
},
"app.export-modal.description-placeholder": {
"message": "Insere a descrição do modpack..."
},
@@ -38,6 +53,9 @@
"app.export-modal.modpack-name-placeholder": {
"message": "Nome do Modpack"
},
"app.export-modal.select-files-label": {
"message": "Seleciona as pastas e ficheiros a incluir no pack"
},
"app.export-modal.version-number-label": {
"message": "Número da versão"
},
@@ -107,9 +107,6 @@
"app.update.reload-to-update": {
"message": "Reîncarcă pentru a instala actualizarea"
},
"app.world.server-modal.select-an-option": {
"message": "Selectează o opțiune"
},
"friends.action.add-friend": {
"message": "Adaugă un prieten"
},
+34 -196
View File
@@ -1,115 +1,16 @@
{
"app.action-bar.downloading-java": {
"message": "Скачивание Java {version}"
},
"app.action-bar.downloads": {
"message": "Скачивания"
},
"app.action-bar.hide-more-running-instances": {
"message": "Скрыть другие активные сборки"
},
"app.action-bar.make-primary-instance": {
"message": "Сделать основной сборкой"
},
"app.action-bar.no-instances-running": {
"message": "Нет активных сборок"
},
"app.action-bar.offline": {
"message": "Офлайн"
},
"app.action-bar.primary-instance": {
"message": "Основная сборка"
},
"app.action-bar.show-more-running-instances": {
"message": "Показать другие активные сборки"
},
"app.action-bar.stop-instance": {
"message": "Остановить сборку"
},
"app.action-bar.view-active-downloads": {
"message": "Посмотреть текущие скачивания"
},
"app.action-bar.view-instance": {
"message": "Посмотреть сборку"
},
"app.action-bar.view-logs": {
"message": "Посмотреть журнал"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "Включает продвинутые эффекты вроде размытия, но может снизить производительность на устройствах без аппаратного ускорения."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Расширенные эффекты"
},
"app.appearance-settings.color-theme.description": {
"message": "Выберите тему для Modrinth App."
},
"app.appearance-settings.color-theme.title": {
"message": "Тема"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Страница, которая открывается при запуске лаунчера."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Главная"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Библиотека"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Стартовая страница"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Скрывать имя над игроком на странице скинов."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Без имени над скином"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Показывать недавние миры в разделе «Jump back in» на главной."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Миры на главной"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Сворачивать окно лаунчера при запуске Minecraft."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Сворачивание лаунчера"
},
"app.appearance-settings.native-decorations.description": {
"message": "Использовать системную рамку окна (требуется перезапуск)."
},
"app.appearance-settings.native-decorations.title": {
"message": "Системное оформление"
},
"app.appearance-settings.select-option": {
"message": "Выберите вариант"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Показывать кнопку скрытия боковой панели."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "Переключатель боковой панели"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Предупреждать о рисках перед установкой файлов .mrpack, не размещённых на Modrinth."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "Предупреждение о сторонних сборках"
},
"app.auth-servers.unreachable.body": {
"message": "Серверы аутентификации Minecraft сейчас могут быть недоступны. Проверьте подключение к интернету и повторите попытку позже."
},
"app.auth-servers.unreachable.header": {
"message": "Нет связи с серверами аутентификации"
},
"app.browse.add-server-to-instance": {
"message": "Добавить сервер в сборку"
},
"app.browse.add-servers-to-instance": {
"message": "Добавление серверов в сборку"
},
"app.browse.add-to-an-instance": {
"message": "Добавить в сборку"
},
"app.browse.add-to-instance": {
"message": "Добавить в сборку"
},
@@ -122,9 +23,6 @@
"app.browse.already-added": {
"message": "Уже добавлено"
},
"app.browse.back-to-instance": {
"message": "Вернуться к сборке"
},
"app.browse.discover-content": {
"message": "Поиск проектов"
},
@@ -134,20 +32,11 @@
"app.browse.hide-added-servers": {
"message": "Скрывать добавленные"
},
"app.browse.project-type.modpacks": {
"message": "Сборки"
"app.browse.hide-installed-content": {
"message": "Скрывать установленные"
},
"app.browse.server-instance-content-warning": {
"message": "Добавление контента может нарушить совместимость при подключении к серверу. Также весь добавленный контент будет удалён при обновлении содержимого серверной сборки."
},
"app.browse.server.installing": {
"message": "Установка"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Установка сборки..."
"app.browse.install-content-to-instance": {
"message": "Установить контент в сборку"
},
"app.export-modal.description-placeholder": {
"message": "Введите описание сборки..."
@@ -156,10 +45,7 @@
"message": "Экспортировать"
},
"app.export-modal.header": {
"message": "Экспорт сборки"
},
"app.export-modal.include-file-accessibility-label": {
"message": "Добавить «{file}» в экспорт?"
"message": "Экспорт сборки модов"
},
"app.export-modal.modpack-name-label": {
"message": "Название сборки"
@@ -168,7 +54,7 @@
"message": "Название сборки"
},
"app.export-modal.select-files-label": {
"message": "Выберите файлы для экспорта"
"message": "Выберите файлы или папки для включения в сборку"
},
"app.export-modal.version-number-label": {
"message": "Номер версии"
@@ -177,10 +63,10 @@
"message": "1.0.0"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Все данные сборки будут удалены навсегда, в том числе миры, настройки и весь установленный контент."
"message": "Все данные вашей инстанции будут окончательно удалены, включая ваши миры, настройки и весь установленный контент."
},
"app.instance.confirm-delete.admonition-header": {
"message": "Это действие необратимо"
"message": "Это действие нельзя обратить"
},
"app.instance.confirm-delete.delete-button": {
"message": "Удалить сборку"
@@ -189,13 +75,13 @@
"message": "Удаление сборки"
},
"app.instance.modpack-already-installed.body": {
"message": "Выбранное содержимое уже установлено в сборке <bold>{instanceName}</bold>. Создать копию?"
"message": "Эта сборка модов уже установлена в сборку <bold>{instanceName}</bold>. Вы уверены, что хотите дублировать её?"
},
"app.instance.modpack-already-installed.create": {
"message": "Создать"
},
"app.instance.modpack-already-installed.header": {
"message": "Содержимое уже установлено"
"message": "Сборка модов уже установлена"
},
"app.instance.modpack-already-installed.instance": {
"message": "Сборка"
@@ -204,13 +90,13 @@
"message": "проект"
},
"app.instance.mods.project-was-added": {
"message": "«{name}» добавлен"
"message": "\"{name}\" был добавлен"
},
"app.instance.mods.projects-were-added": {
"message": "{count, plural, one {Добавлен # проект} few {Добавлено # проекта} other {Добавлено # проектов}}"
"message": "Проектов добавлено: {count}"
},
"app.instance.mods.share-text": {
"message": "Что в моей сборке:"
"message": "Посмотрите проекты, которые я использую в своей сборке модов!"
},
"app.instance.mods.share-title": {
"message": "Содержимое сборки"
@@ -225,13 +111,13 @@
"message": "Найти серверы"
},
"app.instance.worlds.delete-world-description": {
"message": "«{name}» будет **удалён навсегда**. Его невозможно восстановить."
"message": "'{name}' будет **удалён навсегда**, и будет невозможно восстановить."
},
"app.instance.worlds.delete-world-title": {
"message": "Вы действительно хотите удалить этот мир?"
"message": "Вы уверены, что хотите удалить этот мир навсегда?"
},
"app.instance.worlds.filter-modded": {
"message": "Модовые"
"message": "Со сборкой"
},
"app.instance.worlds.filter-offline": {
"message": "Не в сети"
@@ -240,28 +126,28 @@
"message": "В сети"
},
"app.instance.worlds.filter-vanilla": {
"message": "Ванильные"
"message": "Не модифицировано"
},
"app.instance.worlds.no-worlds-description": {
"message": "Добавьте или найдите сервер"
"message": "Добавить сервер или найти, чтобы начать"
},
"app.instance.worlds.no-worlds-heading": {
"message": "Нет серверов и миров"
"message": "Сервера или мира не добавлены"
},
"app.instance.worlds.remove-server-description": {
"message": "«{name}» будет удалён из списка — в том числе в игре. Его невозможно восстановить."
"message": "'{name}' будет удален из вашего списка, включая в игре, и восстановить будет невозможно."
},
"app.instance.worlds.remove-server-description-with-address": {
"message": "«{name}» ({address}) будет удалён из списка — в том числе в игре. Его невозможно восстановить."
"message": "'{name}' ({address}) будет удален из вашего списка, включая в игре, и восстановить будет невозможно."
},
"app.instance.worlds.remove-server-title": {
"message": "Вы действительно хотите удалить {name}?"
"message": "Вы уверены, что хотите удалить {name}?"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Поиск по {count, plural, one {# миру} other {# мирам}}..."
},
"app.instance.worlds.this-server": {
"message": "этот сервер"
"message": "Этот сервер"
},
"app.modal.install-to-play.content-required": {
"message": "Требуется дополнительный контент"
@@ -288,7 +174,7 @@
"message": "Общая сборка сервера"
},
"app.modal.install-to-play.view-contents": {
"message": "Посмотреть содержимое"
"message": "Посмотреть"
},
"app.modal.update-to-play.header": {
"message": "Обновление перед запуском"
@@ -299,15 +185,6 @@
"app.modal.update-to-play.update-required-description": {
"message": "Обновите {name} до последней версии, чтобы запустить игру."
},
"app.project.install-button.already-installed": {
"message": "Этот проект уже установлен"
},
"app.project.install-context.back-to-browse": {
"message": "Вернуться к поиску"
},
"app.project.install-context.install-content-to-instance": {
"message": "Установка контента в сборку"
},
"app.settings.developer-mode-enabled": {
"message": "Режим разработчика включён."
},
@@ -384,7 +261,7 @@
"message": "Несовместимая версия {version}"
},
"app.world.world-item.not-played-yet": {
"message": "Не запускалось"
"message": "Ещё не играли"
},
"app.world.world-item.offline": {
"message": "Не в сети"
@@ -414,7 +291,7 @@
"message": "Какое имя у друга на Modrinth?"
},
"friends.add-friends-to-share": {
"message": "<link>Добавьте друзей</link> и следите за ними!"
"message": "<link>Добавьте друзей</link>, чтобы видеть, во что они играют!"
},
"friends.friend.cancel-request": {
"message": "Отменить запрос"
@@ -453,7 +330,7 @@
"message": "{title} — {count}"
},
"friends.sign-in-to-add-friends": {
"message": "<link>Войдите в аккаунт Modrinth</link>, чтобы добавлять друзей и следить за ними!"
"message": "<link>Войдите в аккаунт Modrinth</link>, чтобы добавлять друзей и видеть, во что они играют!"
},
"instance.add-server.add-and-play": {
"message": "Добавить и играть"
@@ -492,7 +369,7 @@
"message": "Настройка мира"
},
"instance.files.adding-files": {
"message": "Добавление файлов ({completed, number}/{total, number})"
"message": "Добавление файлов ({completed}/{total})"
},
"instance.files.save-as": {
"message": "Сохранить как..."
@@ -519,7 +396,7 @@
"message": "Удалить сборку"
},
"instance.settings.tabs.general.delete.description": {
"message": "Навсегда удаляет сборку с устройства, в том числе миры, настройки и весь установленный контент. Учтите, что после удаления сборки её невозможно восстановить."
"message": "Навсегда удаляет сборку с вашего устройства, включая миры, настройки и весь установленный контент. Учтите, что после удаления сборки восстановить её будет невозможно."
},
"instance.settings.tabs.general.deleting.button": {
"message": "Удаление..."
@@ -555,7 +432,7 @@
"message": "Создать новую группу"
},
"instance.settings.tabs.general.library-groups.description": {
"message": "Позволяет организовать сборки по разным разделам в библиотеке."
"message": "Разделение по группам позволяет организовать сборки по разным разделам в библиотеке."
},
"instance.settings.tabs.general.library-groups.enter-name": {
"message": "Введите название группы"
@@ -698,24 +575,6 @@
"instance.worlds.world_in_use": {
"message": "Мир используется"
},
"minecraft-account.add-account": {
"message": "Добавить"
},
"minecraft-account.label": {
"message": "Учётная запись Minecraft"
},
"minecraft-account.not-signed-in": {
"message": "Вход не выполнен"
},
"minecraft-account.remove-account": {
"message": "Удалить"
},
"minecraft-account.select-account": {
"message": "Выберите профиль"
},
"minecraft-account.sign-in": {
"message": "Войти в Minecraft"
},
"search.filter.locked.instance": {
"message": "Управляется сборкой"
},
@@ -732,33 +591,12 @@
"message": "Управляется сервером"
},
"search.filter.locked.server-environment.title": {
"message": "В серверной сборке доступны только клиентские моды"
"message": "В серверную сборку можно добавлять только моды для клиента"
},
"search.filter.locked.server-game-version.title": {
"message": "Версия игры управляется сервером"
},
"search.filter.locked.server-loader.title": {
"message": "Загрузчик управляется сервером"
},
"unknown-pack-warning-modal.body": {
"message": "Файлы любого формата проверены на безопасность, если они загружены на Modrinth (в том числе файлы⠀.mrpack)."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "Больше не предупреждать"
},
"unknown-pack-warning-modal.header": {
"message": "Подтверждение установки"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "Всё равно установить"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "Вредоносное ПО часто распространяется через сборки на таких платформах, как Discord."
},
"unknown-pack-warning-modal.warning.body": {
"message": "Этот файл не найден на Modrinth. Рекомендуется скачивать файлы только из надёжных источников."
},
"unknown-pack-warning-modal.warning.title": {
"message": "Предупреждение о неизвестном файле"
}
}
@@ -1,136 +1,16 @@
{
"app.auth-servers.unreachable.body": {
"message": "Minecraft serveri za autentifikaciju su možda trenutno nedostupni. Molimo vas da proverite vašu internet vezu i pokušajte ponovo kasnije."
},
"app.auth-servers.unreachable.header": {
"message": "Serveri za autentifikaciju su nedostupni"
},
"app.browse.add-to-instance": {
"message": "Dodaj na instancu"
},
"app.browse.add-to-instance-name": {
"message": "Dodaj na {instanceName}"
},
"app.browse.added": {
"message": "Dodato"
},
"app.browse.already-added": {
"message": "Već je dodato"
},
"app.browse.discover-content": {
"message": "Otkrij sadržaj"
},
"app.browse.discover-servers": {
"message": "Otkrij servere"
},
"app.export-modal.description-placeholder": {
"message": "Ukucaj opis modpacka..."
},
"app.export-modal.export-button": {
"message": "Izvoz"
},
"app.export-modal.header": {
"message": "Izvezi modpack"
},
"app.export-modal.modpack-name-label": {
"message": "Ime Modpacka"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Ime modpacka"
},
"app.export-modal.version-number-label": {
"message": "Broj verzije"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.instance.confirm-delete.admonition-body": {
"message": "Svi podaci za tvoju instancu će biti trajno izbrisani, uključujući tvoje svetove, konfiguracije, i sav instaliran sadržaj."
},
"app.instance.confirm-delete.admonition-header": {
"message": "Ova akcija ne može biti poništena"
},
"app.instance.confirm-delete.delete-button": {
"message": "Izbriši instancu"
},
"app.instance.confirm-delete.header": {
"message": "Izbriši instancu"
},
"app.instance.modpack-already-installed.body": {
"message": "Ovaj modpack je već instaliran u <bold>{instanceName}</bold> instancu. Da li ste sigurni da želite da je duplirate?"
},
"app.instance.modpack-already-installed.create": {
"message": "Napravi"
},
"app.instance.modpack-already-installed.header": {
"message": "Modpack je već instaliran"
},
"app.instance.modpack-already-installed.instance": {
"message": "Instanca"
},
"app.instance.mods.content-type-project": {
"message": "projekat"
},
"app.instance.mods.project-was-added": {
"message": "\"{name}\" je dodato"
},
"app.instance.mods.projects-were-added": {
"message": "{count} projekata je dodato"
},
"app.instance.mods.share-text": {
"message": "Pogledaj ove projekte koje ja koristim u svom modpacku!"
},
"app.instance.mods.share-title": {
"message": "Deljenje sadržaja modpacka"
},
"app.instance.mods.successfully-uploaded": {
"message": "Uspešno otpremljeno"
},
"app.instance.worlds.add-server": {
"message": "Dodaj server"
},
"app.instance.worlds.browse-servers": {
"message": "Pretraži servere"
},
"app.instance.worlds.delete-world-description": {
"message": "'{name}' će biti **trajno izbrisan**, i neće biti načina da se vrati."
},
"app.instance.worlds.delete-world-title": {
"message": "Da li ste sigurni da hoćete da trajno izbrišete ovaj svet?"
},
"app.instance.worlds.filter-modded": {
"message": "Modifikovano"
},
"app.instance.worlds.filter-offline": {
"message": "Oflajn"
},
"app.instance.worlds.filter-online": {
"message": "Onlajn"
},
"app.instance.worlds.filter-vanilla": {
"message": "Vanila"
},
"app.instance.worlds.no-worlds-description": {
"message": "Dodaj server ili pretraži da bi započeo"
},
"app.instance.worlds.no-worlds-heading": {
"message": "Nema dodatih servera niti svetova"
},
"app.instance.worlds.remove-server-description": {
"message": "'{name}' će biti izbrisan sa vaše liste, uključujući i unutar igre, i neće biti načina da se oporavi."
},
"app.instance.worlds.remove-server-description-with-address": {
"message": "'{name}' ({address}) će biti izbrisan sa vaše liste, uključujući i unutar igre, i neće biti načina da se oporavi."
},
"app.instance.worlds.remove-server-title": {
"message": "Da li ste sigurni da hoćete da izbrišete {name}?"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Pretraži {count} svetova..."
},
"app.instance.worlds.this-server": {
"message": "ovaj server"
},
"app.settings.tabs.appearance": {
"message": "Izgled"
},
+19 -19
View File
@@ -1,22 +1,16 @@
{
"app.action-bar.downloading-java": {
"message": "Laddar ner Java {version}"
},
"app.action-bar.downloads": {
"message": "Nedladdningar"
},
"app.action-bar.offline": {
"message": "Offline"
},
"app.appearance-settings.color-theme.title": {
"message": "Färgtema"
},
"app.auth-servers.unreachable.body": {
"message": "Minecrafts autentiseringsservrar kan vara nere just nu. Kontrollera din internetanslutning och försök igen senare."
},
"app.auth-servers.unreachable.header": {
"message": "Kan ej nå autentiseringsservrarna"
},
"app.browse.add-server-to-instance": {
"message": "Lägg till server till instans"
},
"app.browse.add-servers-to-instance": {
"message": "Lägg till servrar till din instans"
},
"app.browse.add-to-instance": {
"message": "Lägg till i instans"
},
@@ -35,11 +29,14 @@
"app.browse.discover-servers": {
"message": "Upptäck servrar"
},
"app.browse.project-type.modpacks": {
"message": "Modpaket"
"app.browse.hide-added-servers": {
"message": "Dölj tillagda servrar"
},
"app.browse.server.installing": {
"message": "Installerar"
"app.browse.hide-installed-content": {
"message": "Dölj installerat innehåll"
},
"app.browse.install-content-to-instance": {
"message": "Installera innehåll till instans"
},
"app.export-modal.description-placeholder": {
"message": "Ange modpaketets beskrivning..."
@@ -56,6 +53,9 @@
"app.export-modal.modpack-name-placeholder": {
"message": "Modpaketets namn"
},
"app.export-modal.select-files-label": {
"message": "Välj filer och mappar att inkludera i paketet"
},
"app.export-modal.version-number-label": {
"message": "Versionsnummer"
},
@@ -111,13 +111,13 @@
"message": "Utforska servrar"
},
"app.instance.worlds.delete-world-description": {
"message": "'{name}' kommer ** tas bort permanent**, och det kommer inte finnas något sätt att återskapa den."
"message": "'{name}' kommer bli **permanent borttagen**, och det kommer inte finnas något sätt att återskapa den."
},
"app.instance.worlds.delete-world-title": {
"message": "Är du säker på att du vill permanent radera denna värld?"
},
"app.instance.worlds.filter-modded": {
"message": "Moddad"
"message": "Moddade"
},
"app.instance.worlds.filter-offline": {
"message": "Offline"
@@ -231,7 +231,7 @@
"message": "Nedladdning slutförd"
},
"app.update-popup.reload": {
"message": "Ladda om"
"message": "Kolla efter uppdateringar"
},
"app.update-popup.title": {
"message": "Uppdatering tillgänglig"
+65 -326
View File
@@ -1,192 +1,42 @@
{
"app.action-bar.downloading-java": {
"message": "ดาวน์โหลดเวอร์ชัน Java {version}"
},
"app.action-bar.downloads": {
"message": "ดาวน์โหลด"
},
"app.action-bar.hide-more-running-instances": {
"message": "ซ่อนการดำเนินการโปรแกรมเบื้องหลัง"
},
"app.action-bar.make-primary-instance": {
"message": "กำหนดโปรแกรมหลัก"
},
"app.action-bar.no-instances-running": {
"message": "ไม่มีโปรแกรมใดดำเนินการ"
},
"app.action-bar.offline": {
"message": "ออฟไลน์"
},
"app.action-bar.primary-instance": {
"message": "โปรแกรมหลัก"
},
"app.action-bar.show-more-running-instances": {
"message": "แสดงการดำเนินการโปรแกรมเบื้องหลังเพิ่มเติม"
},
"app.action-bar.stop-instance": {
"message": "หยุดการทำงานโปรแกรม"
},
"app.action-bar.view-active-downloads": {
"message": "ดูยอดการดาวน์โหลดที่ยังใช้งาน"
},
"app.action-bar.view-instance": {
"message": "ดูโปรแกรม"
},
"app.action-bar.view-logs": {
"message": "ดู Log"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "เปิดการใช้งานการเรนเดอร์ขั้นสูง เช่น เอฟเฟคการเบลอ อาจทำให้เกมเกิดปัญหาด้านประสิทธิภาพได้หากไม่มีอุปกรณ์ฮาร์ดแวร์ที่สามารถรองรับการเรนเดอร์ได้"
},
"app.appearance-settings.advanced-rendering.title": {
"message": "การเรนเดอร์ขั้นสูง"
},
"app.appearance-settings.color-theme.description": {
"message": "เลือกธีมสีที่คุณชื่นชอบสำหรับ Modrinth บนอุปกรณ์นี้"
},
"app.appearance-settings.color-theme.title": {
"message": "ธีมสี"
},
"app.appearance-settings.default-landing-page.description": {
"message": "เปลี่ยนหน้าไปหน้าต่างที่ลันเชอร์เปิดขึ้นมา"
},
"app.appearance-settings.default-landing-page.home": {
"message": "หน้าหลัก"
},
"app.appearance-settings.default-landing-page.library": {
"message": "รายการ"
},
"app.appearance-settings.default-landing-page.title": {
"message": "หน้าเริ่มต้น"
},
"app.appearance-settings.hide-nametag.description": {
"message": "ปิดป้ายชื่อบนศีรษะของผู้เล่นในหน้าแสดงสกิน"
},
"app.appearance-settings.hide-nametag.title": {
"message": "ซ่อนป้ายชื่อ"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "การแสดงผลโลกล่าสุดที่ผู้เล่นเล่นในส่วน \"กระโดดกลับเข้าไป\" ในหน้าหลัก"
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "กระโดดกลับเข้าไปในโลก"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "ย่อลันเชอร์เมื่อกระบวนการการรัน Minecraft เริ่มต้นแล้ว"
},
"app.appearance-settings.minimize-launcher.title": {
"message": "ย่อลันเชอร์"
},
"app.appearance-settings.native-decorations.description": {
"message": "ใช้ระบบกรอบหน้าต่าง (ต้องการการรีสตาร์ทโปรแกรมใหม่)"
},
"app.appearance-settings.native-decorations.title": {
"message": "ของตกแต่งดั้งเดิม"
},
"app.appearance-settings.select-option": {
"message": "เลือกตัวเลิือก"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "เปิดใช้งานตัวเลือกในการเลือกย่อหรือขยายแถบด้านข้าง"
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "ย่อแถบด้านข้าง"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "หากคุณกำลังติดตั้งไฟล์แพ็กของ Modrinth (.mrpack) ที่ไม่ได้โฮสต์โดยตรงบน Modrinth เราจะแจ้งให้คุณตรวจสอบให้มั่นใจก่อนที่จะติดตั้งไฟล์แพ็กดังกล่าว"
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "เตือนฉันก่อนติดตั้งแพ็กม็อดที่ไม่รู้จัก"
},
"app.auth-servers.unreachable.body": {
"message": "เซิร์ฟเวอร์ตรวจสอบสิทธิ์ของ Minecraft อาจใช้งานไม่ได้ในขณะนี้ โปรดตรวจสอบการเชื่อมต่ออินเทอร์เน็ตของคุณและลองใหม่อีกครั้งในภายหลัง"
},
"app.auth-servers.unreachable.header": {
"message": "ไม่สามารถเชื่อมต่อถึงเซิร์ฟเวอร์ได้"
},
"app.browse.add-to-instance": {
"message": "เพิ่มลงในโปรแกรม"
},
"app.browse.add-to-instance-name": {
"message": "เพิ่มลงใน {instanceName}"
"app.browse.add-server-to-instance": {
"message": "เพิ่มเซิร์ฟเวอร์ลงในอินสแตนซ์"
},
"app.browse.added": {
"message": "เพิ่ม"
},
"app.browse.already-added": {
"message": "เพิ่มแล้ว"
},
"app.browse.discover-content": {
"message": "สำรวจเนื้อหา"
},
"app.browse.discover-servers": {
"message": "สำรวจเซิร์ฟเวอร์"
},
"app.browse.hide-added-servers": {
"message": "ซ่อนเซิร์ฟเวอร์ที่ดำเนินการเพิ่มแล้ว"
},
"app.browse.project-type.modpacks": {
"message": "แพ็กม็อด"
},
"app.browse.server.installing": {
"message": "กำลังติดตั้ง"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "กำลังติดตั้งแพ็กม็อด..."
},
"app.export-modal.description-placeholder": {
"message": "กรอกคำอธิบายมอดแพ็ก.."
},
"app.export-modal.export-button": {
"message": "ส่งออก"
},
"app.export-modal.header": {
"message": "ส่งออกแพ็กม็อด"
},
"app.export-modal.include-file-accessibility-label": {
"message": "รวมถึง \"{file}\" ใช่หรือไม่"
},
"app.export-modal.modpack-name-label": {
"message": "ชื่อแพ็กม็อด"
},
"app.export-modal.modpack-name-placeholder": {
"message": "ชื่อแพ็กม็อด"
},
"app.export-modal.select-files-label": {
"message": "กำหนดไฟล์ที่ต้องการจะส่งออก"
},
"app.export-modal.version-number-label": {
"message": "หมายเลขเวอร์ชัน"
"message": "ชื่อมอดแพ็ก"
},
"app.export-modal.version-number-placeholder": {
"message": "1.0.0"
},
"app.instance.confirm-delete.admonition-body": {
"message": "ข้อมูลทั้งหมดที่ถูกเก็บไว้ในโปรแกรมจะถูกลบออกอย่างถาวร รวมถึงโลก การตั้งค่า และเนื้อหาอื่นที่ติดตั้งไว้ทั้งหมด"
"message": "ข้อมูลทั้งหมดในอินสแตนซ์ของคุณจะถูกลบอย่างถาวร รวมถึงโลก การตั้งค่า และเนื้อหาที่ติดตั้งไว้ทั้งหมด"
},
"app.instance.confirm-delete.admonition-header": {
"message": "การดำเนินการนี้ไม่สามารถย้อนคืนได้"
},
"app.instance.confirm-delete.delete-button": {
"message": "ลบโปรแกรม"
},
"app.instance.confirm-delete.header": {
"message": "ลบโปรแกรม"
"message": "ลบอินสแตนซ์"
},
"app.instance.modpack-already-installed.body": {
"message": "แพ็กม็อดดังกล่าวติดตั้งไว้ใน <bold>{instanceName}</bold> อยู่แล้ว คุณแน่ใจหรือไม่ว่าต้องการจะทำซ้ำ?"
"message": "มอดแพ็กนี้ถูกติดตั้งไว้ในอินสแตนซ์ <bold>{instanceName}</bold> อยู่แล้ว คุณแน่ใจหรือไม่ว่าต้องการสร้างสำเนาซ้ำ?"
},
"app.instance.modpack-already-installed.create": {
"message": "สร้าง"
},
"app.instance.modpack-already-installed.header": {
"message": "แพ็กม็อดดังกล่าวถูกติดตั้งไปแล้ว"
"message": "ติดตั้งมอดแพ็กนี้อยู่แล้ว"
},
"app.instance.modpack-already-installed.instance": {
"message": "โปรแกรม"
"message": "อินสแตนซ์"
},
"app.instance.mods.content-type-project": {
"message": "โปรเจกต์"
@@ -198,28 +48,22 @@
"message": "เพิ่ม {count} โปรเจกต์เรียบร้อยแล้ว"
},
"app.instance.mods.share-text": {
"message": "มาตรวจดูโปรเจกต์ต่าง ๆ ที่ฉันใช้ในแพ็กม็อดนี้กัน!"
},
"app.instance.mods.share-title": {
"message": "แบ่งปันเนื้อหาแพ็กม็อด"
"message": "มาตรวจดูโปรเจกต์ต่าง ๆ ที่ฉันใช้ในมอดแพ็กนี้กัน!"
},
"app.instance.mods.successfully-uploaded": {
"message": "อัปโหลดสำเร็จ"
},
"app.instance.worlds.add-server": {
"message": "เพิ่มเซิร์ฟเวอร์"
},
"app.instance.worlds.browse-servers": {
"message": "ค้นหาเซิร์ฟเวอร์"
"message": "ค้นหาเซิฟเวอร์"
},
"app.instance.worlds.delete-world-description": {
"message": "'{name}' จะ**ถูกลบออกอย่างถาวร** และจะไม่มีทางสามารถกู้คืนได้"
"message": "'{name}' จะถูกลบอย่างถาวร** และจะไม่สามารถกู้คืนได้**"
},
"app.instance.worlds.delete-world-title": {
"message": "คุณแน่ใจหรือไม่ว่าต้องการลบโลกนี้อย่างถาวร?"
},
"app.instance.worlds.filter-modded": {
"message": "มอด"
"message": "แบบมีมอด"
},
"app.instance.worlds.filter-offline": {
"message": "ออฟไลน์"
@@ -228,31 +72,31 @@
"message": "ออนไลน์"
},
"app.instance.worlds.filter-vanilla": {
"message": "วานิลลา"
"message": "ต้นฉบับ"
},
"app.instance.worlds.no-worlds-description": {
"message": "เพิ่มเซิร์ฟเวอร์หรือค้นหาเพื่อเริ่มต้น"
"message": "เพิ่มเซิร์ฟเวอร์หรือสำรวจเพื่อเริ่มต้น"
},
"app.instance.worlds.no-worlds-heading": {
"message": "ไม่มีเซิร์ฟเวอร์หรือโลกที่เพิ่มไว้"
},
"app.instance.worlds.remove-server-description": {
"message": "'{name}' จะถูกลบออกจากรายการของคุณ ซึ่งจะรวมถึงในเกม และการลบดังกล่าวจะไม่มีทางกู้คืนได้อีก"
"message": "'{name}' จะถูกลบออกจากรายชื่อของคุณ รวมถึงในเกมด้วย และจะไม่สามารถกู้คืนได้"
},
"app.instance.worlds.remove-server-description-with-address": {
"message": "'{name}' ({address}) จะถูกลบออกจากรายการของคุณ ซึ่งจะรวมถึงในเกม และการลบดังกล่าวจะไม่มีทางกู้คืนได้อีก"
"message": "'{name}' ({address}) จะถูกลบออกจากรายชื่อของคุณ รวมถึงในเกมด้วย และจะไม่สามารถกู้คืนได้"
},
"app.instance.worlds.remove-server-title": {
"message": "คุณแน่ใจหรือไม่ว่าต้องการลบ {name}?"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "ค้หาโลกทั้งหมด {count} โลก"
"message": "ค้หา {count} โลก"
},
"app.instance.worlds.this-server": {
"message": "เซิร์ฟเวอร์นี้"
"message": "เซิร์ฟเวอร์อันนี้"
},
"app.modal.install-to-play.content-required": {
"message": "เนื้อหาที่จำเป็น"
"message": "จำเป็นต้องมีเนื้อหา"
},
"app.modal.install-to-play.header": {
"message": "ติดตั้งเพื่อเล่น"
@@ -260,23 +104,17 @@
"app.modal.install-to-play.install-button": {
"message": "ติดตั้ง"
},
"app.modal.install-to-play.mod-count": {
"message": "{count, plural, other {# ม็อด}}"
},
"app.modal.install-to-play.required-modpack": {
"message": "มอดแพ็กที่จำเป็น"
},
"app.modal.install-to-play.server-requires-mods": {
"message": "เซิร์ฟเวอร์ดังกล่าวจำเป็นต้องใช้มอดเพื่อเล่น โปรดติดตั้งและตั้งค่าไฟล์อื่นใดที่จำเป็นจาก Modrinth ก่อน จากนั้นึงจะสามารถเข้าเล่นเซิร์ฟเวอร์ได้"
"message": "เซิร์ฟเวอร์นี้จำเป็นต้องใช้มอดเพื่อเข้าเล่น คลิกติดตั้ง เพื่อตั้งค่าไฟล์ที่จำเป็นจาก Modrinth จากนั้นึงจะเข้าสู่เซิร์ฟเวอร์โดยตรงได้"
},
"app.modal.install-to-play.shared-instance": {
"message": "โปรแกรมที่มีร่วมกัน"
"message": "อินสแตนซ์ที่ใช้ร่วมกัน"
},
"app.modal.install-to-play.shared-server-instance": {
"message": "เซิร์ฟเวอร์ของโปรแกรมที่มีร่วมกัน"
},
"app.modal.install-to-play.view-contents": {
"message": "ดูเนื้อหา"
"message": "อินสแตนซ์เซิร์ฟเวอร์ที่ใช้ร่วมกัน"
},
"app.modal.update-to-play.header": {
"message": "อัปเดตเพื่อเล่น"
@@ -291,13 +129,13 @@
"message": "โหมดนักพัฒนาเปิดอยู่"
},
"app.settings.downloading": {
"message": "ดาวน์โหลดเวอร์ชัน {version}"
"message": "ดาวน์โหลด เวอร์ชัน{version}"
},
"app.settings.tabs.appearance": {
"message": "หน้าตา"
},
"app.settings.tabs.default-instance-options": {
"message": "ตั้งค่าโปรแกรมเริ่มต้น"
"message": "ตัวเลือกอินสแตนซ์เริ่มต้น"
},
"app.settings.tabs.java-installations": {
"message": "การจัดการ Java ที่ติดตั้ง"
@@ -311,29 +149,11 @@
"app.settings.tabs.resource-management": {
"message": "การจัดการทรัพยากร"
},
"app.update-popup.body": {
"message": "Modrinth v{version} พร้อมสำหรับการติดตั้งแล้ว! เปิดโปรแกรมใหม่อีกครั้งเพื่ออัปเดตตอนนี้ หรือจะรออัปเดตอัตโนมัติ ซึ่งจะเกิดขึ้นเมื่อคุณกดปิดโปรแกรม Modrinth"
},
"app.update-popup.body.download-complete": {
"message": "ดาวน์โหลด Modrinth v{version} สำเร็จแล้ว เปิดโปรแกรมใหม่อีกครั้งเพื่ออัปเดตตอนนี้ หรือจะรออัปเดตอัตโนมัติ ซึ่งจะเกิดขึ้นเมื่อคุณกดปิดโปรแกรม Modrinth"
},
"app.update-popup.body.linux": {
"message": "Modrinth v{version} พร้อมให้อัปเดตแล้ว โปรดไปที่การจัดการแพ็กเกจของคุณสำหรับการอัปเดตคุณสมบัติใหม่และการแก้ไข่าง ๆ"
},
"app.update-popup.body.metered": {
"message": "Modrinth v{version} พร้อมให้บริการแล้ว! แต่เนื่องจากคุณเปิดโหมดจำกัดปริมาณการใช้ข้อมูลเครือข่าย เราจึงไม่ได้อัปเดตเนื้อหาโดยอัตโนมัติ"
},
"app.update-popup.changelog": {
"message": "บันทึกการเปลี่ยนแปลง"
},
"app.update-popup.download": {
"message": "ดาวโหลด ({size})"
"message": "Modrinth App v{version} พร้อมให้อัปเดตแล้ว โปรดใช้ตัวจัดการแพ็กเกจ ของคุณเพื่ออัปเดตฟีเจอร์ใหม่และตัวแก้ไข่าสุด!"
},
"app.update-popup.download-complete": {
"message": "การดาวน์โหลดเสร็จสมบูรณ์"
},
"app.update-popup.reload": {
"message": "โหลดใหม่"
"message": "ดาวน์โหลดเสร็จสมบูรณ์"
},
"app.update-popup.title": {
"message": "มีการอัปเดตใหม่"
@@ -345,25 +165,19 @@
"message": "เวอร์ชั่น {version} ถูกติดตั้งแล้ว"
},
"app.update.download-update": {
"message": "ดาวน์โหลดอัเดต"
"message": "ดาวน์โหลดอัเดต"
},
"app.update.downloading-update": {
"message": "ดาวน์โหลดอัเดตไปแล้ว ({percent}%)"
"message": "ดาวน์โหลดอัเดตไปแล้ว ({percent}%)"
},
"app.update.reload-to-update": {
"message": "รีโหลดเพื่อติดตั้งอัเดต"
"message": "รีโหลดเพื่อติดตั้งอัเดต"
},
"app.world.server-modal.placeholder-address": {
"message": "example.modrinth.gg"
},
"app.world.server-modal.select-an-option": {
"message": "เลือกตัวเลือก"
},
"app.world.world-item.incompatible-version": {
"message": "ไม่สามารถเข้ากับเวอร์ชัน {version} ได้"
},
"app.world.world-item.not-played-yet": {
"message": "ยังไม่เคยเล่น"
"message": "เวอร์ชัน {version} ไม่รองรับ"
},
"app.world.world-item.offline": {
"message": "ออฟไลน์"
@@ -374,9 +188,6 @@
"friends.action.add-friend": {
"message": "เพิ่มเพื่อน"
},
"friends.action.view-friend-requests": {
"message": "คำขอเป็นเพื่อน {count} {count, plural, other {คน}}"
},
"friends.add-friend.submit": {
"message": "ส่งคำขอเป็นเพื่อน"
},
@@ -384,13 +195,13 @@
"message": "กำลังเพิ่มเพื่อน"
},
"friends.add-friend.username.description": {
"message": "มันอาจแตกต่างจากชื่อในเกม Minecraft ของพวกเขา!"
"message": "อาจจะแตกต่างกับชื่อใน Minecraft"
},
"friends.add-friend.username.placeholder": {
"message": "กรอกชื่อผู้ใช้ Modrinth..."
"message": "ใส่ชื่อบน Modrinth"
},
"friends.add-friend.username.title": {
"message": "เพื่อนของคุณมีชื่อผู้ใช้ Modrinth ว่าอะไร?"
"message": "เพื่อนของคุณมีชื่อบน Modrinth ว่าอะไร"
},
"friends.add-friends-to-share": {
"message": "<link>เพิ่มเพื่อน</link> เพื่อเห็นว่าพวกเขากำลังเล่นอะไรอยู่!"
@@ -417,13 +228,13 @@
"message": "ออฟไลน์"
},
"friends.heading.online": {
"message": "ออไลน์"
"message": "ออไลน์"
},
"friends.heading.pending": {
"message": "กําลังดำเนินการ"
},
"friends.no-friends-match": {
"message": "ไม่มีรายชื่อเพื่อนที่ตรงกับ \"{query}\""
"message": "ไม่มีเพื่อนชื่อว่า \"{query}\""
},
"friends.search-friends-placeholder": {
"message": "ค้นหาเพื่อน"
@@ -465,7 +276,7 @@
"message": "โลก Minecraft"
},
"instance.edit-world.reset-icon": {
"message": "รีเซ็ตรูปสัญลักษณ์"
"message": "รีเซ็ตรูปตัวอย่าง"
},
"instance.edit-world.title": {
"message": "แก้ไขโลก"
@@ -492,13 +303,13 @@
"message": "ทั่วไป"
},
"instance.settings.tabs.general.delete": {
"message": "ลบโปรแกรม"
"message": "ลบอินสแตนซ์"
},
"instance.settings.tabs.general.delete.button": {
"message": "ลบโปรแกรม"
"message": "ลบอินสแตนซ์"
},
"instance.settings.tabs.general.delete.description": {
"message": "การกระทำดังกล่าวจะลบโปรแกรมออกจากอุปกรณ์ของคุณอย่างถาวร รวมถึงโลก การตั้งค่า และเนื้อหาทั้งหมดที่ติดตั้งไว้ โปรดระมัดระวัง เนื่องจากเมื่อถูกลบแล้วจะไม่สามารถกู้คืนได้อีก"
"message": "ลบอินสแตนซ์ออกจากอุปกรณ์ของคุณอย่างถาวร รวมถึงโลก การตั้งค่า และเนื้อหาทั้งหมดที่ติดตั้งไว้ โปรดระมัดระวัง เนื่องจากเมื่อถูกลบแล้วจะไม่สามารถกู้คืนได้อีก"
},
"instance.settings.tabs.general.deleting.button": {
"message": "กำลังลบ..."
@@ -510,31 +321,31 @@
"message": "ไม่สามารถทำซ้ำได้ขณะติดตั้ง"
},
"instance.settings.tabs.general.duplicate-instance": {
"message": "สร้างสำเนาโปรแกรม"
"message": "สร้างสำเนาอินสแตนซ์"
},
"instance.settings.tabs.general.duplicate-instance.description": {
"message": "สร้างสำเนาของโปรแกรมนี้ รวมถึงโลก การตั้งค่า ม็อด และอื่น ๆ"
"message": "สร้างสำเนาของอินสแตนซ์นี้ รวมถึงโลก การตั้งค่า ม็อด และอื่นๆ"
},
"instance.settings.tabs.general.edit-icon": {
"message": "แก้ไขสัญลักษณ์"
"message": "แก้ไขไอคอน"
},
"instance.settings.tabs.general.edit-icon.remove": {
"message": "ลบสัญลักษณ์"
"message": "ลบไอคอน"
},
"instance.settings.tabs.general.edit-icon.replace": {
"message": "แทนที่สัญลักษณ์"
"message": "เปลี่ยนไอคอน"
},
"instance.settings.tabs.general.edit-icon.select": {
"message": "เลือกรูปสัญลักษณ์"
"message": "เลือกรูปไอคอน"
},
"instance.settings.tabs.general.library-groups": {
"message": "จัดกลุ่ม"
"message": "การจัดกลุ่ม"
},
"instance.settings.tabs.general.library-groups.create": {
"message": "สร้างกลุ่มใหม่"
},
"instance.settings.tabs.general.library-groups.description": {
"message": "การจัดกลุ่มจะช่วยจัดระเบียบโปรแกรมของคุณภายในหน้ารายการให้เป็นหมวดหมู่"
"message": "กลุ่มไลบรารีช่วยให้คุณจัดระเบียบอินสแตนซ์ของคุณเป็นหมวดหมู่ต่างๆ ภายในไลบรารี"
},
"instance.settings.tabs.general.library-groups.enter-name": {
"message": "ใส่ชื่อกลุ่ม"
@@ -543,58 +354,43 @@
"message": "ชื่อ"
},
"instance.settings.tabs.hooks": {
"message": "Launch Hook"
"message": "ตัวดักการปล่อย"
},
"instance.settings.tabs.hooks.custom-hooks": {
"message": "กำหนด Launch Hook เอง"
"message": "กำหนดเอง"
},
"instance.settings.tabs.hooks.description": {
"message": "Launch Hook จะช่วยให้ผู้เล่นที่ชำนาญสามารถใช้คำสั่งต่อระบบบางอย่างได้ ทั้งก่อนและหลังเกมถูกเปิด"
},
"instance.settings.tabs.hooks.post-exit": {
"message": "Post-exit"
},
"instance.settings.tabs.hooks.post-exit.description": {
"message": "จะรันหลังจากที่ตัวเกมถูกปิด"
"message": "ตัวดักจับช่วยให้ผู้ใช้ระดับสูงสามารถรันคำสั่งระบบบางอย่างได้ ทั้งก่อนและหลังการเปิดเกม"
},
"instance.settings.tabs.hooks.post-exit.enter": {
"message": "ป้อนคำสั่ง..."
"message": "ป้อนคำสั่งหลังจบการทำงาน..."
},
"instance.settings.tabs.hooks.pre-launch": {
"message": "Pre-launch"
},
"instance.settings.tabs.hooks.pre-launch.description": {
"message": "จะรันก่อนที่โปรแกรมจะทำงาน"
},
"instance.settings.tabs.hooks.pre-launch.enter": {
"message": "ป้อนคำสั่ง..."
"message": "ก่อนรัน"
},
"instance.settings.tabs.hooks.title": {
"message": "Game Launch Hook"
"message": "ฮุกการเปิดเกม"
},
"instance.settings.tabs.hooks.wrapper": {
"message": "Wrapper"
"message": "ตัวห่อหุ้ม"
},
"instance.settings.tabs.hooks.wrapper.description": {
"message": "คำสั่ง Wrapper สำหรับใช้ในการรันเปิด Minecraft"
"message": "คำสั่งตัวห่อหุ้มสำหรับเปิด ไมน์คราฟต์"
},
"instance.settings.tabs.hooks.wrapper.enter": {
"message": "ป้อนคำสั่ง Wrapper..."
"message": "ป้อนตัวห่อหุ้มคำสั่ง..."
},
"instance.settings.tabs.installation": {
"message": "การติดตั้ง"
},
"instance.settings.tabs.installation.loader-version": {
"message": "เวอร์ชัน {loader}"
"message": "เวอร์ชัน {loader}"
},
"instance.settings.tabs.java": {
"message": "Java และ หน่วยความจำ"
},
"instance.settings.tabs.java.environment-variables": {
"message": "Environment Variables"
},
"instance.settings.tabs.java.hooks": {
"message": "Hook"
"message": "ฮุก"
},
"instance.settings.tabs.java.java-arguments": {
"message": "อาร์กิวเมนต์ Java"
@@ -608,9 +404,6 @@
"instance.settings.tabs.window": {
"message": "หน้าต่าง"
},
"instance.settings.tabs.window.custom-window-settings": {
"message": "การตั้งค่าการปรับแต่งหน้าต่าง"
},
"instance.settings.tabs.window.fullscreen": {
"message": "เต็มหน้าจอ"
},
@@ -636,7 +429,7 @@
"message": "ป้อนความกว้าง..."
},
"instance.worlds.a_minecraft_server": {
"message": "เซิร์ฟเวอร์ Minecraft"
"message": "เซิร์ฟเวอร์ ไมน์คราฟต์"
},
"instance.worlds.cant_connect": {
"message": "ไม่สามารถเชื่อมต่อกับเซิร์ฟเวอร์ได้"
@@ -648,7 +441,7 @@
"message": "ไม่ต้องแสดงในหน้าแรก"
},
"instance.worlds.game_already_open": {
"message": "โปรแกรมถูกเปิดอยู่แล้ว"
"message": "อินสแตนซ์ถูกเปิดอยู่แล้ว"
},
"instance.worlds.hardcore": {
"message": "โหมดฮาร์ดคอร์"
@@ -669,75 +462,21 @@
"message": "คุณสามารถเข้าสู่โลกผู้เล่นคนเดียวได้โดยตรงบน Minecraft 1.20 ขึ้นไปเท่านั้น"
},
"instance.worlds.play_instance": {
"message": "เริ่มรันโปรแกรม"
"message": "เริ่มเล่นอินสแตนซ์"
},
"instance.worlds.view_instance": {
"message": "ดูโปรแกรม"
"message": "ดูอินสแตนซ์"
},
"instance.worlds.world_in_use": {
"message": "โลกนี้กำลังถูกใช้งานอยู่"
},
"minecraft-account.add-account": {
"message": "เพิ่มบัญชี"
},
"minecraft-account.label": {
"message": "บัญชี Minecraft"
},
"minecraft-account.not-signed-in": {
"message": "ยังไม่ได้ลงชื่อเข้าใช้"
},
"minecraft-account.remove-account": {
"message": "ลบบัญชี"
},
"minecraft-account.select-account": {
"message": "เลือกบัญชี"
},
"minecraft-account.sign-in": {
"message": "ลงชื่อเข้าใช้ Minecraft"
},
"search.filter.locked.instance": {
"message": "โปรแกรมเป็นผู้กำหนด"
},
"search.filter.locked.instance-game-version.title": {
"message": "เวอร์ชันเกมถูกกำหนดไว้โดยโปรแกรมแล้ว"
},
"search.filter.locked.instance-loader.title": {
"message": "ตัวรันถูกกำหนดไว้โดยโปรแกรมแล้ว"
},
"search.filter.locked.instance.sync": {
"message": "เชื่อมต่อกับโปรแกรม"
"message": "อินสแตนซ์เป็นผู้จัดเตรียม"
},
"search.filter.locked.server": {
"message": "เซิร์ฟเวอร์เป็นผู้กำหนด"
},
"search.filter.locked.server-environment.title": {
"message": "มีเพียงม็อดสำหรับฝั่งเครื่องของผู้เล่นเท่านั้นที่สามารถเพิ่มลงในโปรแกรมเซิร์ฟเวอร์ดังกล่าวได้"
"message": "เซิร์ฟเวอร์เป็นผู้จัดเตรียม"
},
"search.filter.locked.server-game-version.title": {
"message": "เวอร์ชันเกมถูกกำหนดโดยเซิร์ฟเวอร์แล้ว"
},
"search.filter.locked.server-loader.title": {
"message": "ตัวรันถูกกำหนดโดยเซิร์ฟเวอร์แล้ว"
},
"unknown-pack-warning-modal.body": {
"message": "ไฟล์จะได้รับการตรวจสอบโดยไม่คำนึงถึงประเภทของไฟล์ (รวมทั้ง .mrpack) เมื่อไฟล์ถูกอัปโหลดขึ้น Modrinth"
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "อย่าแสดงคำเตือนนี้อีก"
},
"unknown-pack-warning-modal.header": {
"message": "ยืนยันการติดตั้ง"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "ดำเนินการติดตั้งต่อไป"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "มัลแวร์มักแฝงตัวมากับไฟล์แพ็กม็อดผ่านการแชร์ผ่านแพลตฟอร์มที่ไม่ใช่แพลตฟอร์มเฉพาะ เช่น ดิสคอร์ด"
},
"unknown-pack-warning-modal.warning.body": {
"message": "เราไม่สามารถค้นหาไฟล์ดังกล่าวได้บน Modrinth พวกเราขอแนะนำอย่างมากกว่าควรติดตั้งไฟล์จากแหล่งที่น่าเชื่อถือเท่านั้น"
},
"unknown-pack-warning-modal.warning.title": {
"message": "แจ้งเตือนไฟล์ไม่รู้จัก"
"message": "เซิร์ฟเวอร์เป็นผู้จัดเตรียมเวอร์ชันเกม"
}
}
+45 -180
View File
@@ -1,157 +1,61 @@
{
"app.action-bar.downloading-java": {
"message": "Java {version} indiriliyor"
},
"app.action-bar.downloads": {
"message": "İndirmeler"
},
"app.action-bar.hide-more-running-instances": {
"message": "Diğer çalışan kurulumları gizle"
},
"app.action-bar.make-primary-instance": {
"message": "Birincil kurulum yap"
},
"app.action-bar.no-instances-running": {
"message": "Herhangi bir kurulum çalışmıyor"
},
"app.action-bar.offline": {
"message": "Çevrimdışı"
},
"app.action-bar.primary-instance": {
"message": "Birincil kurulum"
},
"app.action-bar.show-more-running-instances": {
"message": "Daha fazla çalışan kurulum göster"
},
"app.action-bar.stop-instance": {
"message": "Kurulumu durdur"
},
"app.action-bar.view-active-downloads": {
"message": "Şu anda indirilienleri göster"
},
"app.action-bar.view-instance": {
"message": "Kurulumu göster"
},
"app.action-bar.view-logs": {
"message": "Günlükleri görüntüle"
},
"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."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Gelişmiş işleme"
},
"app.appearance-settings.color-theme.description": {
"message": "Modrinth App için tercih ettiğiniz temayı seçin."
},
"app.appearance-settings.color-theme.title": {
"message": "Tema"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Launcher açıldığında varsayılan olarak açılacak sayfayı seçin."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Ana Sayfa"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Kütüphane"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Varsayılan karşılama sayfası"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Kostümler sayfasındaki karakterinizin üzerindeki isim etiketini devre dışı bırakır."
},
"app.appearance-settings.hide-nametag.title": {
"message": "İsim etiketini gizle"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Ana sayfadaki 'Hızlıca Geri Dön' bölümünde son oynanan dünyaları gösterir."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Dünyalara hızlıca geri dön"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Minecraft başlatıldığında launcher'i simge durumuna at."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Launcher'i simge durumuna at"
},
"app.appearance-settings.native-decorations.description": {
"message": "Sistem pencere kenarlıklarını kullan (Yeniden başlatma gerekli)."
},
"app.appearance-settings.native-decorations.title": {
"message": "Yerel pencere öğeleri"
},
"app.appearance-settings.select-option": {
"message": "Bir seçenek seçin"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Kenar çubuğunu ayarlama özelliğini aktifleştirir."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "Kenar çubuğunu ayarla"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Modrinth üzerinde barındırılmayan bir Modrinth Paket dosyasını (.mrpack) yüklemeye çalışırsanız, yükleme öncesinde riskleri anladığınızdan emin oluruz."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "Bilinmeyen mod paketlerini indirmeden önce beni uyar"
},
"app.auth-servers.unreachable.body": {
"message": "Minecraft doğrulama sunucuları kapalı olabilir. İnternet bağlantını kontrol et ve daha sonra tekrar dene."
},
"app.auth-servers.unreachable.header": {
"message": "Doğrulama sunucularına erişilemedi"
},
"app.browse.add-server-to-instance": {
"message": "Sunucuya içerik ekle"
},
"app.browse.add-servers-to-instance": {
"message": "İçeriğe sunucu ekle"
},
"app.browse.add-to-instance": {
"message": "Kuruluma ekle"
"message": "İçerik ekle"
},
"app.browse.add-to-instance-name": {
"message": "{instanceName}'a ekle"
"message": "{instanceName} içeriğine ekle"
},
"app.browse.added": {
"message": "Ekli"
"message": "Eklendi"
},
"app.browse.already-added": {
"message": "Zaten ekli"
"message": "Zaten eklendi"
},
"app.browse.discover-content": {
"message": "İçerik keşfet"
"message": "İçerikleri keşfet"
},
"app.browse.discover-servers": {
"message": "Sunucu keşfet"
"message": "Sunucuları keşfet"
},
"app.browse.hide-added-servers": {
"message": "Zaten eklenmiş sunucuları gizle"
"message": "Eklenen sunucuları gizle\n"
},
"app.browse.project-type.modpacks": {
"message": "Mod paketleri"
"app.browse.hide-installed-content": {
"message": "Yüklü İçerikleri Gizle"
},
"app.browse.server.installing": {
"message": "Yükleniyor"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Mod paketi indiriliyor..."
"app.browse.install-content-to-instance": {
"message": "İçeriği profile yükle"
},
"app.export-modal.description-placeholder": {
"message": "Mod paketi açıklaması girin..."
"message": "Mod paketi açıklaması yazın..."
},
"app.export-modal.export-button": {
"message": "Dışa aktar"
"message": "Çıkart"
},
"app.export-modal.header": {
"message": "Mod paketini dışa aktar"
"message": "Modpaketi çıkart"
},
"app.export-modal.modpack-name-label": {
"message": "Mod Paketi Adı"
"message": "Modpaketi adı"
},
"app.export-modal.modpack-name-placeholder": {
"message": "Modpaketi adı"
},
"app.export-modal.select-files-label": {
"message": "Pakete dahil edilecek dosya ve klasörleri seçin"
},
"app.export-modal.version-number-label": {
"message": "Sürüm numarası"
},
@@ -165,22 +69,22 @@
"message": "Bu eylem geri alınamaz"
},
"app.instance.confirm-delete.delete-button": {
"message": "Kurulumu sil"
"message": "İçeriği Sil"
},
"app.instance.confirm-delete.header": {
"message": "Kurulumu sil"
"message": "İçeriği Sil"
},
"app.instance.modpack-already-installed.body": {
"message": "Bu mod paketi zaten <bold>{instanceName}</bold> kurulumunda yüklü. Kopyalamak istediğinizden emin misiniz?"
"message": "Bu mod paketi zaten <bold>{instanceName}</bold> örneğinde yüklü. Kopyalamak istediğinizden emin misiniz?"
},
"app.instance.modpack-already-installed.create": {
"message": "Oluştur"
},
"app.instance.modpack-already-installed.header": {
"message": "Modpaketi zaten yüklü"
"message": "Modpaketi zaten kurulu"
},
"app.instance.modpack-already-installed.instance": {
"message": "Kurulum"
"message": "İçerik"
},
"app.instance.mods.content-type-project": {
"message": "proje"
@@ -198,16 +102,16 @@
"message": "Mod paketi içeriğini paylaşıyorsunuz"
},
"app.instance.mods.successfully-uploaded": {
"message": "Başarıyla yüklendi"
"message": "Başarı ile yüklendi"
},
"app.instance.worlds.add-server": {
"message": "Sunucu Ekle"
},
"app.instance.worlds.browse-servers": {
"message": "Sunucuları Keşfet"
"message": "Sunucuya göz at"
},
"app.instance.worlds.delete-world-description": {
"message": "'{name}' **kalıcı olarak silinecek** ve geri getirilmesi mümkün olmayacaktır."
"message": "'{name}' kalıcı olarak silinecek ve geri getirilmesi mümkün olmayacaktır."
},
"app.instance.worlds.delete-world-title": {
"message": "Bu dünyayı kalıcı olarak silmek istediğinizden emin misiniz?"
@@ -216,10 +120,10 @@
"message": "Modlu"
},
"app.instance.worlds.filter-offline": {
"message": "Çevrim dışı"
"message": "Çevrimdışı"
},
"app.instance.worlds.filter-online": {
"message": "Çevrim içi"
"message": "Çevrimiçi"
},
"app.instance.worlds.filter-vanilla": {
"message": "Vanilla"
@@ -237,7 +141,7 @@
"message": "'{name}' ({address}) oyun içi dahil olmak üzere listenizden kaldırılacak ve geri getirilmesi mümkün olmayacaktır."
},
"app.instance.worlds.remove-server-title": {
"message": "{name}'i kaldırmak istediğinizden emin misiniz?"
"message": "{name} öğesini kaldırmak istediğinizden emin misiniz?"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "{count} dünya ara..."
@@ -249,7 +153,7 @@
"message": "İçerik gerekli"
},
"app.modal.install-to-play.header": {
"message": "Oynamak için yükleyin"
"message": "Yükleyip oynayın"
},
"app.modal.install-to-play.install-button": {
"message": "Yükle"
@@ -306,19 +210,19 @@
"message": "Kaynak yönetimi"
},
"app.update-popup.body": {
"message": "Modrinth App v{version} güncellemesi indirilmeye hazır! Hemen güncellemek için yeniden başlatın veya Modrinth Appi kapattığınızda otomatik olarak güncellenecek."
"message": "Modrinth App v{version} güncellemesi hazır! Hemen güncellemek için yeniden yükle veya Modrinth Appi kapattığında otomatik olarak güncellenecek."
},
"app.update-popup.body.download-complete": {
"message": "Modrinth App v{version} indirildi. Güncellemek için yeniden başlatın veya Modrinth Appi kapattığınızda otomatik olarak güncellenecek."
"message": "Modrinth App v{version} indirildi. Güncellemek için sayfayı yeniden yükle veya Modrinth Appi kapattığında otomatik olarak güncellenecek."
},
"app.update-popup.body.linux": {
"message": "Modrinth App v{version} yayımlandı. En yeni özellikler ve hata düzeltmeleri için paket yöneticin üzerinden güncelle!"
},
"app.update-popup.body.metered": {
"message": "Modrinth App v{version} mevcut! Kısıtlı bağlantıda olduğunuzdan otomatik olarak indirmedik."
"message": "Modrinth App v{version} artık mevcut! Ölçüllü bağlantıda olduğunuzdan otomatik olarak indirmedik."
},
"app.update-popup.changelog": {
"message": "Yama Notları"
"message": "Değişiklikler"
},
"app.update-popup.download": {
"message": "İndir ({size})"
@@ -327,7 +231,7 @@
"message": "İndirme tamamlandı"
},
"app.update-popup.reload": {
"message": "Yeniden başlat"
"message": "Yeniden yükle"
},
"app.update-popup.title": {
"message": "Güncelleme mevcut"
@@ -345,7 +249,7 @@
"message": "Güncelleme indiriliyor (%{percent})"
},
"app.update.reload-to-update": {
"message": "Güncellemeyi kurmak için yeniden başlatın"
"message": "Güncellemeyi kurmak için yeniden yükleyin"
},
"app.world.server-modal.placeholder-address": {
"message": "example.modrinth.gg"
@@ -360,7 +264,7 @@
"message": "Henüz oynanmadı"
},
"app.world.world-item.offline": {
"message": "Çevrim dışı"
"message": "Çevrimdışı"
},
"app.world.world-item.players-online": {
"message": "{count} çevrimiçi"
@@ -486,10 +390,10 @@
"message": "Genel"
},
"instance.settings.tabs.general.delete": {
"message": "Kurulumu sil"
"message": "Profili sil"
},
"instance.settings.tabs.general.delete.button": {
"message": "Kurulumu sil"
"message": "Profili sil"
},
"instance.settings.tabs.general.delete.description": {
"message": "Profili, içindeki dünyaları, ayarları ve indirilen şeyleri cihazınızdan sonsuza kadar siler. Dikkatli olun, bir profil silindikten sonra geri alınamaz."
@@ -671,24 +575,6 @@
"instance.worlds.world_in_use": {
"message": "Dünya şu anda kullanımda"
},
"minecraft-account.add-account": {
"message": "Hesap ekle"
},
"minecraft-account.label": {
"message": "Minecraft hesabı"
},
"minecraft-account.not-signed-in": {
"message": "Giriş yapılmadı"
},
"minecraft-account.remove-account": {
"message": "Hesabı kaldır"
},
"minecraft-account.select-account": {
"message": "Hesap seçin"
},
"minecraft-account.sign-in": {
"message": "Minecraft'a giriş yapın"
},
"search.filter.locked.instance": {
"message": "Kurulum tarafından sağlanan"
},
@@ -712,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "Yükleyici sunucu tarafından sağlanıyor"
},
"unknown-pack-warning-modal.body": {
"message": "Dosya formatı ne olursa olsun (.mrpack dahil), bir dosya yalnızca Modrinth'e yüklendiğinde denetlenir."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "Bu uyarıyı tekrar gösterme"
},
"unknown-pack-warning-modal.header": {
"message": "İndirmeyi onayla"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "Yine de indir"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "Kötü amaçlı yazılımlar genellikle Discord gibi platformlarda paylaşılan mod paketi dosyaları aracılığıyla yayılır."
},
"unknown-pack-warning-modal.warning.body": {
"message": "Bu dosyayı Modrinth üzerinde bulamadık. Yalnızca güvendiğiniz kaynaklardan gelen dosyaları yüklemenizi şiddetle öneririz."
},
"unknown-pack-warning-modal.warning.title": {
"message": "Bilinmeyen dosya uyarısı"
}
}
+18 -144
View File
@@ -1,109 +1,16 @@
{
"app.action-bar.downloading-java": {
"message": "Завантаження Java {version}"
},
"app.action-bar.downloads": {
"message": "Завантаження"
},
"app.action-bar.hide-more-running-instances": {
"message": "Приховати більше запущених екземплярів"
},
"app.action-bar.make-primary-instance": {
"message": "Зробити основним екземпляром"
},
"app.action-bar.no-instances-running": {
"message": "Немає запущених екземплярів"
},
"app.action-bar.offline": {
"message": "Офлайн"
},
"app.action-bar.primary-instance": {
"message": "Основний екземпляр"
},
"app.action-bar.show-more-running-instances": {
"message": "Показати більше запущених екземплярів"
},
"app.action-bar.stop-instance": {
"message": "Зупинити екземпляр"
},
"app.action-bar.view-active-downloads": {
"message": "Переглянути активні завантаження"
},
"app.action-bar.view-instance": {
"message": "Переглянути екземпляр"
},
"app.action-bar.view-logs": {
"message": "Переглянути журнали"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "Дозволяє розширений рендеринг, такий як ефекти розмиття, які можуть спричиняти проблеми з продуктивністю без апаратно-прискореного рендерингу."
},
"app.appearance-settings.advanced-rendering.title": {
"message": "Розширений рендеринг"
},
"app.appearance-settings.color-theme.description": {
"message": "Виберіть бажану колірну тему для програми Modrinth App."
},
"app.appearance-settings.color-theme.title": {
"message": "Колірна тема"
},
"app.appearance-settings.default-landing-page.description": {
"message": "Змініть сторінку, на якій відкривається панель запуску."
},
"app.appearance-settings.default-landing-page.home": {
"message": "Головна"
},
"app.appearance-settings.default-landing-page.library": {
"message": "Бібліотека"
},
"app.appearance-settings.default-landing-page.title": {
"message": "Цільова сторінка за замовчуванням"
},
"app.appearance-settings.hide-nametag.description": {
"message": "Вимикає іменний бейдж над вашим гравцем на сторінці скінів."
},
"app.appearance-settings.hide-nametag.title": {
"message": "Приховати бейдж з іменем"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "Включає нещодавні світи в розділі «Повернення» на головній сторінці."
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "Стрибни назад у світи"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "Згорнути лаунчер під час запуску процесу Minecraft."
},
"app.appearance-settings.minimize-launcher.title": {
"message": "Згорнути панель запуску"
},
"app.appearance-settings.native-decorations.description": {
"message": "Використовувати рамку системного вікна (потрібно перезапустити програму)."
},
"app.appearance-settings.native-decorations.title": {
"message": "Рідні прикраси"
},
"app.appearance-settings.select-option": {
"message": "Виберіть опцію"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "Вмикає можливість перемикання бічної панелі."
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "Перемикання бічної панелі"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "Якщо ви спробуєте встановити файл пакета Modrinth (.mrpack), який не розміщено на Modrinth, ми переконаємося, що ви розумієте ризики, перш ніж встановлювати його."
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "Попереджати мене перед встановленням невідомих модпаків"
},
"app.auth-servers.unreachable.body": {
"message": "Сервери автентифікації Minecraft можуть зараз не працювати. Перевірте з’єднання з інтернетом та спробуйте пізніше."
},
"app.auth-servers.unreachable.header": {
"message": "Не вдається зв’язатися зі серверами автентифікації"
},
"app.browse.add-server-to-instance": {
"message": "Додати сервер до профілю"
},
"app.browse.add-servers-to-instance": {
"message": "Додати сервера до вашого профілю"
},
"app.browse.add-to-instance": {
"message": "Додати до профілю"
},
@@ -123,22 +30,16 @@
"message": "Дослідити сервера"
},
"app.browse.hide-added-servers": {
"message": "Скрити наявні сервери"
"message": "Сховати додані сервера"
},
"app.browse.project-type.modpacks": {
"message": "Модпаки"
"app.browse.hide-installed-content": {
"message": "Сховати встановлений уміст"
},
"app.browse.server.installing": {
"message": "Встановлення"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "Встановлення модпаку..."
"app.browse.install-content-to-instance": {
"message": "Установити вміст в профіль"
},
"app.export-modal.description-placeholder": {
"message": "Уведіть опис збірки..."
"message": "Уведіть опис збірки"
},
"app.export-modal.export-button": {
"message": "Експортувати"
@@ -152,6 +53,9 @@
"app.export-modal.modpack-name-placeholder": {
"message": "Назва збірки"
},
"app.export-modal.select-files-label": {
"message": "Виберіть файли й теки, щоб додати їх до збірки"
},
"app.export-modal.version-number-label": {
"message": "Номер версії"
},
@@ -240,7 +144,7 @@
"message": "Ви впевнені, що хочете видалити «{name}»?"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "Пошук {count} світів..."
"message": "Пошук {count} світів"
},
"app.instance.worlds.this-server": {
"message": "цей сервер"
@@ -420,7 +324,7 @@
"message": "Немає друзів, які збігаються з «{query}»"
},
"friends.search-friends-placeholder": {
"message": "Пошук друзів..."
"message": "Пошук друзів"
},
"friends.section.heading": {
"message": "{title} — {count}"
@@ -468,7 +372,7 @@
"message": "Додавання файлів ({completed}/{total})"
},
"instance.files.save-as": {
"message": "Зберегти як..."
"message": "Зберегти як"
},
"instance.server-modal.address": {
"message": "Адреса"
@@ -671,15 +575,6 @@
"instance.worlds.world_in_use": {
"message": "Світ наразі використовується"
},
"minecraft-account.add-account": {
"message": "Додати обліковий запис"
},
"minecraft-account.remove-account": {
"message": "Видалити обліковий запис"
},
"minecraft-account.select-account": {
"message": "Обрати обліковий запис"
},
"search.filter.locked.instance": {
"message": "Надано профілем"
},
@@ -703,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "Завантажувач наданий сервером"
},
"unknown-pack-warning-modal.body": {
"message": "Файл перевірятиметься лише, якщо його завантажено на Modrinth, незалежно від його формату (включно з .mrpack)."
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "Не показувати більше це попередження"
},
"unknown-pack-warning-modal.header": {
"message": "Підтвердити інсталяцію"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "Усе одно інсталювати"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "Шкідливе програмне забезпечення часто поширюють через файли модпаків, які публікуються на таких платформах, як Discord."
},
"unknown-pack-warning-modal.warning.body": {
"message": "Ми не змогли знайти цей файл на Modrinth. Ми рекомендуємо встановлювати файли лише з тих джерел яким ви довіряєте."
},
"unknown-pack-warning-modal.warning.title": {
"message": "Попередження про невідомий файл"
}
}
@@ -5,6 +5,12 @@
"app.auth-servers.unreachable.header": {
"message": "Không thể kết nối đến máy chủ xác thực"
},
"app.browse.add-server-to-instance": {
"message": "Thêm máy chủ vào hồ sơ"
},
"app.browse.add-servers-to-instance": {
"message": "Thêm máy chủ vào hồ sơ của bạn"
},
"app.browse.add-to-instance": {
"message": "Thêm vào hồ sơ"
},
@@ -23,6 +29,15 @@
"app.browse.discover-servers": {
"message": "Khám phá máy chủ"
},
"app.browse.hide-added-servers": {
"message": "Ẩn các máy chủ đã thêm"
},
"app.browse.hide-installed-content": {
"message": "Ẩn các nội dung đã được tải xuống"
},
"app.browse.install-content-to-instance": {
"message": "Tải nội dung này vào hồ sơ"
},
"app.export-modal.description-placeholder": {
"message": "Thêm miêu tả cho gói modpack..."
},
@@ -38,6 +53,9 @@
"app.export-modal.modpack-name-placeholder": {
"message": "Tên modpack"
},
"app.export-modal.select-files-label": {
"message": "Chọn tệp và gói để thêm vào gói tài nguyên"
},
"app.export-modal.version-number-label": {
"message": "Phiên bản"
},
+15 -177
View File
@@ -1,114 +1,15 @@
{
"app.action-bar.downloading-java": {
"message": "正在下载 Java {version}"
},
"app.action-bar.downloads": {
"message": "下载"
},
"app.action-bar.hide-more-running-instances": {
"message": "隐藏更多运行中的实例"
},
"app.action-bar.make-primary-instance": {
"message": "设为主实例"
},
"app.action-bar.no-instances-running": {
"message": "没有运行中的实例"
},
"app.action-bar.offline": {
"message": "离线"
},
"app.action-bar.primary-instance": {
"message": "主实例"
},
"app.action-bar.show-more-running-instances": {
"message": "显示更多运行中的实例"
},
"app.action-bar.stop-instance": {
"message": "停止实例"
},
"app.action-bar.view-active-downloads": {
"message": "查看正在下载内容"
},
"app.action-bar.view-instance": {
"message": "查看实例"
},
"app.action-bar.view-logs": {
"message": "查看日志"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "启用模糊效果等高级渲染。可能会在没有硬件加速渲染的情况下造成性能问题。"
},
"app.appearance-settings.advanced-rendering.title": {
"message": "高级渲染"
},
"app.appearance-settings.color-theme.description": {
"message": "为 Modrinth App 选择偏好的色彩主题。"
},
"app.appearance-settings.color-theme.title": {
"message": "色彩主题"
},
"app.appearance-settings.default-landing-page.description": {
"message": "更改启动器打开的页面。"
},
"app.appearance-settings.default-landing-page.home": {
"message": "首页"
},
"app.appearance-settings.default-landing-page.library": {
"message": "库"
},
"app.appearance-settings.default-landing-page.title": {
"message": "默认起始页"
},
"app.appearance-settings.hide-nametag.description": {
"message": "在皮肤页面中禁用你玩家头顶上的名牌。"
},
"app.appearance-settings.hide-nametag.title": {
"message": "隐藏名牌"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "在主页的“快速回到”部分包含最近的世界。"
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "快速回到世界"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "当 Minecraft 进程启动时,将启动器最小化。"
},
"app.appearance-settings.minimize-launcher.title": {
"message": "最小化启动器"
},
"app.appearance-settings.native-decorations.description": {
"message": "使用系统窗口边框(需要重启应用)。"
},
"app.appearance-settings.native-decorations.title": {
"message": "原生窗口"
},
"app.appearance-settings.select-option": {
"message": "选择一个选项"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "启用切换侧边栏的功能。"
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "切换侧边栏"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "如果你尝试安装一个未托管在 Modrinth 上的 Modrinth 打包文件(.mrpack),我们会确保你在安装之前了解相关风险。"
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "安装未知整合包前提醒我"
},
"app.auth-servers.unreachable.body": {
"message": "Minecraft 身份验证服务器现在可能无法使用。请检查你的网络连接,并稍后再试。"
},
"app.auth-servers.unreachable.header": {
"message": "无法连接到身份验证服务器"
},
"app.browse.add-servers-to-instance": {
"app.browse.add-server-to-instance": {
"message": "将服务器添加到实例"
},
"app.browse.add-to-an-instance": {
"message": "添加到实例"
"app.browse.add-servers-to-instance": {
"message": "将服务器添加到你的实例"
},
"app.browse.add-to-instance": {
"message": "添加到实例"
@@ -122,9 +23,6 @@
"app.browse.already-added": {
"message": "已添加过"
},
"app.browse.back-to-instance": {
"message": "返回实例"
},
"app.browse.discover-content": {
"message": "发现内容"
},
@@ -134,20 +32,11 @@
"app.browse.hide-added-servers": {
"message": "隐藏已添加的服务器"
},
"app.browse.project-type.modpacks": {
"message": "整合包"
"app.browse.hide-installed-content": {
"message": "隐藏已安装的实例"
},
"app.browse.server-instance-content-warning": {
"message": "加入服务器时,添加内容可能会破坏兼容性。当更新服务器实例内容时任何添加的内容也将丢失。"
},
"app.browse.server.installing": {
"message": "安装中"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "正在安装整合包……"
"app.browse.install-content-to-instance": {
"message": "将内容安装到实例中"
},
"app.export-modal.description-placeholder": {
"message": "输入整合包描述……"
@@ -158,9 +47,6 @@
"app.export-modal.header": {
"message": "导出整合包"
},
"app.export-modal.include-file-accessibility-label": {
"message": "包含 \"{file}\""
},
"app.export-modal.modpack-name-label": {
"message": "整合包名称"
},
@@ -168,7 +54,7 @@
"message": "整合包名称"
},
"app.export-modal.select-files-label": {
"message": "配置此导出中包含哪些文件"
"message": "选择要包含在包中的文件和文件"
},
"app.export-modal.version-number-label": {
"message": "版本号"
@@ -204,13 +90,13 @@
"message": "项目"
},
"app.instance.mods.project-was-added": {
"message": "已添加 “{name}”"
"message": "已添加“{name}”"
},
"app.instance.mods.projects-were-added": {
"message": "已添加 {count} 个项目"
},
"app.instance.mods.share-text": {
"message": "查看在整合包中使用的项目!"
"message": "查看在整合包中使用的项目!"
},
"app.instance.mods.share-title": {
"message": "分享整合包内容"
@@ -231,7 +117,7 @@
"message": "你确定要永久删除这个世界吗?"
},
"app.instance.worlds.filter-modded": {
"message": "模组适配"
"message": "修改版"
},
"app.instance.worlds.filter-offline": {
"message": "离线"
@@ -243,7 +129,7 @@
"message": "原版"
},
"app.instance.worlds.no-worlds-description": {
"message": "通过添加一个服务器或点击浏览开始"
"message": "添加一个服务器或点击浏览开始"
},
"app.instance.worlds.no-worlds-heading": {
"message": "未添加服务器或世界"
@@ -264,7 +150,7 @@
"message": "此服务器"
},
"app.modal.install-to-play.content-required": {
"message": "需求内容"
"message": "内容需求"
},
"app.modal.install-to-play.header": {
"message": "安装以游玩"
@@ -276,7 +162,7 @@
"message": "{count} 个模组"
},
"app.modal.install-to-play.required-modpack": {
"message": "需求整合包"
"message": "整合包需求"
},
"app.modal.install-to-play.server-requires-mods": {
"message": "此服务器需要安装模组才能游玩。点击安装,从 Modrinth 下载所需文件,然后直接进入服务器。"
@@ -299,15 +185,6 @@
"app.modal.update-to-play.update-required-description": {
"message": "需要更新至最新版本才能运行 {name}。请更新后启动游戏。"
},
"app.project.install-button.already-installed": {
"message": "此项目已安装"
},
"app.project.install-context.back-to-browse": {
"message": "返回浏览器"
},
"app.project.install-context.install-content-to-instance": {
"message": "将内容安装到实例中"
},
"app.settings.developer-mode-enabled": {
"message": "开发者模式已启用。"
},
@@ -564,7 +441,7 @@
"message": "名称"
},
"instance.settings.tabs.hooks": {
"message": "启动 Hooks"
"message": "启动Hooks"
},
"instance.settings.tabs.hooks.custom-hooks": {
"message": "自定义启动Hooks"
@@ -698,24 +575,6 @@
"instance.worlds.world_in_use": {
"message": "世界正在使用中"
},
"minecraft-account.add-account": {
"message": "添加账户"
},
"minecraft-account.label": {
"message": "Minecraft 账户"
},
"minecraft-account.not-signed-in": {
"message": "未登录"
},
"minecraft-account.remove-account": {
"message": "移除账户"
},
"minecraft-account.select-account": {
"message": "选择账户"
},
"minecraft-account.sign-in": {
"message": "登录 Minecraft"
},
"search.filter.locked.instance": {
"message": "由该实例提供"
},
@@ -739,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "加载器由服务器提供"
},
"unknown-pack-warning-modal.body": {
"message": "只有上传到 Modrinth 的文件才会经过审核,无论其文件格式如何(包括 .mrpack)。"
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "不再显示此警告"
},
"unknown-pack-warning-modal.header": {
"message": "确认安装"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "仍然安装"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "恶意软件常常通过模组包文件在 Discord 等平台上分享而传播。"
},
"unknown-pack-warning-modal.warning.body": {
"message": "我们在 Modrinth 上找不到此文件。强烈建议你仅从可信来源安装文件。"
},
"unknown-pack-warning-modal.warning.title": {
"message": "未知文件警告"
}
}
+25 -187
View File
@@ -1,129 +1,27 @@
{
"app.action-bar.downloading-java": {
"message": "正在下載 Java {version}"
},
"app.action-bar.downloads": {
"message": "下載"
},
"app.action-bar.hide-more-running-instances": {
"message": "隱藏更多執行中的實例"
},
"app.action-bar.make-primary-instance": {
"message": "設為主要實例"
},
"app.action-bar.no-instances-running": {
"message": "沒有執行中的實例"
},
"app.action-bar.offline": {
"message": "離線"
},
"app.action-bar.primary-instance": {
"message": "主要實例"
},
"app.action-bar.show-more-running-instances": {
"message": "顯示更多執行中的實例"
},
"app.action-bar.stop-instance": {
"message": "停止實例"
},
"app.action-bar.view-active-downloads": {
"message": "查看正在下載的項目"
},
"app.action-bar.view-instance": {
"message": "查看實例"
},
"app.action-bar.view-logs": {
"message": "查看紀錄檔"
},
"app.appearance-settings.advanced-rendering.description": {
"message": "啟用進階繪製(如模糊效果);若無硬體加速可能會導致效能問題。"
},
"app.appearance-settings.advanced-rendering.title": {
"message": "進階繪製"
},
"app.appearance-settings.color-theme.description": {
"message": "請選擇你偏好的 Modrinth App 色彩主題。"
},
"app.appearance-settings.color-theme.title": {
"message": "色彩主題"
},
"app.appearance-settings.default-landing-page.description": {
"message": "變更啟動器開啟時的頁面。"
},
"app.appearance-settings.default-landing-page.home": {
"message": "首頁"
},
"app.appearance-settings.default-landing-page.library": {
"message": "遊戲庫"
},
"app.appearance-settings.default-landing-page.title": {
"message": "預設起始頁面"
},
"app.appearance-settings.hide-nametag.description": {
"message": "在外觀頁面中隱藏玩家上方的名牌。"
},
"app.appearance-settings.hide-nametag.title": {
"message": "隱藏名牌"
},
"app.appearance-settings.jump-back-into-worlds.description": {
"message": "在首頁的「繼續遊玩」區塊中顯示最近進入的世界。"
},
"app.appearance-settings.jump-back-into-worlds.title": {
"message": "繼續遊玩世界"
},
"app.appearance-settings.minimize-launcher.description": {
"message": "當 Minecraft 處理程序啟動時最小化啟動器。"
},
"app.appearance-settings.minimize-launcher.title": {
"message": "最小化啟動器"
},
"app.appearance-settings.native-decorations.description": {
"message": "使用系統視窗外框(需要重新啟動應用程式)。"
},
"app.appearance-settings.native-decorations.title": {
"message": "原生裝飾"
},
"app.appearance-settings.select-option": {
"message": "選擇選項"
},
"app.appearance-settings.toggle-sidebar.description": {
"message": "啟用切換側邊欄的功能。"
},
"app.appearance-settings.toggle-sidebar.title": {
"message": "切換側邊欄"
},
"app.appearance-settings.unknown-pack-warning.description": {
"message": "如果你嘗試安裝非 Modrinth 代管的 Modrinth 封裝檔案 (.mrpack),我們會在安裝前確保你已了解相關風險。"
},
"app.appearance-settings.unknown-pack-warning.title": {
"message": "在安裝未知模組包前發出警告"
},
"app.auth-servers.unreachable.body": {
"message": "Minecraft 驗證伺服器現在可能無法使用。請檢查網際網路連線,然後再試一次。"
},
"app.auth-servers.unreachable.header": {
"message": "無法連線到驗證伺服器"
},
"app.browse.add-servers-to-instance": {
"message": "將伺服器新增至實例"
"app.browse.add-server-to-instance": {
"message": "新增此伺服器到實例"
},
"app.browse.add-to-an-instance": {
"message": "新增實例"
"app.browse.add-servers-to-instance": {
"message": "新增伺服器到實例"
},
"app.browse.add-to-instance": {
"message": "新增至實例"
},
"app.browse.add-to-instance-name": {
"message": "新增至「{instanceName}"
"message": "新增{instanceName}"
},
"app.browse.added": {
"message": "已新增"
},
"app.browse.already-added": {
"message": "已新增"
},
"app.browse.back-to-instance": {
"message": "回到實例"
"message": "已新增"
},
"app.browse.discover-content": {
"message": "探索內容"
@@ -134,20 +32,11 @@
"app.browse.hide-added-servers": {
"message": "隱藏已新增的伺服器"
},
"app.browse.project-type.modpacks": {
"message": "模組包"
"app.browse.hide-installed-content": {
"message": "隱藏已安裝的內容"
},
"app.browse.server-instance-content-warning": {
"message": "加入內容可能會導致加入伺服器時發生相容性問題。當你更新伺服器實例內容時,任何新增的內容也會遺失。"
},
"app.browse.server.installing": {
"message": "安裝中"
},
"app.creation-modal.installing-modpack.description": {
"message": "{fileName}"
},
"app.creation-modal.installing-modpack.title": {
"message": "正在安裝模組包..."
"app.browse.install-content-to-instance": {
"message": "安裝至實例中"
},
"app.export-modal.description-placeholder": {
"message": "輸入模組包描述..."
@@ -158,9 +47,6 @@
"app.export-modal.header": {
"message": "匯出模組包"
},
"app.export-modal.include-file-accessibility-label": {
"message": "要包含「{file}」嗎?"
},
"app.export-modal.modpack-name-label": {
"message": "模組包名稱"
},
@@ -168,7 +54,7 @@
"message": "模組包名稱"
},
"app.export-modal.select-files-label": {
"message": "設定要包含在此匯出檔案中的檔案"
"message": "選擇要包含在模組包中的檔案與資料夾"
},
"app.export-modal.version-number-label": {
"message": "版本號碼"
@@ -189,13 +75,13 @@
"message": "刪除實例"
},
"app.instance.modpack-already-installed.body": {
"message": "這個模組包已經安裝在實例「<bold>{instanceName}</bold>中了,確定要再次安裝嗎?"
"message": "模組包已經安裝在<bold>{instanceName}</bold> 實例中了,確定要再次安裝嗎?"
},
"app.instance.modpack-already-installed.create": {
"message": "建立"
},
"app.instance.modpack-already-installed.header": {
"message": "模組包已安裝"
"message": "模組包已安裝"
},
"app.instance.modpack-already-installed.instance": {
"message": "實例"
@@ -204,10 +90,10 @@
"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": "快來看看我在模組包中使用的專案!"
@@ -216,7 +102,7 @@
"message": "分享模組包內容"
},
"app.instance.mods.successfully-uploaded": {
"message": "已成功上傳"
"message": "上傳成功"
},
"app.instance.worlds.add-server": {
"message": "新增伺服器"
@@ -225,10 +111,10 @@
"message": "瀏覽伺服器"
},
"app.instance.worlds.delete-world-description": {
"message": "「{name}」將**永久刪除**,且無法還原。"
"message": "「{name}」將會被**永久刪除**,且無法還原。"
},
"app.instance.worlds.delete-world-title": {
"message": "確定要永久刪除這個世界嗎?"
"message": "確定要永久刪除這個世界嗎?"
},
"app.instance.worlds.filter-modded": {
"message": "模組"
@@ -255,7 +141,7 @@
"message": "「{name}」({address}) 將從你的清單中移除(包含遊戲內),且無法還原。"
},
"app.instance.worlds.remove-server-title": {
"message": "確定要移除「{name}」嗎?"
"message": "確定要移除「{name}」嗎?"
},
"app.instance.worlds.search-worlds-placeholder": {
"message": "搜尋 {count} 個世界..."
@@ -299,15 +185,6 @@
"app.modal.update-to-play.update-required-description": {
"message": "需要更新才能遊玩「{name}」。請更新至最新版本以啟動遊戲。"
},
"app.project.install-button.already-installed": {
"message": "這個專案已安裝"
},
"app.project.install-context.back-to-browse": {
"message": "回到瀏覽頁面"
},
"app.project.install-context.install-content-to-instance": {
"message": "將內容安裝至實例"
},
"app.settings.developer-mode-enabled": {
"message": "開發人員模式已啟用。"
},
@@ -339,7 +216,7 @@
"message": "Modrinth App v{version} 已完成下載!立即重新載入以更新,或在關閉 Modrinth App 時自動更新。"
},
"app.update-popup.body.linux": {
"message": "Modrinth App v{version} 現已推出。請使用軟體包管理員進行更新,以取得最新的功能與修正!"
"message": "Modrinth App v{version} 現已推出。請使用套件管理員進行更新,以取得最新的功能與修正!"
},
"app.update-popup.body.metered": {
"message": "Modrinth App v{version} 現已推出!由於你目前使用的是計量付費網路,我們並未自動下載更新。"
@@ -444,7 +321,7 @@
"message": "待處理"
},
"friends.no-friends-match": {
"message": "找不到相符「{query}」的好友"
"message": "沒有符合「{query}」的好友"
},
"friends.search-friends-placeholder": {
"message": "搜尋好友..."
@@ -549,13 +426,13 @@
"message": "選擇圖示"
},
"instance.settings.tabs.general.library-groups": {
"message": "遊戲庫群組"
"message": "實例庫群組"
},
"instance.settings.tabs.general.library-groups.create": {
"message": "建立新的群組"
},
"instance.settings.tabs.general.library-groups.description": {
"message": "遊戲庫群組讓你可以將實例整理到遊戲庫中的不同分類。"
"message": "實例庫群組讓你可以將實例整理到實例庫中的不同分類。"
},
"instance.settings.tabs.general.library-groups.enter-name": {
"message": "輸入群組名稱"
@@ -570,10 +447,10 @@
"message": "自訂啟動掛勾"
},
"instance.settings.tabs.hooks.description": {
"message": "掛勾讓進階使用者能在遊戲啟動前和啟動後執行特定的系統令。"
"message": "掛勾讓進階使用者能在遊戲啟動前和啟動後執行特定的系統令。"
},
"instance.settings.tabs.hooks.post-exit": {
"message": "結束後"
"message": "結束後執行"
},
"instance.settings.tabs.hooks.post-exit.description": {
"message": "遊戲關閉後執行。"
@@ -698,24 +575,6 @@
"instance.worlds.world_in_use": {
"message": "世界正在使用中"
},
"minecraft-account.add-account": {
"message": "新增帳號"
},
"minecraft-account.label": {
"message": "Minecraft 帳號"
},
"minecraft-account.not-signed-in": {
"message": "未登入"
},
"minecraft-account.remove-account": {
"message": "移除帳號"
},
"minecraft-account.select-account": {
"message": "選擇帳號"
},
"minecraft-account.sign-in": {
"message": "登入 Minecraft"
},
"search.filter.locked.instance": {
"message": "由該實例提供"
},
@@ -739,26 +598,5 @@
},
"search.filter.locked.server-loader.title": {
"message": "載入器由伺服器提供"
},
"unknown-pack-warning-modal.body": {
"message": "只有上傳至 Modrinth 的檔案才會經過審查,無論其檔案格式為何(包含 .mrpack)。"
},
"unknown-pack-warning-modal.dont-show-again": {
"message": "不要再顯示這則警告"
},
"unknown-pack-warning-modal.header": {
"message": "確認安裝"
},
"unknown-pack-warning-modal.install-anyway": {
"message": "仍要安裝"
},
"unknown-pack-warning-modal.malware-statement": {
"message": "惡意軟體經常透過 Discord 等平臺分享模組包檔案來進行傳播。"
},
"unknown-pack-warning-modal.warning.body": {
"message": "我們在 Modrinth 上找不到這個檔案。強烈建議你僅安裝來自信任來源的檔案。"
},
"unknown-pack-warning-modal.warning.title": {
"message": "未知檔案警告"
}
}
-3
View File
@@ -1,5 +1,4 @@
import 'floating-vue/dist/style.css'
import 'overlayscrollbars/overlayscrollbars.css'
import * as Sentry from '@sentry/vue'
import { VueScanPlugin } from '@taijased/vue-render-tracker'
@@ -9,7 +8,6 @@ import { createPinia } from 'pinia'
import { createApp } from 'vue'
import App from '@/App.vue'
import { overlayScrollbarsDirective } from '@/directives/overlayScrollbars'
import i18nPlugin from '@/plugins/i18n'
import i18nDebugPlugin from '@/plugins/i18n-debug'
import router from '@/routes'
@@ -52,6 +50,5 @@ app.use(FloatingVue, {
})
app.use(i18nPlugin)
app.use(i18nDebugPlugin)
app.directive('overlay-scrollbars', overlayScrollbarsDirective)
app.mount('#app')

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