Compare commits

..

1 Commits

Author SHA1 Message Date
jeffvli e3d7e8e856 add default values for optional docker env (#1500) 2026-01-04 15:36:32 -08:00
805 changed files with 53085 additions and 75986 deletions
-1
View File
@@ -5,7 +5,6 @@
*.jpeg binary *.jpeg binary
*.ico binary *.ico binary
*.icns binary *.icns binary
*.webp binary
*.eot binary *.eot binary
*.otf binary *.otf binary
*.ttf binary *.ttf binary
+1 -1
View File
@@ -6,7 +6,7 @@ body:
- type: checkboxes - type: checkboxes
id: check-duplicate id: check-duplicate
attributes: attributes:
label: I have already checked through the existing (both open AND closed) bug reports and found no duplicates label: I have already checked through the existing bug reports and found no duplicates
options: options:
- label: 'Yes' - label: 'Yes'
required: true required: true
-185
View File
@@ -1,185 +0,0 @@
# Alpha builds published to Cloudflare R2 with date versioning (e.g. 1.0.0-alpha-20260205).
# Required repo secrets: R2_ACCESS_KEY_ID, R2_SECRET_ACCESS_KEY (from R2 API token in Cloudflare dashboard).
name: Publish Alpha
on:
workflow_dispatch:
inputs:
version:
description: 'Semantic version number (e.g., 1.0.0) - alpha suffix will be added automatically'
required: false
type: string
schedule:
# Run at 3:00 AM PST daily (11:00 UTC; PST = UTC-8)
- cron: '0 11 * * *'
jobs:
check-new-commits:
runs-on: ubuntu-latest
outputs:
has_new_commits: ${{ steps.manual.outputs.has_new_commits || steps.check.outputs['has-new-commits'] }}
steps:
- name: Set has new commits (manual trigger)
id: manual
if: github.event_name == 'workflow_dispatch'
run: echo "has_new_commits=true" >> "$GITHUB_OUTPUT"
- name: Check for new commits (24 hr interval)
id: check
if: github.event_name != 'workflow_dispatch'
uses: adriangl/check-new-commits-action@v1
with:
token: ${{ secrets.GITHUB_TOKEN }}
seconds: 86400
prepare:
needs: check-new-commits
if: needs.check-new-commits.outputs.has_new_commits == 'true'
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
steps:
- name: Checkout git repo
uses: actions/checkout@v6
- name: Install Node and PNPM
uses: pnpm/action-setup@v4
- name: Install dependencies
run: pnpm install
- name: Set date-based alpha version
id: version
shell: pwsh
run: |
$inputVersion = "${{ github.event.inputs.version }}"
Write-Host "Input version: $inputVersion"
if ($inputVersion -eq "" -or $inputVersion -eq "null") {
# No input version provided (scheduled run or manual without input), auto-increment patch version
Write-Host "No version provided, auto-incrementing patch version..."
$currentVersion = (Get-Content package.json | ConvertFrom-Json).version
Write-Host "Current version: $currentVersion"
$cleanVersion = $currentVersion -replace '-.*$', ''
$versionParts = $cleanVersion.Split('.')
if ($versionParts.Length -ne 3) {
Write-Error "Current version format is invalid: $cleanVersion"
exit 1
}
$major = [int]$versionParts[0]
$minor = [int]$versionParts[1]
$patch = [int]$versionParts[2]
$newPatch = $patch + 1
$inputVersion = "$major.$minor.$newPatch"
Write-Host "Auto-generated version: $inputVersion"
} else {
# Validate semantic version format (major.minor.patch)
$versionPattern = '^\d+\.\d+\.\d+$'
if ($inputVersion -notmatch $versionPattern) {
Write-Error "Invalid version format. Expected semantic version (e.g., 1.0.0), got: $inputVersion"
exit 1
}
}
# Date in YYYYMMDD (PST / America/Los_Angeles)
$pst = [TimeZoneInfo]::FindSystemTimeZoneById('America/Los_Angeles')
$dateInPst = [TimeZoneInfo]::ConvertTimeFromUtc([DateTime]::UtcNow, $pst)
$dateStr = $dateInPst.ToString("yyyyMMdd")
$alphaVersion = "$inputVersion-alpha-$dateStr"
Write-Host "Alpha version: $alphaVersion"
# Update package.json
$packageJson = Get-Content package.json | ConvertFrom-Json
$packageJson.version = $alphaVersion
$packageJson | ConvertTo-Json -Depth 10 | Set-Content package.json
echo "version=$alphaVersion" >> $env:GITHUB_OUTPUT
cleanup:
needs: prepare
runs-on: ubuntu-latest
env:
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
R2_ENDPOINT_URL: ${{ secrets.R2_ENDPOINT_URL }}
steps:
- name: Delete all objects in R2 bucket
run: |
aws s3 rm s3://feishin-nightly --recursive --endpoint-url $R2_ENDPOINT_URL
publish:
needs: [prepare, cleanup]
runs-on: ${{ matrix.os }}
env:
AWS_ACCESS_KEY_ID: ${{ secrets.R2_ACCESS_KEY_ID }}
AWS_SECRET_ACCESS_KEY: ${{ secrets.R2_SECRET_ACCESS_KEY }}
strategy:
matrix:
os: [windows-latest, macos-26, ubuntu-latest]
steps:
- name: Checkout git repo
uses: actions/checkout@v6
- name: Install Node and PNPM
uses: pnpm/action-setup@v4
- name: Install dependencies
run: pnpm install
- name: Set version from prepare job
shell: pwsh
run: |
$version = "${{ needs.prepare.outputs.version }}"
Write-Host "Setting version: $version"
$packageJson = Get-Content package.json | ConvertFrom-Json
$packageJson.version = $version
$packageJson | ConvertTo-Json -Depth 10 | Set-Content package.json
- name: Build and Publish to R2 (Windows)
if: matrix.os == 'windows-latest'
uses: nick-invision/retry@v3.0.2
with:
timeout_minutes: 30
max_attempts: 3
retry_on: error
command: |
pnpm run publish:win:alpha
on_retry_command: pnpm cache delete
- name: Build and Publish to R2 (macOS)
if: matrix.os == 'macos-26'
uses: nick-invision/retry@v3.0.2
with:
timeout_minutes: 30
max_attempts: 3
retry_on: error
command: |
pnpm run publish:mac:alpha
on_retry_command: pnpm cache delete
- name: Build and Publish to R2 (Linux)
if: matrix.os == 'ubuntu-latest'
uses: nick-invision/retry@v3.0.2
with:
timeout_minutes: 30
max_attempts: 3
retry_on: error
command: |
pnpm run publish:linux:alpha
on_retry_command: pnpm cache delete
- name: Build and Publish to R2 (Linux ARM64)
if: matrix.os == 'ubuntu-latest'
uses: nick-invision/retry@v3.0.2
with:
timeout_minutes: 30
max_attempts: 3
retry_on: error
command: |
pnpm run publish:linux-arm64:alpha
on_retry_command: pnpm cache delete
+16 -12
View File
@@ -15,10 +15,12 @@ jobs:
version: ${{ steps.version.outputs.version }} version: ${{ steps.version.outputs.version }}
steps: steps:
- name: Checkout git repo - name: Checkout git repo
uses: actions/checkout@v6 uses: actions/checkout@v1
- name: Install Node and PNPM - name: Install Node and PNPM
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4.1.0
with:
version: 9
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
@@ -113,14 +115,16 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [windows-latest, macos-26, ubuntu-latest] os: [windows-latest, macos-latest, ubuntu-latest]
steps: steps:
- name: Checkout git repo - name: Checkout git repo
uses: actions/checkout@v6 uses: actions/checkout@v1
- name: Install Node and PNPM - name: Install Node and PNPM
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4.1.0
with:
version: 9
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
@@ -142,7 +146,7 @@ jobs:
if: matrix.os == 'windows-latest' if: matrix.os == 'windows-latest'
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: nick-invision/retry@v3.0.2 uses: nick-invision/retry@v2.8.2
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
@@ -152,10 +156,10 @@ jobs:
on_retry_command: pnpm cache delete on_retry_command: pnpm cache delete
- name: Build and Publish releases (macOS) - name: Build and Publish releases (macOS)
if: matrix.os == 'macos-26' if: matrix.os == 'macos-latest'
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: nick-invision/retry@v3.0.2 uses: nick-invision/retry@v2.8.2
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
@@ -168,7 +172,7 @@ jobs:
if: matrix.os == 'ubuntu-latest' if: matrix.os == 'ubuntu-latest'
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: nick-invision/retry@v3.0.2 uses: nick-invision/retry@v2.8.2
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
@@ -181,7 +185,7 @@ jobs:
if: matrix.os == 'ubuntu-latest' if: matrix.os == 'ubuntu-latest'
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: nick-invision/retry@v3.0.2 uses: nick-invision/retry@v2.8.2
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
@@ -195,7 +199,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout git repo - name: Checkout git repo
uses: actions/checkout@v6 uses: actions/checkout@v1
- name: Edit release with commits and title - name: Edit release with commits and title
shell: pwsh shell: pwsh
@@ -342,7 +346,7 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout git repo - name: Checkout git repo
uses: actions/checkout@v6 uses: actions/checkout@v1
- name: Delete existing prereleases - name: Delete existing prereleases
shell: pwsh shell: pwsh
+7 -10
View File
@@ -4,11 +4,6 @@ permissions: write-all
on: on:
workflow_dispatch: workflow_dispatch:
inputs:
tag:
description: 'Docker image tag (e.g. 1.12.0 or latest)'
required: true
type: string
push: push:
tags: tags:
- 'v*.*.*' - 'v*.*.*'
@@ -25,7 +20,7 @@ jobs:
packages: write packages: write
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v6 uses: actions/checkout@v4
- name: Log in to the Container registry - name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with: with:
@@ -38,10 +33,11 @@ jobs:
with: with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }} images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: | tags: |
type=raw,value=${{ inputs.tag }},enable=${{ github.event_name == 'workflow_dispatch' }} type=ref,event=branch
type=semver,pattern={{version}},enable=${{ github.event_name == 'push' }} type=ref,event=pr
type=semver,pattern={{major}}.{{minor}},enable=${{ github.event_name == 'push' }} type=semver,pattern={{version}}
type=semver,pattern={{major}},enable=${{ github.event_name == 'push' }} type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
- name: Set up QEMU - name: Set up QEMU
uses: docker/setup-qemu-action@v3 uses: docker/setup-qemu-action@v3
- name: Setup Docker buildx - name: Setup Docker buildx
@@ -55,4 +51,5 @@ jobs:
labels: ${{ steps.meta.outputs.labels }} labels: ${{ steps.meta.outputs.labels }}
platforms: | platforms: |
linux/amd64 linux/amd64
linux/arm/v7
linux/arm64/v8 linux/arm64/v8
+1 -1
View File
@@ -15,7 +15,7 @@ jobs:
packages: write packages: write
steps: steps:
- name: Checkout repository - name: Checkout repository
uses: actions/checkout@v6 uses: actions/checkout@v4
- name: Log in to the Container registry - name: Log in to the Container registry
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1 uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
with: with:
+6 -4
View File
@@ -12,10 +12,12 @@ jobs:
steps: steps:
- name: Checkout git repo - name: Checkout git repo
uses: actions/checkout@v6 uses: actions/checkout@v1
- name: Install Node and PNPM - name: Install Node and PNPM
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4.1.0
with:
version: 9
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
@@ -23,7 +25,7 @@ jobs:
- name: Build and Publish releases - name: Build and Publish releases
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: nick-invision/retry@v3.0.2 uses: nick-invision/retry@v2.8.2
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
@@ -35,7 +37,7 @@ jobs:
- name: Build and Publish releases (arm64) - name: Build and Publish releases (arm64)
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: nick-invision/retry@v3.0.2 uses: nick-invision/retry@v2.8.2
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
+6 -5
View File
@@ -8,23 +8,24 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [macos-26] os: [macos-latest]
steps: steps:
- name: Checkout git repo - name: Checkout git repo
uses: actions/checkout@v6 uses: actions/checkout@v1
- name: Install Node and PNPM - name: Install Node and PNPM
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4.1.0
with:
version: 9
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
- name: Build and Publish releases - name: Build and Publish releases
env: env:
NODE_OPTIONS: --max-old-space-size=4096
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: nick-invision/retry@v3.0.2 uses: nick-invision/retry@v2.8.2
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
+14 -16
View File
@@ -1,17 +1,14 @@
name: Publish (PR) name: Publish (PR)
on: on:
workflow_dispatch:
pull_request: pull_request:
branches: branches:
- development - development
paths: paths:
- 'src/**' - 'src/**'
- 'electron-builder*.yml'
jobs: jobs:
wait-for-lint: wait-for-lint:
if: github.event_name == 'pull_request'
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Wait for Test workflow to complete - name: Wait for Test workflow to complete
@@ -25,26 +22,27 @@ jobs:
publish: publish:
needs: wait-for-lint needs: wait-for-lint
if: always() && (needs.wait-for-lint.result == 'success' || needs.wait-for-lint.result == 'skipped')
runs-on: ${{ matrix.os }} runs-on: ${{ matrix.os }}
strategy: strategy:
matrix: matrix:
os: [macos-26, ubuntu-latest, windows-latest] os: [macos-latest, ubuntu-latest, windows-latest]
steps: steps:
- name: Checkout git repo - name: Checkout git repo
uses: actions/checkout@v6 uses: actions/checkout@v3
- name: Install Node and PNPM - name: Install Node and PNPM
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4.1.0
with:
version: 9
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
- name: Build for Windows - name: Build for Windows
if: ${{ matrix.os == 'windows-latest' }} if: ${{ matrix.os == 'windows-latest' }}
uses: nick-invision/retry@v3.0.2 uses: nick-invision/retry@v2.8.2
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
@@ -54,7 +52,7 @@ jobs:
- name: Build for Linux - name: Build for Linux
if: ${{ matrix.os == 'ubuntu-latest' }} if: ${{ matrix.os == 'ubuntu-latest' }}
uses: nick-invision/retry@v3.0.2 uses: nick-invision/retry@v2.8.2
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
@@ -63,8 +61,8 @@ jobs:
pnpm run package:linux:pr pnpm run package:linux:pr
- name: Build for MacOS - name: Build for MacOS
if: ${{ matrix.os == 'macos-26' }} if: ${{ matrix.os == 'macos-latest' }}
uses: nick-invision/retry@v3.0.2 uses: nick-invision/retry@v2.8.2
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
@@ -84,27 +82,27 @@ jobs:
zip -r dist/linux-binaries.zip dist/*.{AppImage,deb,rpm} zip -r dist/linux-binaries.zip dist/*.{AppImage,deb,rpm}
- name: Zip MacOS Binaries - name: Zip MacOS Binaries
if: ${{ matrix.os == 'macos-26' }} if: ${{ matrix.os == 'macos-latest' }}
run: | run: |
zip -r dist/macos-binaries.zip dist/*.dmg zip -r dist/macos-binaries.zip dist/*.dmg
- name: Upload Windows Binaries - name: Upload Windows Binaries
if: ${{ matrix.os == 'windows-latest' }} if: ${{ matrix.os == 'windows-latest' }}
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v4
with: with:
name: windows-binaries name: windows-binaries
path: dist/windows-binaries.zip path: dist/windows-binaries.zip
- name: Upload Linux Binaries - name: Upload Linux Binaries
if: ${{ matrix.os == 'ubuntu-latest' }} if: ${{ matrix.os == 'ubuntu-latest' }}
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v4
with: with:
name: linux-binaries name: linux-binaries
path: dist/linux-binaries.zip path: dist/linux-binaries.zip
- name: Upload MacOS Binaries - name: Upload MacOS Binaries
if: ${{ matrix.os == 'macos-26' }} if: ${{ matrix.os == 'macos-latest' }}
uses: actions/upload-artifact@v7 uses: actions/upload-artifact@v4
with: with:
name: macos-binaries name: macos-binaries
path: dist/macos-binaries.zip path: dist/macos-binaries.zip
+5 -3
View File
@@ -12,10 +12,12 @@ jobs:
steps: steps:
- name: Checkout git repo - name: Checkout git repo
uses: actions/checkout@v6 uses: actions/checkout@v1
- name: Install Node and PNPM - name: Install Node and PNPM
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4.1.0
with:
version: 9
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
@@ -23,7 +25,7 @@ jobs:
- name: Build and Publish releases - name: Build and Publish releases
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: nick-invision/retry@v3.0.2 uses: nick-invision/retry@v2.8.2
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
+2 -1
View File
@@ -16,5 +16,6 @@ jobs:
- uses: vedantmgoyal9/winget-releaser@main - uses: vedantmgoyal9/winget-releaser@main
with: with:
identifier: jeffvli.Feishin identifier: jeffvli.Feishin
installers-regex: 'Feishin-*-win-(x64|arm64)\.exe' installers-regex: 'Feishin-*-win-x64\.exe'
token: ${{ secrets.WINGET_ACC_TOKEN }} token: ${{ secrets.WINGET_ACC_TOKEN }}
+10 -8
View File
@@ -8,14 +8,16 @@ jobs:
strategy: strategy:
matrix: matrix:
os: [windows-latest, macos-26, ubuntu-latest] os: [windows-latest, macos-latest, ubuntu-latest]
steps: steps:
- name: Checkout git repo - name: Checkout git repo
uses: actions/checkout@v6 uses: actions/checkout@v1
- name: Install Node and PNPM - name: Install Node and PNPM
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4.1.0
with:
version: 9
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
@@ -24,7 +26,7 @@ jobs:
if: matrix.os == 'windows-latest' if: matrix.os == 'windows-latest'
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: nick-invision/retry@v3.0.2 uses: nick-invision/retry@v2.8.2
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
@@ -34,10 +36,10 @@ jobs:
on_retry_command: pnpm cache delete on_retry_command: pnpm cache delete
- name: Build and Publish releases (macOS) - name: Build and Publish releases (macOS)
if: matrix.os == 'macos-26' if: matrix.os == 'macos-latest'
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: nick-invision/retry@v3.0.2 uses: nick-invision/retry@v2.8.2
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
@@ -50,7 +52,7 @@ jobs:
if: matrix.os == 'ubuntu-latest' if: matrix.os == 'ubuntu-latest'
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: nick-invision/retry@v3.0.2 uses: nick-invision/retry@v2.8.2
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
@@ -63,7 +65,7 @@ jobs:
if: matrix.os == 'ubuntu-latest' if: matrix.os == 'ubuntu-latest'
env: env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
uses: nick-invision/retry@v3.0.2 uses: nick-invision/retry@v2.8.2
with: with:
timeout_minutes: 30 timeout_minutes: 30
max_attempts: 3 max_attempts: 3
+5 -6
View File
@@ -12,8 +12,7 @@ jobs:
pull-requests: write pull-requests: write
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: dessant/lock-threads@v6 - uses: dessant/lock-threads@v5
with: with:
process-only: 'issues, prs' process-only: 'issues, prs'
issue-inactive-days: 120 issue-inactive-days: 120
@@ -30,19 +29,19 @@ jobs:
days-before-pr-close: 30 days-before-pr-close: 30
stale-issue-message: > stale-issue-message: >
This issue has been automatically marked as stale because it has not had recent activity. The resources of the Feishin team are limited, and so we are asking for your help. This issue has been automatically marked as stale because it has not had recent activity. The resources of the Feishin team are limited, and so we are asking for your help.
If this is a **bug** and you can still reproduce this error on the <code>development</code> branch, please reply with all of the information you have about it in order to keep the issue open. If this is a **bug** and you can still reproduce this error on the <code>development</code> branch, please reply with all of the information you have about it in order to keep the issue open.
This issue will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions. This issue will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions.
stale-pr-message: > stale-pr-message: >
This PR has been automatically marked as stale because it has not had recent activity. The resources of the Feishin team are limited, and so we are asking for your help. This PR has been automatically marked as stale because it has not had recent activity. The resources of the Feishin team are limited, and so we are asking for your help.
This PR will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions. This PR will automatically be closed in the near future if no further activity occurs. Thank you for all your contributions.
stale-issue-label: 'stale' stale-issue-label: 'stale'
exempt-issue-labels: 'keep,security,enhancement' exempt-issue-labels: 'keep,security'
stale-pr-label: 'stale' stale-pr-label: 'stale'
exempt-pr-labels: 'keep,security' exempt-pr-labels: 'keep,security'
+4 -2
View File
@@ -8,10 +8,12 @@ jobs:
steps: steps:
- name: Check out Git repository - name: Check out Git repository
uses: actions/checkout@v6 uses: actions/checkout@v1
- name: Install Node.js and PNPM - name: Install Node.js and PNPM
uses: pnpm/action-setup@v4 uses: pnpm/action-setup@v4.1.0
with:
version: 9
- name: Install dependencies - name: Install dependencies
run: pnpm install run: pnpm install
+1
View File
@@ -1 +1,2 @@
legacy-peer-deps=true legacy-peer-deps=true
only-built-dependencies=electron,esbuild
+14 -7
View File
@@ -1,9 +1,11 @@
# --- Builder stage # --- Builder stage
FROM node:23-alpine AS builder FROM node:23-alpine as builder
WORKDIR /app WORKDIR /app
# Copy package.json first to cache node_modules # Copy package.json first to cache node_modules
COPY package.json pnpm-lock.yaml pnpm-workspace.yaml . COPY package.json pnpm-lock.yaml .
RUN npm install -g pnpm
RUN pnpm install RUN pnpm install
@@ -12,14 +14,19 @@ COPY . .
RUN pnpm run build:web RUN pnpm run build:web
# --- Production stage # --- Production stage
FROM nginxinc/nginx-unprivileged:alpine-slim FROM nginx:alpine-slim
COPY --chown=nginx:nginx --from=builder /app/out/web /usr/share/nginx/html COPY --chown=nginx:nginx --from=builder /app/out/web /usr/share/nginx/html
COPY --chown=nginx:nginx ./settings.js.template /etc/nginx/templates/settings.js.template COPY ./settings.js.template /etc/nginx/templates/settings.js.template
COPY --chown=nginx:nginx ng.conf.template /etc/nginx/templates/default.conf.template COPY ./ng.conf.template /etc/nginx/templates/default.conf.template
COPY ./docker-entrypoint.sh /docker-entrypoint.sh
ENV SERVER_LOCK=false SERVER_NAME="" SERVER_TYPE="" SERVER_URL="" REMOTE_URL="" RUN chmod +x /docker-entrypoint.sh
ENV LEGACY_AUTHENTICATION="" ANALYTICS_DISABLED="" PUBLIC_PATH="/"
ENV PUBLIC_PATH="/"
ENV LEGACY_AUTHENTICATION="false"
ENV ANALYTICS_DISABLED="false"
EXPOSE 9180 EXPOSE 9180
ENTRYPOINT ["/docker-entrypoint.sh"]
CMD ["nginx", "-g", "daemon off;"] CMD ["nginx", "-g", "daemon off;"]
+3 -16
View File
@@ -43,7 +43,7 @@ Rewrite of [Sonixd](https://github.com/jeffvli/sonixd).
## Screenshots ## Screenshots
<a href="./media/preview_full_screen_player.png"><img src="./media/preview_full_screen_player.png" width="49.5%"/></a> <a href="./media/preview_album_artist_detail.png"><img src="./media/preview_album_artist_detail.png" width="49.5%"/></a> <a href="./media/preview_album_detail.png"><img src="./media/preview_album_detail.png" width="49.5%"/></a> <a href="./media/preview_smart_playlist.png"><img src="./media/preview_smart_playlist.png" width="49.5%"/></a> <a href="https://raw.githubusercontent.com/jeffvli/feishin/development/media/preview_full_screen_player.png"><img src="https://raw.githubusercontent.com/jeffvli/feishin/development/media/preview_full_screen_player.png" width="49.5%"/></a> <a href="https://raw.githubusercontent.com/jeffvli/feishin/development/media/preview_album_artist_detail.png"><img src="https://raw.githubusercontent.com/jeffvli/feishin/development/media/preview_album_artist_detail.png" width="49.5%"/></a> <a href="https://raw.githubusercontent.com/jeffvli/feishin/development/media/preview_album_detail.png"><img src="https://raw.githubusercontent.com/jeffvli/feishin/development/media/preview_album_detail.png" width="49.5%"/></a> <a href="https://raw.githubusercontent.com/jeffvli/feishin/development/media/preview_smart_playlist.png"><img src="https://raw.githubusercontent.com/jeffvli/feishin/development/media/preview_smart_playlist.png" width="49.5%"/></a>
## Getting Started ## Getting Started
@@ -59,11 +59,7 @@ For media keys to work, you will be prompted to allow Feishin to be a Trusted Ac
#### Linux Notes #### Linux Notes
Feishin is available in [Flathub](https://flathub.org/en/apps/org.jeffvli.feishin). We provide a small install script to download the latest `.AppImage`, make it executable, and also download the icons required by Desktop Environments. Finally, it generates a `.desktop` file to add Feishin to your Application Launcher.
Alternatively, you can install it as an Appimage.
We provide a small install script to download the latest `.AppImage`, make it executable, and also download the icons required by Desktop Environments.
Finally, it generates a `.desktop` file to add Feishin to your Application Launcher.
Simply run the installer like this: Simply run the installer like this:
@@ -118,7 +114,6 @@ services:
- SERVER_LOCK=true # When true AND name/type/url are set, only username/password can be toggled - SERVER_LOCK=true # When true AND name/type/url are set, only username/password can be toggled
- SERVER_TYPE=jellyfin # the allowed types are: jellyfin, navidrome, subsonic. These values are case insensitive - SERVER_TYPE=jellyfin # the allowed types are: jellyfin, navidrome, subsonic. These values are case insensitive
- SERVER_URL= # http://address:port or https://address:port - SERVER_URL= # http://address:port or https://address:port
- REMOTE_URL= # http://address or https://address
- LEGACY_AUTHENTICATION=false # When SERVER_LOCK is true, sets the legacy (plaintext) authentication flag for Subsonic/OpenSubsonic servers - LEGACY_AUTHENTICATION=false # When SERVER_LOCK is true, sets the legacy (plaintext) authentication flag for Subsonic/OpenSubsonic servers
- ANALYTICS_DISABLED=true # Set to true to disable Umami analytics tracking - ANALYTICS_DISABLED=true # Set to true to disable Umami analytics tracking
ports: ports:
@@ -139,11 +134,7 @@ services:
4. _Optional_ - To hard code the server url, pass the following environment variables: `SERVER_NAME`, `SERVER_TYPE` (one of `jellyfin` or `navidrome` or `subsonic`), `SERVER_URL`. To prevent users from changing these settings, pass `SERVER_LOCK=true`. This can only be set if all three of the previous values are set. When `SERVER_LOCK=true`, you can also set `LEGACY_AUTHENTICATION=true` or `LEGACY_AUTHENTICATION=false` to configure the legacy authentication flag for the server (only applicable for Subsonic/OpenSubsonic servers). 4. _Optional_ - To hard code the server url, pass the following environment variables: `SERVER_NAME`, `SERVER_TYPE` (one of `jellyfin` or `navidrome` or `subsonic`), `SERVER_URL`. To prevent users from changing these settings, pass `SERVER_LOCK=true`. This can only be set if all three of the previous values are set. When `SERVER_LOCK=true`, you can also set `LEGACY_AUTHENTICATION=true` or `LEGACY_AUTHENTICATION=false` to configure the legacy authentication flag for the server (only applicable for Subsonic/OpenSubsonic servers).
5. _Optional_ - If your server uses a separate public-facing URL than what integrating applications use internally to communicate with your server, such as a separate Navidrome `ShareURL`, set `REMOTE_URL` to said public-facing URL. 5. _Optional_ - To disable Umami analytics tracking in the Docker/web version, set the environment variable `ANALYTICS_DISABLED=true`. When enabled, the analytics script will not be loaded and all tracking will be disabled.
6. _Optional_ - To disable Umami analytics tracking in the Docker/web version, set the environment variable `ANALYTICS_DISABLED=true`. When enabled, the analytics script will not be loaded and all tracking will be disabled.
7. _Optional_ - App settings (theme, language, sidebar options, etc.) can be overridden with environment variables on first run. The variables use the `FS_` prefix (e.g. `FS_GENERAL_THEME=defaultDark`, `FS_GENERAL_LANGUAGE=de`). See [the settings environment variable documentation](docs/ENV_SETTINGS.md) for the full list.
## FAQ ## FAQ
@@ -169,10 +160,6 @@ Feishin supports any music server that implements a [Navidrome](https://www.navi
- [Qm-Music](https://github.com/chenqimiao/qm-music) - [Qm-Music](https://github.com/chenqimiao/qm-music)
- More (?) - More (?)
- [Plex](https://www.plex.tv/media-server-downloads)
- [Feishin fork by lux032](https://github.com/lux032/feishin) - Plex is not natively supported. Use the fork by lux032 to use Plex with Feishin.
### I have the issue "The SUID sandbox helper binary was found, but is not configured correctly" on Linux ### I have the issue "The SUID sandbox helper binary was found, but is not configured correctly" on Linux
This happens when you have user (unprivileged) namespaces disabled (`sysctl kernel.unprivileged_userns_clone` returns 0). You can fix this by either enabling unprivileged namespaces, or by making the `chrome-sandbox` Setuid. This happens when you have user (unprivileged) namespaces disabled (`sysctl kernel.unprivileged_userns_clone` returns 0). You can fix this by either enabling unprivileged namespaces, or by making the `chrome-sandbox` Setuid.
Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 73 KiB

After

Width:  |  Height:  |  Size: 154 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 651 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.5 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 48 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.1 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 277 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 447 B

Binary file not shown.
Binary file not shown.

Before

Width:  |  Height:  |  Size: 422 KiB

After

Width:  |  Height:  |  Size: 176 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 48 KiB

+4 -5
View File
@@ -1,16 +1,15 @@
services: services:
feishin: feishin:
container_name: feishin container_name: feishin
image: "ghcr.io/jeffvli/feishin:latest" image: ghcr.io/jeffvli/feishin:latest
restart: unless-stopped restart: unless-stopped
environment: environment:
- SERVER_NAME=jellyfin # pre-defined server name - SERVER_NAME=jellyfin # pre-defined server name
- SERVER_LOCK=false # When true AND name/type/url are set, only username/password can be toggled - SERVER_LOCK=true # When true AND name/type/url are set, only username/password can be toggled
- SERVER_TYPE=jellyfin # the allowed types are: jellyfin, navidrome, subsonic. These values are case insensitive - SERVER_TYPE=jellyfin # the allowed types are: jellyfin, navidrome, subsonic. These values are case insensitive
- SERVER_URL=http://localhost:8096 # http://address:port or https://address:port - SERVER_URL= # http://address:port or https://address:port
# - REMOTE_URL=http://share.localhost # Used for compatibility with external functionality, such as custom sharing URLs on Navidrome
- LEGACY_AUTHENTICATION=false # When SERVER_LOCK is true, sets the legacyauth flag for server authentication (true or false) - LEGACY_AUTHENTICATION=false # When SERVER_LOCK is true, sets the legacyauth flag for server authentication (true or false)
- ANALYTICS_DISABLED=false # Set to true to disable Umami analytics tracking - ANALYTICS_DISABLED=false # When true, disables analytics
ports: ports:
- 9180:9180 - 9180:9180
# Alternatively, to restrict to only localhost, - 127.0.0.1:9180:8190 # Alternatively, to restrict to only localhost, - 127.0.0.1:9180:8190
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
# Set default values for environment variables if not already set
export LEGACY_AUTHENTICATION=${LEGACY_AUTHENTICATION:-false}
export ANALYTICS_DISABLED=${ANALYTICS_DISABLED:-false}
# Execute the original nginx command
exec "$@"
-141
View File
@@ -1,141 +0,0 @@
# Environment variables for settings (web / Docker)
These variables override app settings **on first run** when no persisted settings exist. They are injected via `settings.js` (from `settings.js.template`) and only apply to the **web** build.
**Format:** All values are strings; booleans use `true`/`false`, numbers are numeric strings. Leave unset or empty to use the default.
---
## General
| Setting | Default | Env variable | Available values / Description |
|-------------|---------|--------------|--------------------------------|
| `general.accent` | `rgb(53, 116, 252)` | `FS_GENERAL_ACCENT` | CSS `rgb(r, g, b)` string (e.g. `rgb(53, 116, 252)`). Invalid values are ignored. |
| `general.albumBackground` | `false` | `FS_GENERAL_ALBUM_BACKGROUND` | `true` / `false` — Show album background image. |
| `general.albumBackgroundBlur` | `3` | `FS_GENERAL_ALBUM_BACKGROUND_BLUR` | Blur amount for album background (number). |
| `general.artistBackground` | `true` | `FS_GENERAL_ARTIST_BACKGROUND` | `true` / `false` — Show artist background image. |
| `general.artistBackgroundBlur` | `3` | `FS_GENERAL_ARTIST_BACKGROUND_BLUR` | Blur amount for artist background (number). |
| `general.blurExplicitImages` | `false` | `FS_GENERAL_BLUR_EXPLICIT_IMAGES` | `true` / `false` — Blur explicit images. |
| `general.combinedLyricsAndVisualizer` | `false` | `FS_GENERAL_COMBINED_LYRICS_AND_VISUALIZER` | `true` / `false` — Combine lyrics and visualizer panel. |
| `general.enableGridMultiSelect` | `false` | `FS_GENERAL_ENABLE_GRID_MULTI_SELECT` | `true` / `false` — Enable multi-select in grid views. |
| `general.externalLinks` | `true` | `FS_GENERAL_EXTERNAL_LINKS` | `true` / `false` — Show external links in UI. |
| `general.followCurrentSong` | `true` | `FS_GENERAL_FOLLOW_CURRENT_SONG` | `true` / `false` — Follow current song in list. |
| `general.followSystemTheme` | `false` | `FS_GENERAL_FOLLOW_SYSTEM_THEME` | `true` / `false` — Use OS light/dark preference. |
| `general.homeFeature` | `true` | `FS_GENERAL_HOME_FEATURE` | `true` / `false` — Show home featured carousel. |
| `general.homeFeatureStyle` | `single` | `FS_GENERAL_HOME_FEATURE_STYLE` | `multiple` / `single` — Home featured carousel style. |
| `general.language` | `en` | `FS_GENERAL_LANGUAGE` | UI language code (e.g. `en`, `de`, `fr`). |
| `general.theme` | `defaultDark` | `FS_GENERAL_THEME` | One of: `ayuDark`, `ayuLight`, `catppuccinLatte`, `catppuccinMocha`, `defaultDark`, `defaultLight`, `dracula`, `githubDark`, `githubLight`, `glassyDark`, `gruvboxDark`, `gruvboxLight`, `highContrastDark`, `highContrastLight`, `materialDark`, `materialLight`, `monokai`, `nightOwl`, `nord`, `oneDark`, `rosePine`, `rosePineDawn`, `rosePineMoon`, `shadesOfPurple`, `solarizedDark`, `solarizedLight`, `tokyoNight`, `vscodeDarkPlus`, `vscodeLightPlus`. |
| `general.themeDark` | `defaultDark` | `FS_GENERAL_THEME_DARK` | Same as theme (used when system is dark). |
| `general.themeLight` | `defaultLight` | `FS_GENERAL_THEME_LIGHT` | Same as theme (used when system is light). |
| `general.lastfmApiKey` | *(empty)* | `FS_GENERAL_LASTFM_API_KEY` | Last.fm API key. |
| `general.lastFM` | `true` | `FS_GENERAL_LAST_FM` | `true` / `false` — Enable Last.fm. |
| `general.listenBrainz` | `true` | `FS_GENERAL_LISTEN_BRAINZ` | `true` / `false` — ListenBrainz links. |
| `general.musicBrainz` | `true` | `FS_GENERAL_MUSIC_BRAINZ` | `true` / `false` — MusicBrainz links. |
| `general.nativeAspectRatio` | `false` | `FS_GENERAL_NATIVE_ASPECT_RATIO` | `true` / `false` — Use native cover art aspect ratio. |
| `general.pathReplace` | *(empty)* | `FS_GENERAL_PATH_REPLACE` | Path pattern to replace (e.g. server path in Docker). |
| `general.pathReplaceWith` | *(empty)* | `FS_GENERAL_PATH_REPLACE_WITH` | Replacement path. |
| `general.playerbarOpenDrawer` | `false` | `FS_GENERAL_PLAYERBAR_OPEN_DRAWER` | `true` / `false` — Open queue/lyrics as drawer from player bar. |
| `general.primaryShade` | `6` | `FS_GENERAL_PRIMARY_SHADE` | Mantine primary shade 09 (number). |
| `general.qobuz` | `true` | `FS_GENERAL_QOBUZ` | `true` / `false` — Qobuz links. |
| `general.resume` | `true` | `FS_GENERAL_RESUME` | `true` / `false` — Resume playback on load. |
| `general.showLyricsInSidebar` | `true` | `FS_GENERAL_SHOW_LYRICS_IN_SIDEBAR` | `true` / `false` — Show lyrics in sidebar. |
| `general.showRatings` | `true` | `FS_GENERAL_SHOW_RATINGS` | `true` / `false` — Show star ratings. |
| `general.showVisualizerInSidebar` | `true` | `FS_GENERAL_SHOW_VISUALIZER_IN_SIDEBAR` | `true` / `false` — Show visualizer in sidebar. |
| `general.sidebarCollapsedNavigation` | `true` | `FS_GENERAL_SIDEBAR_COLLAPSED_NAVIGATION` | `true` / `false` — Start with collapsed sidebar nav. |
| `general.sidebarCollapseShared` | `false` | `FS_GENERAL_SIDEBAR_COLLAPSE_SHARED` | `true` / `false` — Share sidebar collapse state. |
| `general.sidebarPlaylistFolders` | `true` | `FS_GENERAL_SIDEBAR_PLAYLIST_FOLDERS` | `true` / `false` — Group playlists into folders by name separator. |
| `general.sidebarPlaylistFolderSeparator` | `/` | `FS_GENERAL_SIDEBAR_PLAYLIST_FOLDER_SEPARATOR` | Character or string that separates folder levels in a playlist name. Empty = use default. |
| `general.sidebarPlaylistFolderTreeIndent` | `16` | `FS_GENERAL_SIDEBAR_PLAYLIST_FOLDER_TREE_INDENT` | Pixels each tree level is indented (064). |
| `general.sidebarPlaylistFolderTreeLineColor` | *(empty)* | `FS_GENERAL_SIDEBAR_PLAYLIST_FOLDER_TREE_LINE_COLOR` | CSS color for tree connecting lines. Empty = theme default. |
| `general.sidebarPlaylistFolderView` | `tree` | `FS_GENERAL_SIDEBAR_PLAYLIST_FOLDER_VIEW` | `single` / `tree` / `navigation` — How folders are displayed in the sidebar. |
| `general.sidebarPlaylistList` | `true` | `FS_GENERAL_SIDEBAR_PLAYLIST_LIST` | `true` / `false` — Show playlist list in sidebar. |
| `general.sidebarPlaylistMode` | `expanded` | `FS_GENERAL_SIDEBAR_PLAYLIST_MODE` | `compact` / `expanded` — Sidebar playlist row layout. |
| `general.sidebarPlaylistSorting` | `false` | `FS_GENERAL_SIDEBAR_PLAYLIST_SORTING` | `true` / `false` — Enable playlist sorting in sidebar. |
| `general.sideQueueType` | `sideQueue` | `FS_GENERAL_SIDE_QUEUE_TYPE` | `sideDrawerQueue` / `sideQueue` — Side play queue style. |
| `general.sideQueueLayout` | `horizontal` | `FS_GENERAL_SIDE_QUEUE_LAYOUT` | `horizontal` / `vertical` — Attached side queue layout orientation. |
| `general.useThemeAccentColor` | `false` | `FS_GENERAL_USE_THEME_ACCENT_COLOR` | `true` / `false` — Use themes accent color instead of custom. |
| `general.useThemePrimaryShade` | `true` | `FS_GENERAL_USE_THEME_PRIMARY_SHADE` | `true` / `false` — Use themes primary shade. |
| `general.zoomFactor` | `100` | `FS_GENERAL_ZOOM_FACTOR` | UI zoom percentage (number). |
---
## Playback
| Setting path | Default | Env variable | Available values / Description |
|-------------|---------|--------------|--------------------------------|
| `playback.mediaSession` | `false` | `FS_PLAYBACK_MEDIA_SESSION` | `true` / `false` — Media Session API (e.g. browser/media keys). |
| `playback.webAudio` | `true` | `FS_PLAYBACK_WEB_AUDIO` | `true` / `false` — Use Web Audio for playback. |
| `playback.audioFadeOnStatusChange` | `true` | `FS_PLAYBACK_AUDIO_FADE_ON_STATUS_CHANGE` | `true` / `false` — Fade on play/pause. |
| `playback.preservePitch` | `true` | `FS_PLAYBACK_PRESERVE_PITCH` | `true` / `false` — Preserve pitch when changing speed. |
| `playback.scrobble.enabled` | `true` | `FS_PLAYBACK_SCROBBLE_ENABLED` | `true` / `false` — Enable scrobbling. |
| `playback.scrobble.notify` | `false` | `FS_PLAYBACK_SCROBBLE_NOTIFY` | `true` / `false` — Scrobble notifications. |
| `playback.scrobble.scrobbleAtDuration` | `240` | `FS_PLAYBACK_SCROBBLE_AT_DURATION` | Seconds of playback before scrobble. |
| `playback.scrobble.scrobbleAtPercentage` | `75` | `FS_PLAYBACK_SCROBBLE_AT_PERCENTAGE` | Percentage of track before scrobble. |
| `playback.transcode.enabled` | `false` | `FS_PLAYBACK_TRANSCODE_ENABLED` | `true` / `false` — Enable transcoding. |
| `playback.transcode.format` | *(unset)* | `FS_PLAYBACK_TRANSCODE_FORMAT` | Transcode format string (codec/container), e.g. server-specific value. Empty = use default. |
| `playback.transcode.bitrate` | *(unset)* | `FS_PLAYBACK_TRANSCODE_BITRATE` | Transcode bitrate (number, kbps or as defined by server). |
| `playback.filters` | `[]` | `FS_PLAYBACK_FILTERS` | JSON array of player filters: each object needs `id`, `field`, `operator`, `value`; optional `isEnabled`. Invalid JSON or shape is ignored. |
---
## Discord
| Setting path | Default | Env variable | Available values / Description |
|-------------|---------|--------------|--------------------------------|
| `discord.enabled` | `false` | `FS_DISCORD_ENABLED` | `true` / `false` — Discord rich presence. |
| `discord.clientId` | *(built-in)* | `FS_DISCORD_CLIENT_ID` | Custom Discord application ID. |
| `discord.displayType` | `feishin` | `FS_DISCORD_DISPLAY_TYPE` | `artist` / `feishin` / `song`. |
| `discord.linkType` | `none` | `FS_DISCORD_LINK_TYPE` | `last_fm` / `musicbrainz` / `musicbrainz_last_fm` / `none`. |
| `discord.showAsListening` | `false` | `FS_DISCORD_SHOW_AS_LISTENING` | `true` / `false`. |
| `discord.showPaused` | `true` | `FS_DISCORD_SHOW_PAUSED` | `true` / `false` — Show paused state. |
| `discord.showServerImage` | `false` | `FS_DISCORD_SHOW_SERVER_IMAGE` | `true` / `false`. |
| `discord.showStateIcon` | `true` | `FS_DISCORD_SHOW_STATE_ICON` | `true` / `false`. |
---
## Lyrics
| Setting path | Default | Env variable | Available values / Description |
|-------------|---------|--------------|--------------------------------|
| `lyrics.fetch` | `true` | `FS_LYRICS_FETCH` | `true` / `false` — Fetch lyrics. |
| `lyrics.follow` | `true` | `FS_LYRICS_FOLLOW` | `true` / `false` — Follow current line. |
| `lyrics.delayMs` | `0` | `FS_LYRICS_DELAY_MS` | Sync delay in milliseconds. |
| `lyrics.preferLocalLyrics` | `true` | `FS_LYRICS_PREFER_LOCAL` | `true` / `false` — Prefer local lyric files. |
| `lyrics.showMatch` | `true` | `FS_LYRICS_SHOW_MATCH` | `true` / `false`. |
| `lyrics.showProvider` | `true` | `FS_LYRICS_SHOW_PROVIDER` | `true` / `false`. |
| `lyrics.enableAutoTranslation` | `false` | `FS_LYRICS_ENABLE_AUTO_TRANSLATION` | `true` / `false`. |
| `lyrics.translationApiKey` | *(empty)* | `FS_LYRICS_TRANSLATION_API_KEY` | API key for lyric translation. |
| `lyrics.translationTargetLanguage` | `en` | `FS_LYRICS_TRANSLATION_TARGET_LANGUAGE` | Target language code. |
| `lyrics.alignment` | `center` | `FS_LYRICS_ALIGNMENT` | `center` / `left` / `right`. |
---
## Auto DJ
| Setting path | Default | Env variable | Available values / Description |
|-------------|---------|--------------|--------------------------------|
| `autoDJ.albumStrategy` | `similar` | `FS_AUTO_DJ_ALBUM_STRATEGY` | `similar` / `library_random`. |
| `autoDJ.enabled` | `false` | `FS_AUTO_DJ_ENABLED` | `true` / `false`. |
| `autoDJ.itemCount` | `5` | `FS_AUTO_DJ_ITEM_COUNT` | Number of items to add. |
| `autoDJ.mode` | `songs` | `FS_AUTO_DJ_MODE` | `songs` / `albums`. |
| `autoDJ.songStrategy` | `similar` | `FS_AUTO_DJ_SONG_STRATEGY` | `similar` / `library_random`. |
| `autoDJ.timing` | `1` | `FS_AUTO_DJ_TIMING` | Timing value (number). |
---
## CSS
| Setting path | Default | Env variable | Available values / Description |
|-------------|---------|--------------|--------------------------------|
| `css.content` | *(empty)* | `FS_CSS_CONTENT` | Custom CSS string (sanitized like in-app custom CSS). Set `FS_CSS_ENABLED=true` to apply. |
| `css.enabled` | `false` | `FS_CSS_ENABLED` | `true` / `false` — Enable custom CSS. |
---
## Font
| Setting path | Default | Env variable | Available values / Description |
|-------------|---------|--------------|--------------------------------|
| `font.type` | `builtIn` | `FS_FONT_TYPE` | `builtIn` / `system` / `custom`. |
| `font.builtIn` | `Inter` | `FS_FONT_BUILT_IN` | Built-in font name. |
| `font.system` | *(empty)* | `FS_FONT_SYSTEM` | System font name (when type is `system`). |
-74
View File
@@ -1,74 +0,0 @@
appId: org.jeffvli.feishin
productName: Feishin
artifactName: ${productName}-${version}-${os}-${arch}.${ext}
electronVersion: 41.7.0
directories:
buildResources: assets
files:
- 'out/**/*'
- 'package.json'
extraResources:
- assets/**
asarUnpack:
- resources/**
win:
target:
- target: zip
arch:
- x64
- arm64
- target: nsis
arch:
- x64
- arm64
icon: assets/icons/icon.ico
nsis:
allowToChangeInstallationDirectory: true
oneClick: false
shortcutName: ${productName}
uninstallDisplayName: ${productName}
createDesktopShortcut: always
mac:
target:
- target: dmg
arch:
- arm64
- x64
- target: zip
arch:
- arm64
- x64
icon: media/feishin.icon
type: distribution
hardenedRuntime: false
identity: '-'
gatekeeperAssess: false
notarize: false
extendInfo:
NSAudioCaptureUsageDescription: 'System audio access is required for mpv visualizer capture in Feishin'
NSLocalNetworkUsageDescription: 'Local network is necessary for accessing servers hosted on the same system as Feishin'
dmg:
contents: [{ x: 130, y: 220 }, { x: 410, y: 220, type: link, path: /Applications }]
linux:
target:
- AppImage
- deb
- tar.xz
category: AudioVideo;Audio;Player
icon: assets/icons/icon.png
artifactName: ${productName}-${os}-${arch}.${ext}
toolsets:
appimage: '1.0.3'
npmRebuild: false
publish:
provider: s3
bucket: feishin-nightly
channel: alpha
endpoint: https://065f090c64de2dc707dd70ac72db9669.r2.cloudflarestorage.com
+12 -27
View File
@@ -1,7 +1,7 @@
appId: org.jeffvli.feishin appId: org.jeffvli.feishin
productName: Feishin productName: Feishin
artifactName: ${productName}-${version}-${os}-${arch}.${ext} artifactName: ${productName}-${version}-${os}-${arch}.${ext}
electronVersion: 41.7.0 electronVersion: 39.2.7
directories: directories:
buildResources: assets buildResources: assets
files: files:
@@ -13,15 +13,9 @@ asarUnpack:
- resources/** - resources/**
win: win:
target: target:
- target: zip - zip
arch: - nsis
- x64 icon: assets/icons/icon.png
- arm64
- target: nsis
arch:
- x64
- arm64
icon: assets/icons/icon.ico
nsis: nsis:
allowToChangeInstallationDirectory: true allowToChangeInstallationDirectory: true
@@ -32,23 +26,17 @@ nsis:
mac: mac:
target: target:
- target: dmg target: default
arch: arch:
- arm64 - arm64
- x64 - x64
- target: zip icon: assets/icons/icon.icns
arch:
- arm64
- x64
icon: media/feishin.icon
type: distribution type: distribution
hardenedRuntime: false hardenedRuntime: true
identity: '-' entitlements: assets/entitlements.mac.plist
entitlementsInherit: assets/entitlements.mac.plist
gatekeeperAssess: false gatekeeperAssess: false
notarize: false notarize: false
extendInfo:
NSAudioCaptureUsageDescription: 'System audio access is required for mpv visualizer capture in Feishin'
NSLocalNetworkUsageDescription: 'Local network is necessary for accessing servers hosted on the same system as Feishin'
dmg: dmg:
contents: [{ x: 130, y: 220 }, { x: 410, y: 220, type: link, path: /Applications }] contents: [{ x: 130, y: 220 }, { x: 410, y: 220, type: link, path: /Applications }]
@@ -62,9 +50,6 @@ linux:
icon: assets/icons/icon.png icon: assets/icons/icon.png
artifactName: ${productName}-${os}-${arch}.${ext} artifactName: ${productName}-${os}-${arch}.${ext}
toolsets:
appimage: '1.0.3'
npmRebuild: false npmRebuild: false
publish: publish:
provider: github provider: github
+12 -28
View File
@@ -1,7 +1,7 @@
appId: org.jeffvli.feishin appId: org.jeffvli.feishin
productName: Feishin productName: Feishin
artifactName: ${productName}-${version}-${os}-${arch}.${ext} artifactName: ${productName}-${version}-${os}-${arch}.${ext}
electronVersion: 41.7.0 electronVersion: 39.2.7
directories: directories:
buildResources: assets buildResources: assets
files: files:
@@ -13,15 +13,9 @@ asarUnpack:
- resources/** - resources/**
win: win:
target: target:
- target: zip - zip
arch: - nsis
- x64 icon: assets/icons/icon.png
- arm64
- target: nsis
arch:
- x64
- arm64
icon: assets/icons/icon.ico
nsis: nsis:
allowToChangeInstallationDirectory: true allowToChangeInstallationDirectory: true
@@ -32,23 +26,17 @@ nsis:
mac: mac:
target: target:
- target: dmg target: default
arch: arch:
- arm64 - arm64
- x64 - x64
- target: zip icon: assets/icons/icon.icns
arch:
- arm64
- x64
icon: media/feishin.icon
type: distribution type: distribution
hardenedRuntime: false hardenedRuntime: true
identity: '-' entitlements: assets/entitlements.mac.plist
entitlementsInherit: assets/entitlements.mac.plist
gatekeeperAssess: false gatekeeperAssess: false
notarize: false notarize: false
extendInfo:
NSAudioCaptureUsageDescription: 'System audio access is required for mpv visualizer capture in Feishin'
NSLocalNetworkUsageDescription: 'Local network is necessary for accessing servers hosted on the same system as Feishin'
dmg: dmg:
contents: [{ x: 130, y: 220 }, { x: 410, y: 220, type: link, path: /Applications }] contents: [{ x: 130, y: 220 }, { x: 410, y: 220, type: link, path: /Applications }]
@@ -62,11 +50,7 @@ linux:
icon: assets/icons/icon.png icon: assets/icons/icon.png
artifactName: ${productName}-${os}-${arch}.${ext} artifactName: ${productName}-${os}-${arch}.${ext}
toolsets:
appimage: '1.0.3'
npmRebuild: false npmRebuild: false
afterAllArtifactBuild: scripts/after-all-artifact-build.mjs
publish: publish:
provider: github provider: github
owner: jeffvli owner: jeffvli
+2 -11
View File
@@ -1,13 +1,11 @@
import react from '@vitejs/plugin-react';
import { externalizeDepsPlugin, UserConfig } from 'electron-vite'; import { externalizeDepsPlugin, UserConfig } from 'electron-vite';
import { resolve } from 'path'; import { resolve } from 'path';
import conditionalImportPlugin from 'vite-plugin-conditional-import'; import conditionalImportPlugin from 'vite-plugin-conditional-import';
import dynamicImportPlugin from 'vite-plugin-dynamic-import'; import dynamicImportPlugin from 'vite-plugin-dynamic-import';
import { ViteEjsPlugin } from 'vite-plugin-ejs'; import { ViteEjsPlugin } from 'vite-plugin-ejs';
import { createReactPlugin } from './vite.react-plugin';
const currentOSEnv = process.platform; const currentOSEnv = process.platform;
const electronRendererTarget = 'chrome87';
const config: UserConfig = { const config: UserConfig = {
main: { main: {
@@ -38,9 +36,6 @@ const config: UserConfig = {
}, },
}, },
preload: { preload: {
build: {
sourcemap: true,
},
plugins: [externalizeDepsPlugin()], plugins: [externalizeDepsPlugin()],
resolve: { resolve: {
alias: { alias: {
@@ -53,11 +48,7 @@ const config: UserConfig = {
build: { build: {
cssMinify: 'esbuild', cssMinify: 'esbuild',
minify: 'esbuild', minify: 'esbuild',
modulePreload: {
polyfill: false,
},
sourcemap: true, sourcemap: true,
target: electronRendererTarget,
}, },
css: { css: {
modules: { modules: {
@@ -65,7 +56,7 @@ const config: UserConfig = {
localsConvention: 'camelCase', localsConvention: 'camelCase',
}, },
}, },
plugins: [createReactPlugin(), ViteEjsPlugin({ web: false })], plugins: [react(), ViteEjsPlugin({ web: false })],
resolve: { resolve: {
alias: { alias: {
'/@/i18n': resolve('src/i18n'), '/@/i18n': resolve('src/i18n'),
+1 -1
View File
@@ -25,7 +25,7 @@ export default tseslint.config(
'react-refresh': eslintPluginReactRefresh, 'react-refresh': eslintPluginReactRefresh,
}, },
rules: { rules: {
...eslintPluginReactHooks.configs['recommended-latest'].rules, ...eslintPluginReactHooks.configs.recommended.rules,
...eslintPluginReactRefresh.configs.vite.rules, ...eslintPluginReactRefresh.configs.vite.rules,
'@typescript-eslint/explicit-function-return-type': 'off', '@typescript-eslint/explicit-function-return-type': 'off',
'@typescript-eslint/no-duplicate-enum-values': 'off', '@typescript-eslint/no-duplicate-enum-values': 'off',
Executable → Regular
-1
View File
@@ -1,4 +1,3 @@
#!/usr/bin/env xdg-open
[Desktop Entry] [Desktop Entry]
Name=Feishin Name=Feishin
GenericName=Music player GenericName=Music player
Binary file not shown.
Binary file not shown.

After

Width:  |  Height:  |  Size: 118 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 81 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 77 KiB

-1
View File
@@ -1 +0,0 @@
<svg xmlns="http://www.w3.org/2000/svg" width="512" height="512"><g style="display:inline" transform="translate(-53.452 -43.352)scale(1.11813)"><circle cx="256" cy="240.312" r="21.5" style="opacity:1;fill:#000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.19597;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke;filter:url(#filter249)"/><path d="M220.85 277.951 183.5 315.6l36 36.1 20-19.7s5.856-6.2 16.5-6.2 16.5 6.2 16.5 6.2l20 19.7 36-36.1-37.35-37.649A51.5 51.5 0 0 1 256 291.812a51.5 51.5 0 0 1-35.15-13.86" style="opacity:1;fill:#000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter249)"/><path d="M256 145.4a25.7 25.7 0 0 0-18.229 7.551L66.97 323.47A25.42 25.42 0 0 0 59.5 341.5c0 14.083 11.417 25.5 25.5 25.5a25.42 25.42 0 0 0 18.031-7.469l103.895-103.597a51.5 51.5 0 0 1-2.426-15.621 51.5 51.5 0 0 1 51.5-51.5 51.5 51.5 0 0 1 51.5 51.5 51.5 51.5 0 0 1-2.426 15.62L408.97 359.532A25.42 25.42 0 0 0 427 367c14.083 0 25.5-11.417 25.5-25.5a25.42 25.42 0 0 0-7.469-18.031L274.23 152.95a25.7 25.7 0 0 0-18.229-7.55" style="display:inline;opacity:1;fill:#000;fill-opacity:1;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;paint-order:markers fill stroke;filter:url(#filter249)"/></g></svg>

Before

Width:  |  Height:  |  Size: 1.4 KiB

-202
View File
@@ -1,202 +0,0 @@
{
"fill-specializations" : [
{
"value" : {
"linear-gradient" : [
"display-p3:0.87416,0.87416,0.87416,1.00000",
"display-p3:0.99575,0.99575,0.99575,1.00000"
],
"orientation" : {
"start" : {
"x" : 0.5,
"y" : 1
},
"stop" : {
"x" : 0.5,
"y" : 0.3
}
}
}
},
{
"appearance" : "dark",
"value" : "system-dark"
}
],
"groups" : [
{
"blend-mode-specializations" : [
{
"appearance" : "tinted",
"value" : "normal"
}
],
"blur-material-specializations" : [
{
"value" : 0.7
},
{
"appearance" : "dark",
"value" : 0.7
},
{
"appearance" : "tinted",
"value" : null
}
],
"hidden" : false,
"layers" : [
{
"blend-mode-specializations" : [
{
"appearance" : "tinted",
"value" : "normal"
}
],
"fill-specializations" : [
{
"value" : {
"solid" : "extended-gray:0.00000,1.00000"
}
},
{
"appearance" : "dark",
"value" : {
"linear-gradient" : [
"display-p3:0.78674,0.78674,0.78674,1.00000",
"display-p3:0.87416,0.87416,0.87416,1.00000"
],
"orientation" : {
"start" : {
"x" : 0.5,
"y" : 1
},
"stop" : {
"x" : 0.5,
"y" : 0
}
}
}
},
{
"appearance" : "tinted",
"value" : {
"solid" : "gray:1.00000,1.00000"
}
}
],
"glass-specializations" : [
{
"value" : true
},
{
"appearance" : "dark",
"value" : true
},
{
"appearance" : "tinted",
"value" : true
}
],
"hidden" : false,
"image-name" : "feishin.svg",
"name" : "feishin",
"opacity-specializations" : [
{
"value" : 1
},
{
"appearance" : "tinted",
"value" : 1
}
],
"position" : {
"scale" : 0.79,
"translation-in-points" : [
18,
-2
]
}
}
],
"lighting-specializations" : [
{
"value" : "individual"
},
{
"appearance" : "tinted",
"value" : "combined"
}
],
"position" : {
"scale" : 2.2,
"translation-in-points" : [
0,
0
]
},
"shadow-specializations" : [
{
"value" : {
"kind" : "neutral",
"opacity" : 1
}
},
{
"appearance" : "dark",
"value" : {
"kind" : "layer-color",
"opacity" : 0.5
}
},
{
"appearance" : "tinted",
"value" : {
"kind" : "neutral",
"opacity" : 1
}
}
],
"specular-specializations" : [
{
"value" : false
},
{
"appearance" : "dark",
"value" : false
},
{
"appearance" : "tinted",
"value" : true
}
],
"translucency-specializations" : [
{
"value" : {
"enabled" : true,
"value" : 0.29
}
},
{
"appearance" : "dark",
"value" : {
"enabled" : false,
"value" : 0.29
}
},
{
"appearance" : "tinted",
"value" : {
"enabled" : true,
"value" : 0.5
}
}
]
}
],
"supported-platforms" : {
"squares" : [
"macOS"
]
}
}
File diff suppressed because one or more lines are too long

Before

Width:  |  Height:  |  Size: 214 KiB

BIN
View File
Binary file not shown.
BIN
View File
Binary file not shown.

After

Width:  |  Height:  |  Size: 101 KiB

-104
View File
@@ -1,104 +0,0 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<!-- Created with Inkscape (http://www.inkscape.org/) -->
<svg
width="512"
height="512"
viewBox="0 0 512 512"
version="1.1"
id="svg1"
xml:space="preserve"
xmlns:xlink="http://www.w3.org/1999/xlink"
xmlns="http://www.w3.org/2000/svg"
xmlns:svg="http://www.w3.org/2000/svg"><defs
id="defs1"><linearGradient
id="linearGradient1"><stop
style="stop-color:#dfdfdf;stop-opacity:1;"
offset="0"
id="stop1" /><stop
style="stop-color:#ffffff;stop-opacity:1;"
offset="1"
id="stop2" /></linearGradient><filter
style="color-interpolation-filters:sRGB"
id="filter249"
x="-0.61395349"
y="-0.61395349"
width="2.227907"
height="2.5069767"><feFlood
result="flood"
in="SourceGraphic"
flood-opacity="0.498039"
flood-color="rgb(0,0,0)"
id="feFlood247" /><feGaussianBlur
result="blur"
in="SourceGraphic"
stdDeviation="1.000000"
id="feGaussianBlur247" /><feOffset
result="offset"
in="blur"
dx="0.000000"
dy="2"
id="feOffset247" /><feComposite
result="comp1"
operator="in"
in="flood"
in2="offset"
id="feComposite248" /><feComposite
result="fbSourceGraphic"
operator="over"
in="SourceGraphic"
id="feComposite249"
in2="comp1" /><feColorMatrix
result="fbSourceGraphicAlpha"
in="fbSourceGraphic"
values="0 0 0 -1 0 0 0 0 -1 0 0 0 0 -1 0 0 0 0 1 0"
id="feColorMatrix122" /><feFlood
id="feFlood122"
result="flood"
in="fbSourceGraphic"
flood-opacity="0.196078"
flood-color="rgb(0,0,0)" /><feGaussianBlur
id="feGaussianBlur122"
result="blur"
in="fbSourceGraphic"
stdDeviation="10.000000" /><feOffset
id="feOffset122"
result="offset"
in="blur"
dx="0.000000"
dy="10.000000" /><feComposite
id="feComposite122"
result="comp1"
operator="in"
in="flood"
in2="offset" /><feComposite
id="feComposite123"
result="comp2"
operator="over"
in="fbSourceGraphic"
in2="comp1" /></filter><linearGradient
xlink:href="#linearGradient1"
id="linearGradient2"
x1="256"
y1="0"
x2="256"
y2="512"
gradientUnits="userSpaceOnUse" /></defs><g
id="layer1"
style="display:inline"><circle
style="display:inline;fill:url(#linearGradient2);stroke-width:25;stroke-linecap:round;stroke-linejoin:round;paint-order:markers fill stroke"
id="background"
cx="256"
cy="256"
r="256" /><circle
style="opacity:1;fill:#000000;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2.19597;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;paint-order:markers fill stroke;filter:url(#filter249)"
id="dot"
cx="256"
cy="240.31155"
r="21.5" /><path
id="bottom"
style="opacity:1;fill:#000000;fill-opacity:1;stroke:none;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;filter:url(#filter249)"
d="M 220.84961,277.95117 183.5,315.59961 219.5,351.69922 239.5,332 c 0,0 5.85615,-6.19922 16.5,-6.19922 10.64385,0 16.5,6.19922 16.5,6.19922 l 20,19.69922 36,-36.09961 -37.34961,-37.64844 A 51.5,51.5 0 0 1 256,291.8125 51.5,51.5 0 0 1 220.84961,277.95117 Z" /><path
id="main"
style="display:inline;opacity:1;fill:#000000;fill-opacity:1;stroke-width:2.2;stroke-linecap:round;stroke-linejoin:round;paint-order:markers fill stroke;filter:url(#filter249)"
d="m 256,145.40039 c -7.11895,0 -13.56326,2.88552 -18.22852,7.55078 L 66.96875,323.46875 C 62.354158,328.08334 59.5,334.45837 59.5,341.5 c 0,14.08326 11.416739,25.5 25.5,25.5 7.04163,0 13.41666,-2.85416 18.03125,-7.46875 L 206.92578,255.93359 A 51.5,51.5 0 0 1 204.5,240.3125 a 51.5,51.5 0 0 1 51.5,-51.5 51.5,51.5 0 0 1 51.5,51.5 51.5,51.5 0 0 1 -2.42578,15.62109 L 408.96875,359.53125 C 413.58334,364.14585 419.95837,367 427,367 c 14.08326,0 25.5,-11.41674 25.5,-25.5 0,-7.04163 -2.85415,-13.41666 -7.46875,-18.03125 L 274.22852,152.95117 C 269.56326,148.2859 263.11895,145.40039 256,145.40039 Z" /></g></svg>

Before

Width:  |  Height:  |  Size: 4.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 733 KiB

After

Width:  |  Height:  |  Size: 644 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 371 KiB

After

Width:  |  Height:  |  Size: 186 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 869 KiB

After

Width:  |  Height:  |  Size: 465 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 49 KiB

After

Width:  |  Height:  |  Size: 15 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 990 KiB

After

Width:  |  Height:  |  Size: 887 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 356 KiB

After

Width:  |  Height:  |  Size: 396 KiB

-3
View File
@@ -1,6 +1,5 @@
server { server {
listen 9180; listen 9180;
listen [::]:9180;
sendfile on; sendfile on;
default_type application/octet-stream; default_type application/octet-stream;
@@ -20,11 +19,9 @@ server {
location ${PUBLIC_PATH}settings.js { location ${PUBLIC_PATH}settings.js {
alias /etc/nginx/conf.d/settings.js; alias /etc/nginx/conf.d/settings.js;
add_header Cache-Control "no-store";
} }
location ${PUBLIC_PATH}/settings.js { location ${PUBLIC_PATH}/settings.js {
alias /etc/nginx/conf.d/settings.js; alias /etc/nginx/conf.d/settings.js;
add_header Cache-Control "no-store";
} }
} }
+18321
View File
File diff suppressed because it is too large Load Diff
+86 -92
View File
@@ -1,6 +1,6 @@
{ {
"name": "feishin", "name": "feishin",
"version": "1.13.0", "version": "1.2.0",
"description": "A modern self-hosted music player.", "description": "A modern self-hosted music player.",
"keywords": [ "keywords": [
"subsonic", "subsonic",
@@ -30,37 +30,29 @@
"dev:watch": "electron-vite dev --watch", "dev:watch": "electron-vite dev --watch",
"i18next": "i18next -c src/i18n/i18next-parser.config.js", "i18next": "i18next -c src/i18n/i18next-parser.config.js",
"postinstall": "electron-builder install-app-deps", "postinstall": "electron-builder install-app-deps",
"lint": "pnpm run typecheck && pnpm run lint-code && pnpm run lint-styles", "lint": "pnpm run lint-code && pnpm run lint-styles",
"lint:fix": "pnpm run lint-code:fix && pnpm run lint-styles:fix",
"lint-code": "eslint --max-warnings=0 --cache .", "lint-code": "eslint --max-warnings=0 --cache .",
"lint-code:fix": "eslint --cache --fix .", "lint-code:fix": "eslint --cache --fix .",
"lint-styles": "stylelint --max-warnings=0 'src/**/*.{css,scss}'", "lint-styles": "stylelint --max-warnings=0 'src/**/*.{css,scss}'",
"lint-styles:fix": "stylelint 'src/**/*.{css,scss}' --fix", "lint-styles:fix": "stylelint 'src/**/*.{css,scss}' --fix",
"lint:fix": "pnpm run lint-code:fix && pnpm run lint-styles:fix",
"package": "pnpm run build && electron-builder", "package": "pnpm run build && electron-builder",
"package:dev": "pnpm run build && electron-builder --dir", "package:dev": "pnpm run build && electron-builder --dir",
"package:linux": "pnpm run build && electron-builder --linux", "package:linux": "pnpm run build && electron-builder --linux",
"package:linux:pr": "pnpm run build && electron-builder --linux --publish never",
"package:linux-arm64:pr": "pnpm run build && electron-builder --linux --arm64 --publish never", "package:linux-arm64:pr": "pnpm run build && electron-builder --linux --arm64 --publish never",
"package:linux:pr": "pnpm run build && electron-builder --linux --publish never",
"package:mac": "pnpm run build && electron-builder --mac", "package:mac": "pnpm run build && electron-builder --mac",
"package:mac:pr": "pnpm run build && electron-builder --mac --publish never", "package:mac:pr": "pnpm run build && electron-builder --mac --publish never",
"package:win": "pnpm run build && electron-builder --win", "package:win": "pnpm run build && electron-builder --win",
"package:win:pr": "pnpm run build && electron-builder --win --publish never", "package:win:pr": "pnpm run build && electron-builder --win --publish never",
"package:win-arm64:pr": "pnpm run build && electron-builder --win --arm64 --publish never",
"publish:linux": "pnpm run build && electron-builder --publish always --linux", "publish:linux": "pnpm run build && electron-builder --publish always --linux",
"publish:linux:alpha": "pnpm run build && electron-builder --config electron-builder-alpha.yml --publish always --linux",
"publish:linux:beta": "pnpm run build && electron-builder --config electron-builder-beta.yml --publish always --linux",
"publish:linux-arm64": "pnpm run build && electron-builder --publish always --linux --arm64", "publish:linux-arm64": "pnpm run build && electron-builder --publish always --linux --arm64",
"publish:linux-arm64:alpha": "pnpm run build && electron-builder --config electron-builder-alpha.yml --publish always --linux --arm64",
"publish:linux-arm64:beta": "pnpm run build && electron-builder --config electron-builder-beta.yml --publish always --linux --arm64", "publish:linux-arm64:beta": "pnpm run build && electron-builder --config electron-builder-beta.yml --publish always --linux --arm64",
"publish:linux:beta": "pnpm run build && electron-builder --config electron-builder-beta.yml --publish always --linux",
"publish:mac": "pnpm run build && electron-builder --publish always --mac", "publish:mac": "pnpm run build && electron-builder --publish always --mac",
"publish:mac:alpha": "pnpm run build && electron-builder --config electron-builder-alpha.yml --publish always --mac",
"publish:mac:beta": "pnpm run build && electron-builder --config electron-builder-beta.yml --publish always --mac", "publish:mac:beta": "pnpm run build && electron-builder --config electron-builder-beta.yml --publish always --mac",
"publish:win": "pnpm run build && electron-builder --publish always --win", "publish:win": "pnpm run build && electron-builder --publish always --win",
"publish:win:alpha": "pnpm run build && electron-builder --config electron-builder-alpha.yml --publish always --win",
"publish:win:beta": "pnpm run build && electron-builder --config electron-builder-beta.yml --publish always --win", "publish:win:beta": "pnpm run build && electron-builder --config electron-builder-beta.yml --publish always --win",
"publish:win-arm64": "pnpm run build && electron-builder --publish always --win --arm64",
"publish:win-arm64:alpha": "pnpm run build && electron-builder --config electron-builder-alpha.yml --publish always --win --arm64",
"publish:win-arm64:beta": "pnpm run build && electron-builder --config electron-builder-beta.yml --publish always --win --arm64",
"start": "electron-vite preview", "start": "electron-vite preview",
"typecheck": "pnpm run typecheck:node && pnpm run typecheck:web", "typecheck": "pnpm run typecheck:node && pnpm run typecheck:web",
"typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false", "typecheck:node": "tsc --noEmit -p tsconfig.node.json --composite false",
@@ -68,125 +60,127 @@
"version": "pnpm version --no-git-tag-version", "version": "pnpm version --no-git-tag-version",
"postversion": "node ./scripts/update-app-stream.mjs" "postversion": "node ./scripts/update-app-stream.mjs"
}, },
"resolutions": {
"xml2js": "0.5.0"
},
"dependencies": { "dependencies": {
"@atlaskit/pragmatic-drag-and-drop": "1.7.7", "@atlaskit/pragmatic-drag-and-drop": "1.7.7",
"@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^2.1.5", "@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^2.1.2",
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.2.0", "@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.1.0",
"@electron-toolkit/preload": "^3.0.2", "@electron-toolkit/preload": "^3.0.1",
"@electron-toolkit/utils": "^4.0.0", "@electron-toolkit/utils": "^4.0.0",
"@mantine/colors-generator": "^9.3.0", "@mantine/colors-generator": "^8.3.8",
"@mantine/core": "^9.3.0", "@mantine/core": "^8.3.8",
"@mantine/dates": "^9.3.0", "@mantine/dates": "^8.3.8",
"@mantine/form": "^9.3.0", "@mantine/form": "^8.3.8",
"@mantine/hooks": "^9.3.0", "@mantine/hooks": "^8.3.8",
"@mantine/modals": "^9.3.0", "@mantine/modals": "^8.3.8",
"@mantine/notifications": "^9.3.0", "@mantine/notifications": "^8.3.8",
"@radix-ui/react-context-menu": "^2.3.0", "@radix-ui/react-context-menu": "^2.2.16",
"@tanstack/react-query": "5.96.2", "@tanstack/react-query": "^5.90.9",
"@tanstack/react-query-devtools": "5.96.2", "@tanstack/react-query-devtools": "^5.90.2",
"@tanstack/react-query-persist-client": "5.96.2", "@tanstack/react-query-persist-client": "^5.90.11",
"@ts-rest/core": "^3.52.1", "@ts-rest/core": "^3.52.1",
"@wavesurfer/react": "^1.0.12", "@wavesurfer/react": "^1.0.11",
"@xhayper/discord-rpc": "^1.3.4", "@xhayper/discord-rpc": "^1.3.0",
"audiomotion-analyzer": "^4.5.4", "audiomotion-analyzer": "^4.5.1",
"axios": "^1.17.0", "axios": "^1.13.2",
"butterchurn": "3.0.0-beta.5", "butterchurn": "^3.0.0-beta.5",
"butterchurn-presets": "3.0.0-beta.4", "butterchurn-presets": "^3.0.0-beta.4",
"cheerio": "^1.2.0", "cheerio": "^1.1.2",
"clsx": "^2.1.1", "clsx": "^2.1.1",
"cmdk": "^1.1.1", "cmdk": "^1.1.1",
"dayjs": "^1.11.21", "dayjs": "^1.11.19",
"dompurify": "^3.4.8", "dompurify": "^3.3.0",
"electron-debug": "^3.2.0", "electron-debug": "^3.2.0",
"electron-localshortcut": "^3.2.1", "electron-localshortcut": "^3.2.1",
"electron-log": "^5.4.4", "electron-log": "^5.4.3",
"electron-store": "^8.2.0", "electron-store": "^8.2.0",
"electron-updater": "^6.8.9", "electron-updater": "^6.6.2",
"fast-average-color": "9.5.0", "fast-average-color": "^9.5.0",
"fast-xml-parser": "^5.8.0", "fast-xml-parser": "^5.3.2",
"format-duration": "^3.0.2", "format-duration": "^3.0.2",
"fuse.js": "^7.4.2", "fuse.js": "^7.1.0",
"i18next": "^25.10.10", "i18next": "^25.6.2",
"icecast-metadata-stats": "^0.1.12", "icecast-metadata-stats": "^0.1.12",
"idb-keyval": "^6.2.5", "idb-keyval": "^6.2.2",
"immer": "^10.2.0", "immer": "^10.2.0",
"is-electron": "^2.2.2", "is-electron": "^2.2.2",
"kuroshiro": "^1.2.0", "lodash": "^4.17.21",
"kuroshiro-analyzer-kuromoji": "^1.1.0",
"lodash": "^4.18.1",
"md5": "^2.3.0", "md5": "^2.3.0",
"motion": "^12.40.0", "motion": "^12.23.24",
"mpris-service": "^2.1.2", "mpris-service": "^2.1.2",
"nanoid": "^3.3.12", "nanoid": "^3.3.11",
"node-mpv": "github:jeffvli/Node-MPV#32b4d64395289ad710c41d481d2707a7acfc228f", "node-mpv": "github:jeffvli/Node-MPV#32b4d64395289ad710c41d481d2707a7acfc228f",
"overlayscrollbars": "^2.16.0", "nuqs": "^2.7.1",
"overlayscrollbars": "^2.11.1",
"overlayscrollbars-react": "^0.5.6", "overlayscrollbars-react": "^0.5.6",
"qs": "^6.15.2", "qs": "^6.14.1",
"react": "^19.2.7", "react": "^19.1.0",
"react-call": "^1.8.2", "react-call": "^1.8.1",
"react-dom": "^19.2.7", "react-dom": "^19.1.0",
"react-error-boundary": "^5.0.0", "react-error-boundary": "^5.0.0",
"react-i18next": "^16.6.6", "react-i18next": "^16.3.3",
"react-icons": "^5.6.0", "react-icons": "^5.5.0",
"react-player": "^2.16.1", "react-image": "^4.1.0",
"react-router": "^7.17.0", "react-loading-skeleton": "^3.5.0",
"react-split-pane": "^3.2.0", "react-player": "^2.16.0",
"react-router": "^7.9.6",
"react-split-pane": "^3.0.4",
"react-virtualized-auto-sizer": "^1.0.26", "react-virtualized-auto-sizer": "^1.0.26",
"react-window": "1.8.11", "react-window": "1.8.11",
"react-window-v2": "npm:react-window@^2.2.7", "react-window-v2": "npm:react-window@^2.2.3",
"semver": "^7.8.2", "semver": "^7.5.4",
"string-to-color": "^2.2.2", "string-to-color": "^2.2.2",
"wavesurfer.js": "^7.12.7", "wavesurfer.js": "^7.11.1",
"ws": "^8.21.0", "ws": "^8.18.2",
"zod": "^3.25.76", "zod": "^3.22.3",
"zustand": "^5.0.14" "zustand": "^5.0.5"
}, },
"devDependencies": { "devDependencies": {
"@electron-toolkit/eslint-config-prettier": "^3.0.0", "@electron-toolkit/eslint-config-prettier": "^3.0.0",
"@electron-toolkit/eslint-config-ts": "^3.1.0", "@electron-toolkit/eslint-config-ts": "^3.0.0",
"@electron-toolkit/tsconfig": "^2.0.0", "@electron-toolkit/tsconfig": "^2.0.0",
"@types/electron-localshortcut": "^3.1.3", "@types/electron-localshortcut": "^3.1.0",
"@types/lodash": "^4.17.24", "@types/lodash": "^4.17.18",
"@types/md5": "^2.3.6", "@types/md5": "^2.3.5",
"@types/node": "^24.13.1", "@types/node": "^24.10.1",
"@types/react": "^19.2.17", "@types/react": "^19.2.5",
"@types/react-dom": "^19.2.3", "@types/react-dom": "^19.2.3",
"@types/react-window": "^1.8.8", "@types/react-window": "^1.8.8",
"@types/source-map-support": "^0.5.10", "@types/source-map-support": "^0.5.10",
"@types/ws": "^8.18.1", "@types/ws": "^8.18.1",
"@vitejs/plugin-react": "^5.2.0", "@vitejs/plugin-react": "^5.1.1",
"babel-plugin-react-compiler": "^1.0.0",
"concurrently": "^9.2.1", "concurrently": "^9.2.1",
"cross-env": "^10.1.0", "cross-env": "^10.1.0",
"electron": "^41.7.1", "electron": "^39.2.7",
"electron-builder": "^26.15.0", "electron-builder": "^26.0.12",
"electron-devtools-installer": "^4.0.0", "electron-devtools-installer": "^4.0.0",
"electron-vite": "^4.0.1", "electron-vite": "^4.0.1",
"eslint": "^9.39.4", "eslint": "^9.24.0",
"eslint-plugin-perfectionist": "^4.15.1", "eslint-plugin-perfectionist": "^4.13.0",
"eslint-plugin-prettier": "^5.5.6", "eslint-plugin-prettier": "^5.4.0",
"eslint-plugin-react": "^7.37.5", "eslint-plugin-react": "^7.37.5",
"eslint-plugin-react-hooks": "^7.1.1", "eslint-plugin-react-hooks": "^7.0.1",
"eslint-plugin-react-refresh": "^0.4.26", "eslint-plugin-react-refresh": "^0.4.24",
"i18next-parser": "^9.4.0", "i18next-parser": "^9.3.0",
"postcss-preset-mantine": "^1.18.0", "postcss-preset-mantine": "^1.18.0",
"postcss-simple-vars": "^7.0.1", "postcss-simple-vars": "^7.0.1",
"prettier": "^3.8.3", "prettier": "^3.6.2",
"prettier-plugin-packagejson": "^2.5.22", "prettier-plugin-packagejson": "^2.5.19",
"stylelint": "^16.26.1", "stylelint": "^16.25.0",
"stylelint-config-css-modules": "^4.6.0", "stylelint-config-css-modules": "^4.5.1",
"stylelint-config-recess-order": "^7.7.0", "stylelint-config-recess-order": "^7.4.0",
"stylelint-config-standard": "^39.0.1", "stylelint-config-standard": "^39.0.1",
"typescript": "^5.9.3", "typescript": "^5.8.3",
"vite": "^7.3.5", "vite": "^7.2.2",
"vite-plugin-conditional-import": "^0.1.7", "vite-plugin-conditional-import": "^0.1.7",
"vite-plugin-dynamic-import": "^1.6.0", "vite-plugin-dynamic-import": "^1.6.0",
"vite-plugin-ejs": "^1.7.0", "vite-plugin-ejs": "^1.7.0",
"vite-plugin-pwa": "^1.3.0" "vite-plugin-pwa": "^1.1.0"
},
"pnpm": {
"onlyBuiltDependencies": [
"electron",
"esbuild"
]
}, },
"packageManager": "pnpm@11.5.2",
"productName": "feishin" "productName": "feishin"
} }
+3821 -3653
View File
File diff suppressed because it is too large Load Diff
-9
View File
@@ -1,9 +0,0 @@
allowBuilds:
abstract-socket: true
electron: true
electron-winstaller: true
esbuild: true
minimumReleaseAge: 1440
overrides:
'xml2js': '0.5.0'
'react-router': '7.14.0'
+2 -3
View File
@@ -1,9 +1,9 @@
import react from '@vitejs/plugin-react';
import path from 'path'; import path from 'path';
import { defineConfig, normalizePath } from 'vite'; import { defineConfig, normalizePath } from 'vite';
import { ViteEjsPlugin } from 'vite-plugin-ejs'; import { ViteEjsPlugin } from 'vite-plugin-ejs';
import { version } from './package.json'; import { version } from './package.json';
import { createReactPlugin } from './vite.react-plugin';
export default defineConfig({ export default defineConfig({
build: { build: {
@@ -23,7 +23,6 @@ export default defineConfig({
assetFileNames: '[name].[ext]', assetFileNames: '[name].[ext]',
chunkFileNames: '[name].js', chunkFileNames: '[name].js',
entryFileNames: '[name].js', entryFileNames: '[name].js',
sourcemapExcludeSources: false,
}, },
}, },
sourcemap: true, sourcemap: true,
@@ -35,7 +34,7 @@ export default defineConfig({
}, },
}, },
plugins: [ plugins: [
createReactPlugin(), react(),
ViteEjsPlugin({ ViteEjsPlugin({
prod: process.env.NODE_ENV === 'production', prod: process.env.NODE_ENV === 'production',
root: normalizePath(path.resolve(__dirname, './src/remote')), root: normalizePath(path.resolve(__dirname, './src/remote')),
Binary file not shown.

Before

Width:  |  Height:  |  Size: 32 KiB

After

Width:  |  Height:  |  Size: 48 KiB

-45
View File
@@ -1,45 +0,0 @@
import { execSync } from 'child_process';
import path from 'path';
import { fileURLToPath } from 'url';
const __filename = fileURLToPath(import.meta.url);
const __dirname = path.dirname(__filename);
/**
* Electron-builder afterAllArtifactBuild hook
* Runs the app stream update script only for Linux builds
* Returns the metainfo file path to be included in published artifacts
*/
// This is not a typescript file, and is called by electron-builder, so we cannot use typescript features here.
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
export default async function afterAllArtifactBuild(buildResult) {
// Check if this build includes Linux as a target
const isLinux = Array.from(buildResult.platformToTargets.keys()).some(
(platform) => platform.name === 'linux',
);
if (isLinux) {
const updateScriptPath = path.join(__dirname, 'update-app-stream.mjs');
const projectRoot = path.resolve(__dirname, '..');
const metainfoFile = path.resolve(projectRoot, 'org.jeffvli.feishin.metainfo.xml');
console.log('Running app stream update for Linux build...');
try {
execSync(`node ${updateScriptPath} --replace-if-version-missing`, {
cwd: projectRoot,
stdio: 'inherit',
});
// Return the metainfo file to be included in published artifacts
return [metainfoFile];
} catch (error) {
console.error('Failed to update app stream:', error.message);
throw error;
}
}
// Return empty array if not a Linux build
return [];
}
+11 -32
View File
@@ -3,51 +3,30 @@ import fs from 'fs';
import path from 'path'; import path from 'path';
const args = process.argv.slice(2); const args = process.argv.slice(2);
if (args.length > 3) {
// Parse flags and positional arguments console.error('Usage: node update-app-stream.js [package-file] [date] [metainfo-file]');
const flags = args.filter((arg) => arg.startsWith('--'));
const positionalArgs = args.filter((arg) => !arg.startsWith('--'));
const replaceIfVersionMissing = flags.includes('--replace-if-version-missing');
if (positionalArgs.length > 3) {
console.error(
'Usage: node update-app-stream.js [package-file] [date] [metainfo-file] [--replace-if-version-missing]',
);
process.exit(1); process.exit(1);
} }
const packageFile = positionalArgs[0] || path.resolve(process.cwd(), 'package.json'); const packageFile = args[0] || path.resolve(process.cwd(), 'package.json');
const packageContent = fs.readFileSync(packageFile, 'utf8'); const packageContent = fs.readFileSync(packageFile, 'utf8');
const packageJson = JSON.parse(packageContent); const packageJson = JSON.parse(packageContent);
const version = packageJson.version; const version = packageJson.version;
const time = Math.floor((Date.parse(positionalArgs[1]) || Date.now()) / 1000); const time = Math.floor((Date.parse(args[1]) || Date.now()) / 1000);
const metainfoFile = const metainfoFile = args[2] || path.resolve(process.cwd(), 'org.jeffvli.feishin.metainfo.xml');
positionalArgs[2] || path.resolve(process.cwd(), 'org.jeffvli.feishin.metainfo.xml');
const parser = new XMLParser({ ignoreAttributes: false }); const parser = new XMLParser({ ignoreAttributes: false });
const metainfoContent = fs.readFileSync(metainfoFile, 'utf8'); const metainfoContent = fs.readFileSync(metainfoFile, 'utf8');
const metainfo = parser.parse(metainfoContent); const metainfo = parser.parse(metainfoContent);
const newRelease = { if (!metainfo.component.releases.release.find((release) => release['@_version'] === version)) {
'@_date': new Date(time * 1000).toISOString().split('T')[0], metainfo.component.releases.release.unshift({
'@_type': version.includes('-') ? 'development' : 'stable', '@_date': new Date(time * 1000).toISOString().split('T')[0],
'@_version': version, '@_type': version.includes('-') ? 'development' : 'stable',
}; '@_version': version,
});
if (replaceIfVersionMissing) {
// Replace all releases with only the current version
metainfo.component.releases.release = [newRelease];
} else {
// Default behavior: add new release if it doesn't exist
const releaseExists =
metainfo.component.releases.release.findIndex(
(release) => release['@_version'] === version,
) !== -1;
if (!releaseExists) {
metainfo.component.releases.release.unshift(newRelease);
}
} }
const builder = new XMLBuilder({ format: true, ignoreAttributes: false, indentBy: ' ' }); const builder = new XMLBuilder({ format: true, ignoreAttributes: false, indentBy: ' ' });
+1 -102
View File
@@ -1,102 +1 @@
"use strict"; "use strict";window.SERVER_URL="${SERVER_URL}";window.SERVER_NAME="${SERVER_NAME}";window.SERVER_TYPE="${SERVER_TYPE}";window.SERVER_LOCK=${SERVER_LOCK};window.LEGACY_AUTHENTICATION=${LEGACY_AUTHENTICATION};window.ANALYTICS_DISABLED="${ANALYTICS_DISABLED}";
window.SERVER_URL = "${SERVER_URL}";
window.REMOTE_URL = "${REMOTE_URL}";
window.SERVER_NAME = "${SERVER_NAME}";
window.SERVER_TYPE = "${SERVER_TYPE}";
window.SERVER_LOCK = "${SERVER_LOCK}";
window.LEGACY_AUTHENTICATION = "${LEGACY_AUTHENTICATION}";
window.ANALYTICS_DISABLED = "${ANALYTICS_DISABLED}";
window.FS_GENERAL_ACCENT = "${FS_GENERAL_ACCENT}";
window.FS_GENERAL_ALBUM_BACKGROUND = "${FS_GENERAL_ALBUM_BACKGROUND}";
window.FS_GENERAL_ALBUM_BACKGROUND_BLUR = "${FS_GENERAL_ALBUM_BACKGROUND_BLUR}";
window.FS_GENERAL_ARTIST_BACKGROUND = "${FS_GENERAL_ARTIST_BACKGROUND}";
window.FS_GENERAL_ARTIST_BACKGROUND_BLUR = "${FS_GENERAL_ARTIST_BACKGROUND_BLUR}";
window.FS_GENERAL_BLUR_EXPLICIT_IMAGES = "${FS_GENERAL_BLUR_EXPLICIT_IMAGES}";
window.FS_GENERAL_COMBINED_LYRICS_AND_VISUALIZER = "${FS_GENERAL_COMBINED_LYRICS_AND_VISUALIZER}";
window.FS_GENERAL_ENABLE_GRID_MULTI_SELECT = "${FS_GENERAL_ENABLE_GRID_MULTI_SELECT}";
window.FS_GENERAL_EXTERNAL_LINKS = "${FS_GENERAL_EXTERNAL_LINKS}";
window.FS_GENERAL_FOLLOW_CURRENT_SONG = "${FS_GENERAL_FOLLOW_CURRENT_SONG}";
window.FS_GENERAL_FOLLOW_SYSTEM_THEME = "${FS_GENERAL_FOLLOW_SYSTEM_THEME}";
window.FS_GENERAL_HOME_FEATURE = "${FS_GENERAL_HOME_FEATURE}";
window.FS_GENERAL_HOME_FEATURE_STYLE = "${FS_GENERAL_HOME_FEATURE_STYLE}";
window.FS_GENERAL_LANGUAGE = "${FS_GENERAL_LANGUAGE}";
window.FS_GENERAL_LAST_FM = "${FS_GENERAL_LAST_FM}";
window.FS_GENERAL_LASTFM_API_KEY = "${FS_GENERAL_LASTFM_API_KEY}";
window.FS_GENERAL_LISTEN_BRAINZ = "${FS_GENERAL_LISTEN_BRAINZ}";
window.FS_GENERAL_MUSIC_BRAINZ = "${FS_GENERAL_MUSIC_BRAINZ}";
window.FS_GENERAL_NATIVE_ASPECT_RATIO = "${FS_GENERAL_NATIVE_ASPECT_RATIO}";
window.FS_GENERAL_PATH_REPLACE = "${FS_GENERAL_PATH_REPLACE}";
window.FS_GENERAL_PATH_REPLACE_WITH = "${FS_GENERAL_PATH_REPLACE_WITH}";
window.FS_GENERAL_PLAYERBAR_OPEN_DRAWER = "${FS_GENERAL_PLAYERBAR_OPEN_DRAWER}";
window.FS_GENERAL_PRIMARY_SHADE = "${FS_GENERAL_PRIMARY_SHADE}";
window.FS_GENERAL_QOBUZ = "${FS_GENERAL_QOBUZ}";
window.FS_GENERAL_RESUME = "${FS_GENERAL_RESUME}";
window.FS_GENERAL_SHOW_LYRICS_IN_SIDEBAR = "${FS_GENERAL_SHOW_LYRICS_IN_SIDEBAR}";
window.FS_GENERAL_SHOW_RATINGS = "${FS_GENERAL_SHOW_RATINGS}";
window.FS_GENERAL_SHOW_VISUALIZER_IN_SIDEBAR = "${FS_GENERAL_SHOW_VISUALIZER_IN_SIDEBAR}";
window.FS_GENERAL_SIDEBAR_COLLAPSED_NAVIGATION = "${FS_GENERAL_SIDEBAR_COLLAPSED_NAVIGATION}";
window.FS_GENERAL_SIDEBAR_COLLAPSE_SHARED = "${FS_GENERAL_SIDEBAR_COLLAPSE_SHARED}";
window.FS_GENERAL_SIDEBAR_PLAYLIST_FOLDERS = "${FS_GENERAL_SIDEBAR_PLAYLIST_FOLDERS}";
window.FS_GENERAL_SIDEBAR_PLAYLIST_FOLDER_SEPARATOR = "${FS_GENERAL_SIDEBAR_PLAYLIST_FOLDER_SEPARATOR}";
window.FS_GENERAL_SIDEBAR_PLAYLIST_FOLDER_TREE_INDENT = "${FS_GENERAL_SIDEBAR_PLAYLIST_FOLDER_TREE_INDENT}";
window.FS_GENERAL_SIDEBAR_PLAYLIST_FOLDER_TREE_LINE_COLOR = "${FS_GENERAL_SIDEBAR_PLAYLIST_FOLDER_TREE_LINE_COLOR}";
window.FS_GENERAL_SIDEBAR_PLAYLIST_FOLDER_VIEW = "${FS_GENERAL_SIDEBAR_PLAYLIST_FOLDER_VIEW}";
window.FS_GENERAL_SIDEBAR_PLAYLIST_LIST = "${FS_GENERAL_SIDEBAR_PLAYLIST_LIST}";
window.FS_GENERAL_SIDEBAR_PLAYLIST_MODE = "${FS_GENERAL_SIDEBAR_PLAYLIST_MODE}";
window.FS_GENERAL_SIDEBAR_PLAYLIST_SORTING = "${FS_GENERAL_SIDEBAR_PLAYLIST_SORTING}";
window.FS_GENERAL_SIDE_QUEUE_TYPE = "${FS_GENERAL_SIDE_QUEUE_TYPE}";
window.FS_GENERAL_SIDE_QUEUE_LAYOUT = "${FS_GENERAL_SIDE_QUEUE_LAYOUT}";
window.FS_GENERAL_THEME = "${FS_GENERAL_THEME}";
window.FS_GENERAL_THEME_DARK = "${FS_GENERAL_THEME_DARK}";
window.FS_GENERAL_THEME_LIGHT = "${FS_GENERAL_THEME_LIGHT}";
window.FS_GENERAL_USE_THEME_ACCENT_COLOR = "${FS_GENERAL_USE_THEME_ACCENT_COLOR}";
window.FS_GENERAL_USE_THEME_PRIMARY_SHADE = "${FS_GENERAL_USE_THEME_PRIMARY_SHADE}";
window.FS_GENERAL_ZOOM_FACTOR = "${FS_GENERAL_ZOOM_FACTOR}";
window.FS_PLAYBACK_MEDIA_SESSION = "${FS_PLAYBACK_MEDIA_SESSION}";
window.FS_PLAYBACK_WEB_AUDIO = "${FS_PLAYBACK_WEB_AUDIO}";
window.FS_PLAYBACK_AUDIO_FADE_ON_STATUS_CHANGE = "${FS_PLAYBACK_AUDIO_FADE_ON_STATUS_CHANGE}";
window.FS_PLAYBACK_PRESERVE_PITCH = "${FS_PLAYBACK_PRESERVE_PITCH}";
window.FS_PLAYBACK_SCROBBLE_ENABLED = "${FS_PLAYBACK_SCROBBLE_ENABLED}";
window.FS_PLAYBACK_SCROBBLE_NOTIFY = "${FS_PLAYBACK_SCROBBLE_NOTIFY}";
window.FS_PLAYBACK_SCROBBLE_AT_DURATION = "${FS_PLAYBACK_SCROBBLE_AT_DURATION}";
window.FS_PLAYBACK_SCROBBLE_AT_PERCENTAGE = "${FS_PLAYBACK_SCROBBLE_AT_PERCENTAGE}";
window.FS_PLAYBACK_TRANSCODE_ENABLED = "${FS_PLAYBACK_TRANSCODE_ENABLED}";
window.FS_PLAYBACK_TRANSCODE_FORMAT = "${FS_PLAYBACK_TRANSCODE_FORMAT}";
window.FS_PLAYBACK_TRANSCODE_BITRATE = "${FS_PLAYBACK_TRANSCODE_BITRATE}";
window.FS_PLAYBACK_FILTERS = "${FS_PLAYBACK_FILTERS}";
window.FS_DISCORD_ENABLED = "${FS_DISCORD_ENABLED}";
window.FS_DISCORD_CLIENT_ID = "${FS_DISCORD_CLIENT_ID}";
window.FS_DISCORD_DISPLAY_TYPE = "${FS_DISCORD_DISPLAY_TYPE}";
window.FS_DISCORD_LINK_TYPE = "${FS_DISCORD_LINK_TYPE}";
window.FS_DISCORD_SHOW_AS_LISTENING = "${FS_DISCORD_SHOW_AS_LISTENING}";
window.FS_DISCORD_SHOW_PAUSED = "${FS_DISCORD_SHOW_PAUSED}";
window.FS_DISCORD_SHOW_SERVER_IMAGE = "${FS_DISCORD_SHOW_SERVER_IMAGE}";
window.FS_DISCORD_SHOW_STATE_ICON = "${FS_DISCORD_SHOW_STATE_ICON}";
window.FS_LYRICS_FETCH = "${FS_LYRICS_FETCH}";
window.FS_LYRICS_FOLLOW = "${FS_LYRICS_FOLLOW}";
window.FS_LYRICS_DELAY_MS = "${FS_LYRICS_DELAY_MS}";
window.FS_LYRICS_PREFER_LOCAL = "${FS_LYRICS_PREFER_LOCAL}";
window.FS_LYRICS_SHOW_MATCH = "${FS_LYRICS_SHOW_MATCH}";
window.FS_LYRICS_SHOW_PROVIDER = "${FS_LYRICS_SHOW_PROVIDER}";
window.FS_LYRICS_ENABLE_AUTO_TRANSLATION = "${FS_LYRICS_ENABLE_AUTO_TRANSLATION}";
window.FS_LYRICS_TRANSLATION_API_KEY = "${FS_LYRICS_TRANSLATION_API_KEY}";
window.FS_LYRICS_TRANSLATION_TARGET_LANGUAGE = "${FS_LYRICS_TRANSLATION_TARGET_LANGUAGE}";
window.FS_LYRICS_ALIGNMENT = "${FS_LYRICS_ALIGNMENT}";
window.FS_AUTO_DJ_ALBUM_STRATEGY = "${FS_AUTO_DJ_ALBUM_STRATEGY}";
window.FS_AUTO_DJ_ENABLED = "${FS_AUTO_DJ_ENABLED}";
window.FS_AUTO_DJ_ITEM_COUNT = "${FS_AUTO_DJ_ITEM_COUNT}";
window.FS_AUTO_DJ_MODE = "${FS_AUTO_DJ_MODE}";
window.FS_AUTO_DJ_SONG_STRATEGY = "${FS_AUTO_DJ_SONG_STRATEGY}";
window.FS_AUTO_DJ_TIMING = "${FS_AUTO_DJ_TIMING}";
window.FS_CSS_CONTENT = "${FS_CSS_CONTENT}";
window.FS_CSS_ENABLED = "${FS_CSS_ENABLED}";
window.FS_FONT_TYPE = "${FS_FONT_TYPE}";
window.FS_FONT_BUILT_IN = "${FS_FONT_BUILT_IN}";
window.FS_FONT_SYSTEM = "${FS_FONT_SYSTEM}";
+12 -22
View File
@@ -1,4 +1,4 @@
import { PostProcessorModule } from 'i18next'; import { PostProcessorModule, TOptions } from 'i18next';
import i18n from 'i18next'; import i18n from 'i18next';
import { initReactI18next } from 'react-i18next'; import { initReactI18next } from 'react-i18next';
@@ -8,7 +8,6 @@ import cs from './locales/cs.json';
import de from './locales/de.json'; import de from './locales/de.json';
import en from './locales/en.json'; import en from './locales/en.json';
import es from './locales/es.json'; import es from './locales/es.json';
import et from './locales/et.json';
import eu from './locales/eu.json'; import eu from './locales/eu.json';
import fa from './locales/fa.json'; import fa from './locales/fa.json';
import fi from './locales/fi.json'; import fi from './locales/fi.json';
@@ -28,8 +27,6 @@ import sl from './locales/sl.json';
import sr from './locales/sr.json'; import sr from './locales/sr.json';
import sv from './locales/sv.json'; import sv from './locales/sv.json';
import ta from './locales/ta.json'; import ta from './locales/ta.json';
import th from './locales/th.json';
import tl from './locales/tl.json';
import tr from './locales/tr.json'; import tr from './locales/tr.json';
import zhHans from './locales/zh-Hans.json'; import zhHans from './locales/zh-Hans.json';
import zhHant from './locales/zh-Hant.json'; import zhHant from './locales/zh-Hant.json';
@@ -41,7 +38,6 @@ const resources = {
de: { translation: de }, de: { translation: de },
en: { translation: en }, en: { translation: en },
es: { translation: es }, es: { translation: es },
et: { translation: et },
eu: { translation: eu }, eu: { translation: eu },
fa: { translation: fa }, fa: { translation: fa },
fi: { translation: fi }, fi: { translation: fi },
@@ -61,8 +57,6 @@ const resources = {
sr: { translation: sr }, sr: { translation: sr },
sv: { translation: sv }, sv: { translation: sv },
ta: { translation: ta }, ta: { translation: ta },
th: { translation: th },
tl: { translation: tl },
tr: { translation: tr }, tr: { translation: tr },
'zh-Hans': { translation: zhHans }, 'zh-Hans': { translation: zhHans },
'zh-Hant': { translation: zhHant }, 'zh-Hant': { translation: zhHant },
@@ -93,10 +87,6 @@ export const languages = [
label: 'Español', label: 'Español',
value: 'es', value: 'es',
}, },
{
label: 'Eesti',
value: 'et',
},
{ {
label: 'Basque', label: 'Basque',
value: 'eu', value: 'eu',
@@ -173,14 +163,6 @@ export const languages = [
label: 'Tamil', label: 'Tamil',
value: 'ta', value: 'ta',
}, },
{
label: 'Thai',
value: 'th',
},
{
label: 'Tagalog',
value: 'tl',
},
{ {
label: 'Türkçe', label: 'Türkçe',
value: 'tr', value: 'tr',
@@ -221,17 +203,25 @@ const titleCasePostProcessor: PostProcessorModule = {
type: 'postProcessor', type: 'postProcessor',
}; };
// const ignoreSentenceCaseLanguages = ['de']; const ignoreSentenceCaseLanguages = ['de'];
const sentenceCasePostProcessor: PostProcessorModule = { const sentenceCasePostProcessor: PostProcessorModule = {
name: 'sentenceCase', name: 'sentenceCase',
process: (value: string) => { process: (
value: string,
_key: string,
_options: TOptions<Record<string, string>>,
translator: any,
) => {
const sentences = value.split('. '); const sentences = value.split('. ');
return sentences return sentences
.map((sentence) => { .map((sentence) => {
return ( return (
sentence.charAt(0).toLocaleUpperCase() + sentence.slice(1).toLocaleLowerCase() sentence.charAt(0).toLocaleUpperCase() +
(!ignoreSentenceCaseLanguages.includes(translator.language)
? sentence.slice(1).toLocaleLowerCase()
: sentence.slice(1))
); );
}) })
.join('. '); .join('. ');
+24 -369
View File
@@ -1,49 +1,27 @@
{ {
"action": { "action": {
"addToFavorites": "إضافة الى $t(entity.favorite, {\"count\": 2})", "addToFavorites": "إضافة الى $t(entity.favorite_other)",
"addToPlaylist": "إضافة الى $t(entity.playlist, {\"count\": 1})", "addToPlaylist": "إضافة الى $t(entity.playlist_one)",
"clearQueue": "مسح قائمة التشغيل", "clearQueue": "مسح قائمة الإنتظار",
"createPlaylist": "إنشاء $t(entity.playlist, {\"count\": 1})", "createPlaylist": "إنشاء $t(entity.playlist_one)",
"deletePlaylist": "حذف $t(entity.playlist, {\"count\": 1})", "deletePlaylist": "حذف $t(entity.playlist_one)",
"deselectAll": "إلغاء تحديد الكل", "deselectAll": "إلغاء تحديد الكل",
"editPlaylist": "تعديل $t(entity.playlist, {\"count\": 1})", "editPlaylist": "تعديل $t(entity.playlist_one)",
"goToPage": "اذهب الى الصفحة", "goToPage": "اذهب الى صفحة",
"moveToNext": "نقل إلى التالي", "moveToNext": "الذهاب الى التالي",
"moveToBottom": "نقل إلى الأسفل", "moveToBottom": "الذهاب الى الأسفل",
"moveToTop": "نقل إلى الأعلى", "moveToTop": "الذهاب الى الأعلى",
"refresh": "$t(common.refresh)", "refresh": "$t(common.refresh)",
"removeFromFavorites": "حذف من $t(entity.favorite, {\"count\": 2})", "removeFromFavorites": "حذف من $t(entity.favorite_other)",
"removeFromPlaylist": "حذف من $t(entity.playlist, {\"count\": 1})", "removeFromPlaylist": "حذف من $t(entity.playlist_one)",
"removeFromQueue": "حذف من قائمة التشغيل", "removeFromQueue": "حذف من قائمة الإنتظار",
"setRating": "تحديد التقييم", "setRating": "تحديد التقييم",
"toggleSmartPlaylistEditor": "إظهار / إخفاء وضع التعديل لـ $t(entity.smartPlaylist)", "toggleSmartPlaylistEditor": "تشغيل / إطفاء وضع التعديل لـ $t(entity.smartPlaylist)",
"viewPlaylists": "عرض $t(entity.playlist, {\"count\": 2})", "viewPlaylists": "إظهار $t(entity.playlist_other)",
"openIn": { "openIn": {
"lastfm": "فتح في Last.fm", "lastfm": "فتح في Last.fm",
"musicbrainz": "فتح في MusicBrainz", "musicbrainz": "فتح في MusicBrainz"
"listenbrainz": "فتح في ListenBrainz", }
"qobuz": "فتح في Qobuz",
"spotify": "فتح في Spotify"
},
"addOrRemoveFromSelection": "إضافة أو إزالة من الإختيارات",
"selectRangeOfItems": "اختر مجموعة من العناصر",
"goToCurrent": "الانتقال إلى العنصر الحالي",
"createRadioStation": "إنشاء $t(entity.radioStation, {\"count\": 1})",
"deleteRadioStation": "يمسح $t(entity.radioStation, {\"count\": 1})",
"selectAll": "تحديد الكل",
"shuffle": "لخبط",
"shuffleAll": "لخبط الكل",
"shuffleSelected": "لخبط المحدد",
"collapseAllFolders": "اطو جميع المجلدات",
"expandAllFolders": "بسط الملفات",
"downloadStarted": "بدأ تحميل {{count}} عنصر",
"moveUp": "نقل إلى فوق",
"moveDown": "نقل إلى تحت",
"holdToMoveToTop": "اضغط مطولاً للنقل إلى الأعلى",
"holdToMoveToBottom": "اضغط مطولاً للنقل إلى الأسفل",
"moveItems": "نقل العناصر",
"viewMore": "عرض المزيد",
"openApplicationDirectory": "فتح مجلد التطبيق"
}, },
"common": { "common": {
"action_zero": "عملية", "action_zero": "عملية",
@@ -55,13 +33,13 @@
"add": "إضافة", "add": "إضافة",
"additionalParticipants": "مشاركين إضافيين", "additionalParticipants": "مشاركين إضافيين",
"newVersion": "تم تثبيت تحديث جديد {{version}}", "newVersion": "تم تثبيت تحديث جديد {{version}}",
"viewReleaseNotes": "عرض ملاحظات الإصدار", "viewReleaseNotes": "عرض معلومات الإصدار",
"albumGain": "مستوى صوت الألبوم", "albumGain": "مستوى صوت الألبوم",
"albumPeak": "اعلى مستوى للألبوم", "albumPeak": "اعلى مستوى للألبوم",
"areYouSure": "هل أنت متأكد؟", "areYouSure": "هل أنت متأكد؟",
"ascending": "تصاعدي", "ascending": "تصاعدي",
"backward": "خلف", "backward": "خلف",
"biography": "السيرة", "biography": "سيرة",
"bitDepth": "عمق البت", "bitDepth": "عمق البت",
"bitrate": "معدل البت (البت ريت)", "bitrate": "معدل البت (البت ريت)",
"bpm": "نبضة في الدقيقة", "bpm": "نبضة في الدقيقة",
@@ -81,7 +59,7 @@
"configure": "تعديل", "configure": "تعديل",
"confirm": "تأكيد", "confirm": "تأكيد",
"create": "إنشاء", "create": "إنشاء",
"currentSong": "$t(entity.track, {\"count\": 1}) الحالي", "currentSong": "$t(entity.track_one) الحالي",
"decrease": "تنقيص", "decrease": "تنقيص",
"delete": "حذف", "delete": "حذف",
"descending": "تنازلي", "descending": "تنازلي",
@@ -124,7 +102,7 @@
"path": "المسار", "path": "المسار",
"playerMustBePaused": "يجب إيقاف المشغل", "playerMustBePaused": "يجب إيقاف المشغل",
"preview": "معاينة", "preview": "معاينة",
"previousSong": "$t(entity.track, {\"count\": 1}) السابق", "previousSong": "$t(entity.track_one) السابق",
"quit": "خروج", "quit": "خروج",
"random": "عشوائي", "random": "عشوائي",
"rating": "التقييم", "rating": "التقييم",
@@ -139,12 +117,7 @@
"saveAndReplace": "حفظ واستبدال", "saveAndReplace": "حفظ واستبدال",
"saveAs": "حفظ بإسم", "saveAs": "حفظ بإسم",
"search": "بحث", "search": "بحث",
"setting_zero": "إعداد", "setting": "إعداد",
"setting_one": "",
"setting_two": "",
"setting_few": "",
"setting_many": "",
"setting_other": "",
"share": "نشر", "share": "نشر",
"size": "حجم", "size": "حجم",
"sortOrder": "الترتيب", "sortOrder": "الترتيب",
@@ -157,35 +130,7 @@
"unknown": "غير معروف", "unknown": "غير معروف",
"version": "الإصدار", "version": "الإصدار",
"year": "السنة", "year": "السنة",
"yes": "نعم", "yes": "نعم"
"explicitStatus": "حالة المحتوى الصريح",
"countSelected": "{{count}} عنصر محدد",
"back": "للخلف",
"doNotShowAgain": "لا تظهر هذا مجدداً",
"view": "عرض",
"example": "مثال",
"externalLinks": "روابط الخارجية",
"openFolder": "فتح المجلد",
"faster": "أسرع",
"filter_single": "فردي",
"filter_multiple": "متعدد",
"grouping": "مجموعات",
"mood": "مزاج",
"numberOfResults": "{{numberOfResults}} نتيجة",
"noFilters": "لا توجد فلاتر معينة",
"private": "خاص",
"public": "عام",
"retry": "إعادة المحاولة",
"recordLabel": "شركة التسجيل",
"releaseType": "نوع الإصدار",
"rename": "إعادة تسمية",
"slower": "أبطأ",
"sort": "فرز",
"explicit": "صريح",
"clean": "نظيف",
"gridRows": "صفوف الشبكة",
"tableColumns": "أعمدة الجدول",
"newVersionAvailable": "هناك نسخة جديدة متاحة"
}, },
"entity": { "entity": {
"album_zero": "الالبوم", "album_zero": "الالبوم",
@@ -199,296 +144,6 @@
"albumArtist_two": "فنان الالبومين", "albumArtist_two": "فنان الالبومين",
"albumArtist_few": "فنان الالبومات", "albumArtist_few": "فنان الالبومات",
"albumArtist_many": "فنان الالبومات", "albumArtist_many": "فنان الالبومات",
"albumArtist_other": "فنان الالبومات", "albumArtist_other": "فنان الالبومات"
"albumArtistCount_zero": "{{count}} فنان الالبوم",
"albumArtistCount_one": "{{count}} فنان الالبوم",
"albumArtistCount_two": "{{count}} فنان الالبومين",
"albumArtistCount_few": "{{count}} فنان الالبومات",
"albumArtistCount_many": "{{count}} فنان الالبومات",
"albumArtistCount_other": "{{count}} فنان الالبومات",
"albumWithCount_zero": "{{count}} البوم",
"albumWithCount_one": "{{count}} البوم",
"albumWithCount_two": "{{count}} البومين",
"albumWithCount_few": "{{count}} البومات",
"albumWithCount_many": "{{count}} البومات",
"albumWithCount_other": "{{count}} البومات",
"radioStation_zero": "محطة راديو",
"radioStation_one": "محطة راديو",
"radioStation_two": "محطتان راديو",
"radioStation_few": "محطات راديو",
"radioStation_many": "محطات راديو",
"radioStation_other": "محطات راديو",
"radioStationWithCount_zero": "{{count}} محطة راديو",
"radioStationWithCount_one": "{{count}} محطة راديو",
"radioStationWithCount_two": "{{count}} محطتان راديو",
"radioStationWithCount_few": "{{count}} محطات راديو",
"radioStationWithCount_many": "{{count}} محطات راديو",
"radioStationWithCount_other": "{{count}} محطات راديو",
"artist_zero": "فنان",
"artist_one": "فنان",
"artist_two": "فنانان",
"artist_few": "فنانين",
"artist_many": "فنانين",
"artist_other": "فنانين",
"artistWithCount_zero": "{{count}} فنان",
"artistWithCount_one": "{{count}} فنان",
"artistWithCount_two": "{{count}} فنانان",
"artistWithCount_few": "{{count}} فنانين",
"artistWithCount_many": "{{count}} فنانين",
"artistWithCount_other": "{{count}} فنانين",
"favorite_zero": "مفضلة",
"favorite_one": "مفضلة",
"favorite_two": "مفضلتان",
"favorite_few": "مفضلات",
"favorite_many": "مفضلات",
"favorite_other": "مفضلات",
"folder_zero": "مجلد",
"folder_one": "مجلد",
"folder_two": "مجلدان",
"folder_few": "مجلدات",
"folder_many": "مجلدات",
"folder_other": "مجلدات",
"folderWithCount_zero": "{{count}} مجلد",
"folderWithCount_one": "{{count}} مجلد",
"folderWithCount_two": "{{count}} مجلدان",
"folderWithCount_few": "{{count}} مجلدات",
"folderWithCount_many": "{{count}} مجلدات",
"folderWithCount_other": "{{count}} مجلدات",
"genre_zero": "نوع",
"genre_one": "نوع",
"genre_two": "نوعان",
"genre_few": "أنواع",
"genre_many": "أنواع",
"genre_other": "أنواع",
"genreWithCount_zero": "{{count}} نوع",
"genreWithCount_one": "{{count}} نوع",
"genreWithCount_two": "{{count}} نوعان",
"genreWithCount_few": "{{count}} أنواع",
"genreWithCount_many": "{{count}} أنواع",
"genreWithCount_other": "{{count}} أنواع",
"playlist_zero": "قائمة تشغيل",
"playlist_one": "قائمة تشغيل",
"playlist_two": "قائمتان تشغيل",
"playlist_few": "قوائم تشغيل",
"playlist_many": "قوائم تشغيل",
"playlist_other": "قوائم تشغيل",
"play_zero": "{{count}} قائمة تشغيل",
"play_one": "{{count}} قائمة تشغيل",
"play_two": "{{count}} قائمتان تشغيل",
"play_few": "{{count}} قوائم تشغيل",
"play_many": "{{count}} قوائم تشغيل",
"play_other": "{{count}} قوائم تشغيل",
"playlistWithCount_zero": "{{count}} قائمة تشغيل",
"playlistWithCount_one": "{{count}} قائمة تشغيل",
"playlistWithCount_two": "{{count}} قائمتان تشغيل",
"playlistWithCount_few": "{{count}} قوائم تشغيل",
"playlistWithCount_many": "{{count}} قوائم تشغيل",
"playlistWithCount_other": "{{count}} قوائم تشغيل",
"smartPlaylist": "$t(entity.playlist, {\"count\": 1}) قائمة تشغيل ذكية",
"track_zero": "مقطع",
"track_one": "مقطع",
"track_two": "مقطعان",
"track_few": "مقاطع",
"track_many": "مقاطع",
"track_other": "مقاطع",
"song_zero": "أغنية",
"song_one": "أغنية",
"song_two": "أغنيتان",
"song_few": "أغاني",
"song_many": "أغاني",
"song_other": "أغاني",
"trackWithCount_zero": "{{count}} مقطع",
"trackWithCount_one": "{{count}} مقطع",
"trackWithCount_two": "{{count}} مقطعان",
"trackWithCount_few": "{{count}} مقاطع",
"trackWithCount_many": "{{count}} مقاطع",
"trackWithCount_other": "{{count}} مقاطع"
},
"error": {
"apiRouteError": "تعذّر توجيه الطلب",
"audioDeviceFetchError": "حصل خطأ أثناء محاولة الحصول على أجهزة الصوت",
"authenticationFailed": "فشلت المصادقة",
"badAlbum": "أنت ترى هذة الصفحة لأن هذه الأغنية ليست جزءاً من ألبوم. على الأرجح تظهر لك هذه المشكلة إذا كان لديك أغنية في المستوى الأعلى من مجلد الموسيقى. يقوم Jellyfin بتجميع الأغاني فقط إذا كانت داخل مجلد",
"credentialsRequired": "يتطلب بيانات اعتماد",
"genericError": "حدث خطأ",
"loginRateError": "تجاوزت الحد لمحاولات الدخول. حاول مجدداً بعد بضع ثوان",
"mpvRequired": "يتطلب MPV",
"multipleServerSaveQueueError": "قائمة التشغيل تحتوي على أغنية أو أكثر من خادم مختلف. هذا غير مدعوم",
"networkError": "حصل خطأ في الشبكة",
"noNetwork": "الخادم غير متوفر",
"noNetworkDescription": "تعذر الإتصال بالخادم",
"notificationDenied": "تم رفض أذن الإشعارات. هذا الإعداد لن يكون له أي تأثير",
"openError": "تعذر فتح الملف",
"playbackError": "حدث خطأ أثناء محاولة تشغيل الوسائط",
"playbackPausedDueToError": "تم ايقاف التشغيل بسبب خطأ",
"remoteDisableError": "حدث خطأ أثناء محاولة $t(common.disable) الخادم البعيد",
"remoteEnableError": "حدث خطأ أثناء محاولة $t(common.enable) الخادم البعيد",
"remotePortError": "حدث خطأ أثناء محاولة تعيين الخادم البعيد",
"remotePortWarning": "أعد تشغيل الخادم لتطبيق المنفذ الجديد",
"saveQueueFailed": "فشل حفظ قائمة التشغيل",
"serverLockSingleServer": "فقط خادم واحد متاح إذا الخادم مقفل",
"serverNotSelectedError": "لم يتم اختيار أي خادم",
"serverRequired": "يتطلب خادم",
"sessionExpiredError": "انتهت صلاحية جلستك",
"systemFontError": "حدث خطأ أثناء محاولة الحصول على خطوط النظام",
"settingsSyncError": "تم اكتشاف تعارضات بين إعدادات العارض والعملية الرئيسية. أعد تشغيل التطبيق لتطبيق التغييرات",
"invalidJson": "JSON غير صالح",
"invalidServer": "خادم غير صالح",
"localFontAccessDenied": "تم رفض الوصول إلى الخطوط المحلية"
},
"filter": {
"album": "$t(entity.album, {\"count\": 1})",
"albumArtist": "$t(entity.albumArtist, {\"count\": 1})",
"matchAnd": "و",
"matchOr": "أو",
"biography": "السيرة",
"bitrate": "معدل البت (البت ريت)",
"bpm": "نبضة في الدقيقة",
"comment": "تعليق",
"communityRating": "تقييم المجتمع",
"criticRating": "تقييم الناقد",
"dateAdded": "تاريخ الإضافة",
"disc": "قرص",
"duration": "المدة",
"favorited": "مفضل",
"fromYear": "من سنة",
"id": "معرف",
"isFavorited": "مفضل",
"isPublic": "عام",
"isRated": "مقيم",
"isRecentlyPlayed": "تم التشغيل حديثاً",
"lastPlayed": "أخر تشغيل",
"mostPlayed": "أكثر تشغيل",
"name": "الأسم",
"note": "الملاحظة",
"path": "المسار",
"playCount": "عدد التشغيلات",
"random": "عشوائي",
"rating": "التقييم",
"recentlyAdded": "مضاف حديثاً",
"recentlyPlayed": "تم التشغيل حديثاً",
"recentlyUpdated": "محدث حديثاً",
"releaseDate": "تاريخ الإصدار",
"releaseYear": "سنة الإصدار",
"search": "بحث",
"songCount": "عدد الأغاني",
"sortName": "أسم الفرز",
"title": "العنوان",
"toYear": "إلى سنة",
"trackNumber": "مقطع",
"isCompilation": "تجميعة"
},
"datetime": {
"minuteShort": "د",
"secondShort": "ث",
"hourShort": "س",
"dayShort": "ي"
},
"filterOperator": {
"after": "بعد",
"afterDate": "بعد (تاريخ)",
"before": "قبل",
"beforeDate": "قبل (تاريخ)",
"contains": "يحتوي على",
"endsWith": "ينتهي بـ",
"inPlaylist": "في",
"inTheLast": "في أخِر",
"inTheRange": "في مدى",
"inTheRangeDate": "في مدى (تاريخ)",
"is": "في",
"isNot": "ليس في",
"isGreaterThan": "أكبر من",
"isLessThan": "أقل من",
"matchesRegex": "يطابق التعبير النمطي",
"notContains": "لا يحتوي على",
"notInPlaylist": "ليس في",
"notInTheLast": "ليس في أخِر",
"startsWith": "يبدأ بـ"
},
"form": {
"addServer": {
"error_savePassword": "حدث خطأ أثناء محاولة حفظ كلمة السر",
"input_legacyAuthentication": "تفعيل المصادقة القديمة",
"input_name": "أسم الخادم",
"input_password": "كلمة السر",
"input_preferRemoteUrl": "تفضيل رابط عام",
"input_remoteUrl": "رابط عام",
"input_savePassword": "حفظ كلمة السر",
"input_url": "الرابط",
"input_username": "أسم المستخدم",
"success": "تمت إضافة الخادم بنجاح",
"title": "إضافة خادم",
"input_preferInstantMix": "تفضيل الميكس الفوري",
"input_preferInstantMixDescription": "استخدم الميكس الفوري فقط للحصول على أغاني مشابهة. مفيد إذا كان لديك إضافات تعدّل هذا السلوك",
"input_remoteUrlPlaceholder": "اختياري: عنوان URL عام للميزات الخارجية"
},
"largeFetchConfirmation": {
"title": "أضف العناصر إلى قائمة التشغيل",
"description": "سيقوم هذا الإجراء بإضافة جميع العناصر في العرض المفلتر الحالي"
},
"addToPlaylist": {
"input_skipDuplicates": "تخطي العناصر المكررة",
"title": "أضف إلى $t(entity.playlist, {\"count\": 1})",
"create": "إنشاء $t(entity.playlist, {\"count\": 1}) {{playlist}}"
},
"createPlaylist": {
"input_public": "عام"
},
"createRadioStation": {
"input_homepageUrl": "رابط الرئيسية",
"input_name": "الأسم",
"input_streamUrl": "رابط البث",
"success": "تم إنشاء محطة راديو جديدة بنجاح",
"title": "إنشاء محطة راديو"
},
"editRadioStation": {
"success": "تم تحديث محطة الراديو بنجاح"
},
"deletePlaylist": {
"input_confirm": "أكتب أسم $t(entity.playlist, {\"count\": 1}) للتأكيد",
"success": "تم حذف $t(entity.playlist, {\"count\": 1}) بنجاح",
"title": "حذف $t(entity.playlist, {\"count\": 1})"
},
"editPlaylist": {
"success": "تم تحديث $t(entity.playlist, {\"count\": 1}) بنجاح",
"title": "تعديل $t(entity.playlist, {\"count\": 1})",
"publicJellyfinNote": "لسبب ما، لا يكشف Jellyfin عما إذا كانت قائمة التشغيل عامة أم لا. إذا كنت ترغب في إبقائها عامة، يرجى التأكد من تحديد الخيار التالي"
},
"lyricsExport": {
"export": "تصدير الكلمات",
"input_synced": "تصدير الكلمات المتزامنة"
},
"lyricSearch": {
"title": "البحث بالكلمات"
},
"queryEditor": {
"input_optionMatchAll": "تطابق الجميع",
"input_optionMatchAny": "تطابق أي",
"title": "محرر الاستعلامات",
"addRuleGroup": "إضافة مجموعة قواعد",
"removeRuleGroup": "إزالة مجموعة قواعد",
"resetToDefault": "استعادة الإعدادات الافتراضية"
},
"shareItem": {
"allowDownloading": "السماح بالتحميل",
"description": "الوصف"
},
"shuffleAll": {
"title": "تشغيل عشوائي",
"input_kind_albums": "ألبومات",
"input_kind_songs": "أغاني",
"input_kind": "إختيارات عشوائية",
"input_minYear": "من سنة",
"input_maxYear": "إلى سنة"
},
"updateServer": {
"success": "تم تحديث الخادم بنجاح",
"title": "تحديث الخادم"
}
},
"page": {
"albumArtistDetail": {
"favoriteSongs": "الأغاني المفضلة"
}
} }
} }
+923 -1102
View File
File diff suppressed because it is too large Load Diff
+920 -1068
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+431 -705
View File
File diff suppressed because it is too large Load Diff
+895 -1076
View File
File diff suppressed because it is too large Load Diff
+626 -774
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+652 -946
View File
File diff suppressed because it is too large Load Diff
+63 -63
View File
@@ -12,7 +12,7 @@
"unfavorite": "حذف از موردعلاقه‌ها", "unfavorite": "حذف از موردعلاقه‌ها",
"shuffle_off": "پخش تصادفی غیر فعال", "shuffle_off": "پخش تصادفی غیر فعال",
"skip_forward": "برو جلو", "skip_forward": "برو جلو",
"queue_moveToTop": "جابجا کردن انتخاب شده به بالا", "queue_moveToTop": "جابجا کردن انتخاب شده به پایین",
"queue_clear": "خالی کردن صف", "queue_clear": "خالی کردن صف",
"queue_remove": "حذف انتخاب شده", "queue_remove": "حذف انتخاب شده",
"addLast": "افزودن به پایان", "addLast": "افزودن به پایان",
@@ -24,7 +24,7 @@
"mute": "بی‌صدا کردن", "mute": "بی‌صدا کردن",
"playbackFetchCancel": "دارد طول می‌کشد... برای لفو کردن اعلان را ببندید", "playbackFetchCancel": "دارد طول می‌کشد... برای لفو کردن اعلان را ببندید",
"playbackFetchInProgress": "بارگذاری قطعه‌ها…", "playbackFetchInProgress": "بارگذاری قطعه‌ها…",
"queue_moveToBottom": "جابجا کردن انتخاب شده به پایین", "queue_moveToBottom": "جابجا کردن انتخاب شده به بالا",
"addNext": "افزودن به پسین", "addNext": "افزودن به پسین",
"favorite": "مورد علاقه", "favorite": "مورد علاقه",
"playSimilarSongs": "پخش آهنگ‌های همگون", "playSimilarSongs": "پخش آهنگ‌های همگون",
@@ -33,23 +33,23 @@
"muted": "بی‌صدا" "muted": "بی‌صدا"
}, },
"action": { "action": {
"editPlaylist": "ویرایش $t(entity.playlist, {\"count\": 1})", "editPlaylist": "ویرایش $t(entity.playlist_one)",
"goToPage": "برو به صفحهٔ", "goToPage": "برو به صفحهٔ",
"moveToTop": "انتقال به بالا", "moveToTop": "انتقال به بالا",
"clearQueue": "خالی کردن صف", "clearQueue": "خالی کردن صف",
"addToFavorites": "افزودن به $t(entity.favorite, {\"count\": 2})", "addToFavorites": "افزودن به $t(entity.favorite_other)",
"addToPlaylist": "افزودن به $t(entity.playlist, {\"count\": 1})", "addToPlaylist": "افزودن به $t(entity.playlist_one)",
"createPlaylist": "ساخت $t(entity.playlist, {\"count\": 1})", "createPlaylist": "ساخت $t(entity.playlist_one)",
"removeFromPlaylist": "حذف از $t(entity.playlist, {\"count\": 1})", "removeFromPlaylist": "حذف از $t(entity.playlist_one)",
"viewPlaylists": "نمایش $t(entity.playlist, {\"count\": 2})", "viewPlaylists": "نمایش $t(entity.playlist_other)",
"refresh": "$t(common.refresh)", "refresh": "$t(common.refresh)",
"deletePlaylist": "حذف $t(entity.playlist, {\"count\": 1})", "deletePlaylist": "حذف $t(entity.playlist_one)",
"removeFromQueue": "حذف از صف", "removeFromQueue": "حذف از صف",
"deselectAll": "لغو انتخاب همه", "deselectAll": "لغو انتخاب همه",
"moveToBottom": "انتقال به پایین", "moveToBottom": "انتقال به پایین",
"setRating": "تعیین امتیاز", "setRating": "تعیین امتیاز",
"toggleSmartPlaylistEditor": "تغییر ویرایشگر $t(entity.smartPlaylist)", "toggleSmartPlaylistEditor": "تغییر ویرایشگر $t(entity.smartPlaylist)",
"removeFromFavorites": "حذف از $t(entity.favorite, {\"count\": 2})", "removeFromFavorites": "حذف از $t(entity.favorite_other)",
"openIn": { "openIn": {
"lastfm": "باز کردن در Last.fm", "lastfm": "باز کردن در Last.fm",
"musicbrainz": "باز کردن در MusicBranz" "musicbrainz": "باز کردن در MusicBranz"
@@ -70,21 +70,22 @@
"hotkey_rate1": "امتیاز ۱ ستاره", "hotkey_rate1": "امتیاز ۱ ستاره",
"hotkey_skipForward": "برو جلو", "hotkey_skipForward": "برو جلو",
"disableLibraryUpdateOnStartup": "غیرفعال کردن بررسی آخرین نسخه در آغاز به کار برنامه", "disableLibraryUpdateOnStartup": "غیرفعال کردن بررسی آخرین نسخه در آغاز به کار برنامه",
"discordApplicationId_description": "the application ID for {{discord}} Rich Presence (defaults to {{defaultId}})", "discordApplicationId_description": "the application id for {{discord}} rich presence (defaults to {{defaultId}})",
"playButtonBehavior_optionAddLast": "$t(player.addLast)", "playButtonBehavior_optionAddLast": "$t(player.addLast)",
"hotkey_playbackPlay": "پخش", "hotkey_playbackPlay": "پخش",
"hotkey_volumeDown": "کم کردن صدا", "hotkey_volumeDown": "کم کردن صدا",
"audioPlayer_description": "پخش‌کنندهٔ صدا را برای پخش انتخاب کنید", "audioPlayer_description": "پخش‌کنندهٔ صدا را برای پخش انتخاب کنید",
"hotkey_globalSearch": "جست و جوی سراسری", "hotkey_globalSearch": "جست و جوی سراسری",
"disableAutomaticUpdates": "غیرفعال کردن به‌‌روزرسانی خودکار",
"exitToTray_description": "خروج از اپلیکیشن به system tray", "exitToTray_description": "خروج از اپلیکیشن به system tray",
"replayGainMode_optionAlbum": "$t(entity.album, {\"count\": 1})", "replayGainMode_optionAlbum": "$t(entity.album_one)",
"discordUpdateInterval_description": "فاصلهٔ بین هر به روزرسانی به ثانیه (حداقل ۱۵ ثانیه)", "discordUpdateInterval_description": "فاصلهٔ بین هر به روزرسانی به ثانیه (حداقل ۱۵ ثانیه)",
"audioExclusiveMode": "حالت اختصاصی صدا", "audioExclusiveMode": "حالت اختصاصی صدا",
"remotePassword": "رمز عبور کنترل از راه دور", "remotePassword": "رمز عبور کنترل از راه دور",
"language_description": "زبان اپلیکیشن را معین می‌کند $t(common.restartRequired)", "language_description": "زبان اپلیکیشن را معین می‌کند $t(common.restartRequired)",
"hotkey_rate3": "امتیاز ۳ ستاره", "hotkey_rate3": "امتیاز ۳ ستاره",
"font": "قلم", "font": "قلم",
"replayGainMode_optionTrack": "$t(entity.track, {\"count\": 1})", "replayGainMode_optionTrack": "$t(entity.track_one)",
"hotkey_toggleFullScreenPlayer": "تغییر به پخش‌کنندهٔ تمام‌صفحه", "hotkey_toggleFullScreenPlayer": "تغییر به پخش‌کنندهٔ تمام‌صفحه",
"hotkey_localSearch": "جست و جو در صفحه", "hotkey_localSearch": "جست و جو در صفحه",
"hotkey_toggleQueue": "تغییر صف", "hotkey_toggleQueue": "تغییر صف",
@@ -109,7 +110,7 @@
"customFontPath": "مسیر قلم سفارشی", "customFontPath": "مسیر قلم سفارشی",
"audioPlayer": "پخش‌کنندهٔ صدا", "audioPlayer": "پخش‌کنندهٔ صدا",
"hotkey_rate0": "حذف امتیاز", "hotkey_rate0": "حذف امتیاز",
"discordApplicationId": "{{discord}} application ID", "discordApplicationId": "{{discord}} application id",
"hotkey_volumeMute": "بستن صدا", "hotkey_volumeMute": "بستن صدا",
"showSkipButton": "نمایش دکمهٔ رد کردن", "showSkipButton": "نمایش دکمهٔ رد کردن",
"customFontPath_description": "مسیر قلم سفارشی را برای استفاده در اپلیکیشن مشخص کنید", "customFontPath_description": "مسیر قلم سفارشی را برای استفاده در اپلیکیشن مشخص کنید",
@@ -132,7 +133,7 @@
"buttonSize": "اندازه‌ی دکمه‌ی پخش نوار", "buttonSize": "اندازه‌ی دکمه‌ی پخش نوار",
"contextMenu": "پیکربندی فهرست زمینه (کلیک راست)", "contextMenu": "پیکربندی فهرست زمینه (کلیک راست)",
"buttonSize_description": "اندازه‌ی دکمه‌های پخش نوار", "buttonSize_description": "اندازه‌ی دکمه‌های پخش نوار",
"audioExclusiveMode_description": "حالت اختصاصی خروجی را فعال می‌کند. در این حالت، سامانه معمولاً قفل است و فقط MPV می‌تواند خروجی صدا دهد", "audioExclusiveMode_description": "حالت اختصاصی خروجی را فعال می‌کند. در این حالت، سامانه معمولاً قفل است و فقط mpv می‌تواند خروجی صدا دهد",
"clearQueryCache_description": "یک 'پاک‌سازی نرم' از فیشین. این فهرست‌های پخش و فراداده‌ی قطعه‌ها را تازه می‌کند و متن شعرهای ذخیره شده را بازنشانی می‌کند. پیکربندی‌ها، اعتبارنامه‌های سرویس‌دهنده و نگاره‌های کَش شده حفظ می‌شوند", "clearQueryCache_description": "یک 'پاک‌سازی نرم' از فیشین. این فهرست‌های پخش و فراداده‌ی قطعه‌ها را تازه می‌کند و متن شعرهای ذخیره شده را بازنشانی می‌کند. پیکربندی‌ها، اعتبارنامه‌های سرویس‌دهنده و نگاره‌های کَش شده حفظ می‌شوند",
"clearCache_description": "یک 'پاک‌سازی سخت' فیشین. افزون بر پاک‌سازی کَش فیشین، کَش مرورگر هم تهی می‌شود (نگاره‌های ذخیره شده و باقی دارایی‌ها). اعتبارنامه‌ها و پیکربندی‌ها حفظ می‌شوند", "clearCache_description": "یک 'پاک‌سازی سخت' فیشین. افزون بر پاک‌سازی کَش فیشین، کَش مرورگر هم تهی می‌شود (نگاره‌های ذخیره شده و باقی دارایی‌ها). اعتبارنامه‌ها و پیکربندی‌ها حفظ می‌شوند",
"contextMenu_description": "به شما اجازه می‌دهد که آیتم‌های نمایش داده شده در فهرستی که وقتی روی یک آیتم کلیک راست می‌کنید پدیدار می‌شود، را پنهان کنید. آیتم‌هایی که منتخب نیستند پنهان می‌شوند", "contextMenu_description": "به شما اجازه می‌دهد که آیتم‌های نمایش داده شده در فهرستی که وقتی روی یک آیتم کلیک راست می‌کنید پدیدار می‌شود، را پنهان کنید. آیتم‌هایی که منتخب نیستند پنهان می‌شوند",
@@ -176,7 +177,7 @@
"backward": "به عقب", "backward": "به عقب",
"increase": "افزایش", "increase": "افزایش",
"rating": "امتیاز", "rating": "امتیاز",
"bpm": "BPM", "bpm": "bpm",
"refresh": "تازه‌سازی", "refresh": "تازه‌سازی",
"unknown": "ناشناخته", "unknown": "ناشناخته",
"areYouSure": "مطمئنید؟", "areYouSure": "مطمئنید؟",
@@ -185,7 +186,7 @@
"left": "چپ", "left": "چپ",
"save": "ذخیره", "save": "ذخیره",
"right": "راست", "right": "راست",
"currentSong": "فعلی $t(entity.track, {\"count\": 1})", "currentSong": "فعلی $t(entity.track_one)",
"collapse": "بستن", "collapse": "بستن",
"trackNumber": "قطعه", "trackNumber": "قطعه",
"descending": "نزولی", "descending": "نزولی",
@@ -238,7 +239,7 @@
"none": "هیچ", "none": "هیچ",
"menu": "منو", "menu": "منو",
"restartRequired": "راه‌اندازی دوباره لازم است", "restartRequired": "راه‌اندازی دوباره لازم است",
"previousSong": "$t(entity.track, {\"count\": 1}) پیشین", "previousSong": "$t(entity.track_one) پیشین",
"noResultsFromQuery": "جست‌وجو نتیجه‌ای نداشت", "noResultsFromQuery": "جست‌وجو نتیجه‌ای نداشت",
"quit": "خروج", "quit": "خروج",
"expand": "گسترش", "expand": "گسترش",
@@ -255,8 +256,7 @@
"albumPeak": "اوج آلبوم", "albumPeak": "اوج آلبوم",
"mbid": "شناسه‌ی MusicBrainz", "mbid": "شناسه‌ی MusicBrainz",
"reload": "بارگذاری مجدد", "reload": "بارگذاری مجدد",
"setting_one": "پیکربندی", "setting": "پیکربندی",
"setting_other": "",
"trackGain": "گین قطعه", "trackGain": "گین قطعه",
"trackPeak": "اوج قطعه", "trackPeak": "اوج قطعه",
"translation": "ترجمه", "translation": "ترجمه",
@@ -301,25 +301,25 @@
"rating": "امتیاز", "rating": "امتیاز",
"search": "جست‌وجو", "search": "جست‌وجو",
"bitrate": "بیت‌ریت", "bitrate": "بیت‌ریت",
"genre": "$t(entity.genre, {\"count\": 1})", "genre": "$t(entity.genre_one)",
"recentlyAdded": "به تازگی افزوده شده", "recentlyAdded": "به تازگی افزوده شده",
"note": "توجه", "note": "توجه",
"name": "نام", "name": "نام",
"dateAdded": "تاریخ افزوده شدن", "dateAdded": "تاریخ افزوده شدن",
"releaseDate": "تاریخ انتشار", "releaseDate": "تاریخ انتشار",
"albumCount": "$t(entity.album, {\"count\": 2}) عدد", "albumCount": "$t(entity.album_other) عدد",
"path": "مسیر", "path": "مسیر",
"favorited": "موردعلاقه", "favorited": "موردعلاقه",
"albumArtist": "$t(entity.albumArtist, {\"count\": 1})", "albumArtist": "$t(entity.albumArtist_one)",
"isRecentlyPlayed": "به تازگی پخش شده است", "isRecentlyPlayed": "به تازگی پخش شده است",
"isFavorited": "موردعلاقه است", "isFavorited": "موردعلاقه است",
"bpm": "BPM", "bpm": "bpm",
"releaseYear": "سال انتشار", "releaseYear": "سال انتشار",
"id": "ID", "id": "id",
"disc": "دیسک", "disc": "دیسک",
"biography": "زندگی‌نامه", "biography": "زندگی‌نامه",
"songCount": "تعداد ترانه", "songCount": "تعداد ترانه",
"artist": "$t(entity.artist, {\"count\": 1})", "artist": "$t(entity.artist_one)",
"duration": "مدت", "duration": "مدت",
"isPublic": "عمومی است", "isPublic": "عمومی است",
"random": "تصادفی", "random": "تصادفی",
@@ -327,23 +327,23 @@
"toYear": "تا سال", "toYear": "تا سال",
"fromYear": "از سال", "fromYear": "از سال",
"criticRating": "امتیاز منتقدین", "criticRating": "امتیاز منتقدین",
"album": "$t(entity.album, {\"count\": 1})", "album": "$t(entity.album_one)",
"trackNumber": "قطعه", "trackNumber": "قطعه",
"communityRating": "رتبه بندی جامعه", "communityRating": "رتبه بندی جامعه",
"isCompilation": "مخلوط است" "isCompilation": "مخلوط است"
}, },
"form": { "form": {
"deletePlaylist": { "deletePlaylist": {
"title": "حذف $t(entity.playlist, {\"count\": 1})", "title": "حذف $t(entity.playlist_one)",
"success": "$t(entity.playlist, {\"count\": 1}) حذف شد", "success": "$t(entity.playlist_one) حذف شد",
"input_confirm": "برای تایید، نام $t(entity.playlist, {\"count\": 1}) را وارد کنید" "input_confirm": "برای تایید، نام $t(entity.playlist_one) را وارد کنید"
}, },
"createPlaylist": { "createPlaylist": {
"input_description": "$t(common.description)", "input_description": "$t(common.description)",
"title": "ساخت $t(entity.playlist, {\"count\": 1})", "title": "ساخت $t(entity.playlist_one)",
"input_public": "عمومی", "input_public": "عمومی",
"input_name": "$t(common.name)", "input_name": "$t(common.name)",
"success": "$t(entity.playlist, {\"count\": 1}) ساخته شد", "success": "$t(entity.playlist_one) ساخته شد",
"input_owner": "$t(common.owner)" "input_owner": "$t(common.owner)"
}, },
"addServer": { "addServer": {
@@ -360,19 +360,19 @@
"ignoreSsl": "نادیده گرفتن ssl ($t(common.restartRequired))" "ignoreSsl": "نادیده گرفتن ssl ($t(common.restartRequired))"
}, },
"addToPlaylist": { "addToPlaylist": {
"success": "$t(entity.song, {\"count\": 2}) به {{numOfPlaylists}}$t(entity.playlist, {\"count\": 2}) افزوده شد", "success": "$t(entity.song_other) به {{numOfPlaylists}}$t(entity.playlist_other) افزوده شد",
"title": "افزودن به $t(entity.playlist, {\"count\": 1})", "title": "افزودن به $t(entity.playlist_one)",
"input_playlists": "$t(entity.playlist, {\"count\": 2})", "input_playlists": "$t(entity.playlist_other)",
"input_skipDuplicates": "پرش از تکراری‌ها" "input_skipDuplicates": "پرش از تکراری‌ها"
}, },
"lyricSearch": { "lyricSearch": {
"input_name": "$t(common.name)", "input_name": "$t(common.name)",
"input_artist": "$t(entity.artist, {\"count\": 1})", "input_artist": "$t(entity.artist_one)",
"title": "جست‌وجو در متن شعر" "title": "جست‌وجو در متن شعر"
}, },
"editPlaylist": { "editPlaylist": {
"title": "ویرایش $t(entity.playlist, {\"count\": 1})", "title": "ویرایش $t(entity.playlist_one)",
"success": "$t(entity.playlist, {\"count\": 1}) با موفقیت بروزرسانی شد", "success": "$t(entity.playlist_one) با موفقیت بروزرسانی شد",
"publicJellyfinNote": "جلی‌فین به دلیلی این‌که فهرست پخش عمومی‌ست یا خصوصی را فاش نمی‌کند. اگر می‌خواهید این عمومی باقی بماند، لطفاٌ ورودی پیش‌رو را منتخب داشته باشید" "publicJellyfinNote": "جلی‌فین به دلیلی این‌که فهرست پخش عمومی‌ست یا خصوصی را فاش نمی‌کند. اگر می‌خواهید این عمومی باقی بماند، لطفاٌ ورودی پیش‌رو را منتخب داشته باشید"
}, },
"queryEditor": { "queryEditor": {
@@ -417,7 +417,7 @@
"artistWithCount_other": "{{count}} هنرمند", "artistWithCount_other": "{{count}} هنرمند",
"folder_one": "پوشه", "folder_one": "پوشه",
"folder_other": "پوشه‌ها", "folder_other": "پوشه‌ها",
"smartPlaylist": "$t(entity.playlist, {\"count\": 1}) هوشمند", "smartPlaylist": "$t(entity.playlist_one) هوشمند",
"album_one": "آلبوم", "album_one": "آلبوم",
"album_other": "آلبوم‌ها", "album_other": "آلبوم‌ها",
"genreWithCount_one": "{{count}} ژانر", "genreWithCount_one": "{{count}} ژانر",
@@ -431,12 +431,12 @@
}, },
"page": { "page": {
"albumList": { "albumList": {
"title": "$t(entity.album, {\"count\": 2})", "title": "$t(entity.album_other)",
"artistAlbums": "آلبوم‌های {{artist}}", "artistAlbums": "آلبوم‌های {{artist}}",
"genreAlbums": "\"{{genre}}\" $t(entity.album, {\"count\": 2})" "genreAlbums": "\"{{genre}}\" $t(entity.album_other)"
}, },
"appMenu": { "appMenu": {
"settings": "$t(common.setting, {\"count\": 2})", "settings": "$t(common.setting_other)",
"selectServer": "گزینش سرویس‌دهنده", "selectServer": "گزینش سرویس‌دهنده",
"expandSidebar": "گسترش نوار کناری", "expandSidebar": "گسترش نوار کناری",
"collapseSidebar": "فروکش نوار کناری", "collapseSidebar": "فروکش نوار کناری",
@@ -451,11 +451,11 @@
"appearsOn": "مشاهده می‌شود در", "appearsOn": "مشاهده می‌شود در",
"about": "درباره‌ی {{artist}}", "about": "درباره‌ی {{artist}}",
"recentReleases": "عرضه‌های اخیر", "recentReleases": "عرضه‌های اخیر",
"viewAllTracks": "نمایش همه‌ی $t(entity.track, {\"count\": 2})", "viewAllTracks": "نمایش همه‌ی $t(entity.track_other)",
"topSongsFrom": "قطعه‌های برتر از {{title}}", "topSongsFrom": "قطعه‌های برتر از {{title}}",
"viewAll": "نمایش همه", "viewAll": "نمایش همه",
"viewDiscography": "نمایش کاتالوگ", "viewDiscography": "نمایش کاتالوگ",
"relatedArtists": "$t(entity.artist, {\"count\": 2}) مربوطه", "relatedArtists": "$t(entity.artist_other) مربوطه",
"topSongs": "قطعه‌های برتر" "topSongs": "قطعه‌های برتر"
}, },
"contextMenu": { "contextMenu": {
@@ -523,21 +523,21 @@
"playbackTab": "پخش" "playbackTab": "پخش"
}, },
"sidebar": { "sidebar": {
"genres": "$t(entity.genre, {\"count\": 2})", "genres": "$t(entity.genre_other)",
"playlists": "$t(entity.playlist, {\"count\": 2})", "playlists": "$t(entity.playlist_other)",
"search": "$t(common.search)", "search": "$t(common.search)",
"albumArtists": "$t(entity.albumArtist, {\"count\": 2})", "albumArtists": "$t(entity.albumArtist_other)",
"albums": "$t(entity.album, {\"count\": 2})", "albums": "$t(entity.album_other)",
"folders": "$t(entity.folder, {\"count\": 2})", "folders": "$t(entity.folder_other)",
"artists": "$t(entity.artist, {\"count\": 2})", "artists": "$t(entity.artist_other)",
"home": "$t(common.home)", "home": "$t(common.home)",
"nowPlaying": "پخش کنونی", "nowPlaying": "پخش کنونی",
"tracks": "$t(entity.track, {\"count\": 2})", "tracks": "$t(entity.track_other)",
"settings": "$t(common.setting, {\"count\": 2})", "settings": "$t(common.setting_other)",
"shared": "$t(entity.playlist, {\"count\": 2}) اشتراک‌گذاری شده" "shared": "$t(entity.playlist_other) اشتراک‌گذاری شده"
}, },
"albumDetail": { "albumDetail": {
"moreFromArtist": "موارد بیشتر از این $t(entity.artist, {\"count\": 1})", "moreFromArtist": "موارد بیشتر از این $t(entity.artist_one)",
"moreFromGeneric": "موارد بیشتر از {{item}}", "moreFromGeneric": "موارد بیشتر از {{item}}",
"released": "عرضه شده" "released": "عرضه شده"
}, },
@@ -550,9 +550,9 @@
"editServerDetailsTooltip": "ویرایش ریزگان سرویس‌دهنده" "editServerDetailsTooltip": "ویرایش ریزگان سرویس‌دهنده"
}, },
"genreList": { "genreList": {
"showAlbums": "نمایش $t(entity.genre, {\"count\": 1}) $t(entity.album, {\"count\": 2})", "showAlbums": "نمایش $t(entity.genre_one) $t(entity.album_other)",
"title": "$t(entity.genre, {\"count\": 2})", "title": "$t(entity.genre_other)",
"showTracks": "نمایش $t(entity.genre, {\"count\": 1}) $t(entity.track, {\"count\": 2})" "showTracks": "نمایش $t(entity.genre_one) $t(entity.track_other)"
}, },
"globalSearch": { "globalSearch": {
"commands": { "commands": {
@@ -563,15 +563,15 @@
"title": "فرمان‌ها" "title": "فرمان‌ها"
}, },
"playlistList": { "playlistList": {
"title": "$t(entity.playlist, {\"count\": 2})" "title": "$t(entity.playlist_other)"
}, },
"trackList": { "trackList": {
"title": "$t(entity.track, {\"count\": 2})", "title": "$t(entity.track_other)",
"artistTracks": "قطعه‌های {{artist}}", "artistTracks": "قطعه‌های {{artist}}",
"genreTracks": "$t(entity.track, {\"count\": 2}) \"{{genre}}\"" "genreTracks": "$t(entity.track_other) \"{{genre}}\""
}, },
"albumArtistList": { "albumArtistList": {
"title": "$t(entity.albumArtist, {\"count\": 2})" "title": "$t(entity.albumArtist_other)"
}, },
"itemDetail": { "itemDetail": {
"copyPath": "کپی کردن مسیر در کلیپ‌بورد", "copyPath": "کپی کردن مسیر در کلیپ‌بورد",
@@ -584,11 +584,11 @@
"size": "$t(common.size)", "size": "$t(common.size)",
"lastPlayed": "آخرین بار پخش شده", "lastPlayed": "آخرین بار پخش شده",
"discNumber": "دیسک", "discNumber": "دیسک",
"songCount": "$t(entity.track, {\"count\": 2})", "songCount": "$t(entity.track_other)",
"title": "عنوان", "title": "عنوان",
"trackNumber": "قطعه", "trackNumber": "قطعه",
"favorite": "مورد علاقه", "favorite": "مورد علاقه",
"genre": "$t(entity.genre, {\"count\": 1})", "genre": "$t(entity.genre_one)",
"comment": "دیدگاه", "comment": "دیدگاه",
"playCount": "تعداد پخش", "playCount": "تعداد پخش",
"rating": "امتیاز", "rating": "امتیاز",
+643 -840
View File
File diff suppressed because it is too large Load Diff
+861 -1204
View File
File diff suppressed because it is too large Load Diff
+788 -783
View File
File diff suppressed because it is too large Load Diff
+558 -1202
View File
File diff suppressed because it is too large Load Diff
+631 -878
View File
File diff suppressed because it is too large Load Diff
+200 -591
View File
File diff suppressed because it is too large Load Diff
+66 -286
View File
@@ -1,34 +1,31 @@
{ {
"action": { "action": {
"createPlaylist": "$t(entity.playlist, {\"count\": 1}) 생성", "createPlaylist": "$t(entity.playlist_one) 생성",
"addToFavorites": "$t(entity.favorite, {\"count\": 2})에 추가", "addToFavorites": "$t(entity.favorite_other)에 추가",
"addToPlaylist": "$t(entity.playlist, {\"count\": 1})에 추가", "addToPlaylist": "$t(entity.playlist_one)에 추가",
"clearQueue": "대기열 지우기", "clearQueue": "대기열 지우기",
"deletePlaylist": "$t(entity.playlist, {\"count\": 1}) 삭제", "deletePlaylist": "$t(entity.playlist_one) 삭제",
"deselectAll": "모두 선택 해제", "deselectAll": "모두 선택 해제",
"editPlaylist": "$t(entity.playlist, {\"count\": 1}) 편집", "editPlaylist": "$t(entity.playlist_one) 편집",
"goToPage": "페이지 이동", "goToPage": "페이지 이동",
"moveToBottom": "맨 아래로 이동", "moveToBottom": "맨 아래로 이동",
"moveToTop": "맨 위로 이동", "moveToTop": "맨 위로 이동",
"moveToNext": "다음으로 이동", "moveToNext": "다음으로 이동",
"removeFromQueue": "대기열에서 제거", "removeFromQueue": "대기열에서 제거",
"refresh": "$t(common.refresh)", "refresh": "$t(common.refresh)",
"removeFromFavorites": "$t(entity.favorite, {\"count\": 2})에서 제거", "removeFromFavorites": "$t(entity.favorite_other)에서 제거",
"removeFromPlaylist": "$t(entity.playlist, {\"count\": 1})에서 제거", "removeFromPlaylist": "$t(entity.playlist_one)에서 제거",
"openIn": { "openIn": {
"musicbrainz": "MusicBrainz에서 보기", "musicbrainz": "MusicBrainz에서 보기",
"lastfm": "Last.fm에서 보기", "lastfm": "Last.fm에서 보기"
"listenbrainz": "ListenBrainz에서 열기",
"qobuz": "Qobuz에서 열기",
"spotify": "Spotify에서 열기"
}, },
"viewPlaylists": "$t(entity.playlist, {\"count\": 2}) 보기", "viewPlaylists": "$t(entity.playlist_other) 보기",
"setRating": "평점 지정", "setRating": "평점 지정",
"toggleSmartPlaylistEditor": "$t(entity.smartPlaylist) 편집기 펼치기", "toggleSmartPlaylistEditor": "$t(entity.smartPlaylist) 편집기 펼치기",
"addOrRemoveFromSelection": "선택항목에서 추가 또는 제거", "addOrRemoveFromSelection": "선택항목에서 추가 또는 제거",
"selectRangeOfItems": "항목의 범위 선택", "selectRangeOfItems": "항목의 범위 선택",
"createRadioStation": "$t(entity.radioStation, {\"count\": 1}) 생성", "createRadioStation": "$t(entity.radioStation_one) 생성",
"deleteRadioStation": "$t(entity.radioStation, {\"count\": 1}) 삭제", "deleteRadioStation": "$t(entity.radioStation_one) 삭제",
"selectAll": "전부 선택", "selectAll": "전부 선택",
"downloadStarted": "{{count}}개 항목 다운로드 시작했습니다", "downloadStarted": "{{count}}개 항목 다운로드 시작했습니다",
"moveUp": "위로 옮기기", "moveUp": "위로 옮기기",
@@ -40,10 +37,7 @@
"shuffleAll": "모두 섞기", "shuffleAll": "모두 섞기",
"shuffleSelected": "선택항목 섞기", "shuffleSelected": "선택항목 섞기",
"viewMore": "더 보기", "viewMore": "더 보기",
"openApplicationDirectory": "앱 디렉토리 열기", "openApplicationDirectory": "앱 디렉토리 열기"
"goToCurrent": "현재 항목으로 이동",
"collapseAllFolders": "모든 폴더 접기",
"expandAllFolders": "모든 폴더 확장"
}, },
"common": { "common": {
"translation": "번역", "translation": "번역",
@@ -65,7 +59,7 @@
"backward": "뒤로", "backward": "뒤로",
"saveAs": "(으)로 저장하기", "saveAs": "(으)로 저장하기",
"search": "검색", "search": "검색",
"setting_other": "설정", "setting": "설정",
"share": "공유", "share": "공유",
"size": "크기", "size": "크기",
"sortOrder": "순서", "sortOrder": "순서",
@@ -80,7 +74,7 @@
"comingSoon": "조만간…", "comingSoon": "조만간…",
"configure": "설정", "configure": "설정",
"confirm": "확인", "confirm": "확인",
"currentSong": "현재 $t(entity.track, {\"count\": 1})", "currentSong": "현재 $t(entity.track_one)",
"decrease": "감소", "decrease": "감소",
"delete": "삭제", "delete": "삭제",
"descending": "내림차순", "descending": "내림차순",
@@ -102,7 +96,7 @@
"path": "경로", "path": "경로",
"playerMustBePaused": "플레이어가 일시정지 되어야 합니다", "playerMustBePaused": "플레이어가 일시정지 되어야 합니다",
"preview": "미리보기", "preview": "미리보기",
"previousSong": "이전곡 $t(entity.track, {\"count\": 1})", "previousSong": "이전곡 $t(entity.track_one)",
"quit": "종료", "quit": "종료",
"refresh": "새로고침", "refresh": "새로고침",
"reload": "리로드", "reload": "리로드",
@@ -112,7 +106,7 @@
"ascending": "오름차순", "ascending": "오름차순",
"areYouSure": "확실한가요?", "areYouSure": "확실한가요?",
"bitrate": "비트 전송률", "bitrate": "비트 전송률",
"bpm": "BPM", "bpm": "bpm",
"biography": "바이오그래피", "biography": "바이오그래피",
"center": "중앙", "center": "중앙",
"channel_other": "채널", "channel_other": "채널",
@@ -133,7 +127,7 @@
"filters": "필터", "filters": "필터",
"noResultsFromQuery": "쿼리 결과가 없습니다", "noResultsFromQuery": "쿼리 결과가 없습니다",
"note": "노트", "note": "노트",
"ok": "Ok", "ok": "OK",
"owner": "소유자", "owner": "소유자",
"sampleRate": "샘플레이트", "sampleRate": "샘플레이트",
"tags": "태그", "tags": "태그",
@@ -155,18 +149,7 @@
"sort": "정렬", "sort": "정렬",
"gridRows": "행 그리드", "gridRows": "행 그리드",
"tableColumns": "테이블 열", "tableColumns": "테이블 열",
"itemsMore": "{{count}}개 더", "itemsMore": "{{count}}개 더"
"back": "뒤로",
"example": "예",
"openFolder": "폴더 열기",
"filter_single": "미혼",
"filter_multiple": "다중",
"grouping": "그룹화",
"mood": "기분",
"numberOfResults": "결과 {{numberOfResults}}개",
"retry": "다시 해 보다",
"rename": "이름 변경",
"newVersionAvailable": "새로운 버전이 나왔습니다"
}, },
"entity": { "entity": {
"albumWithCount_other": "{{count}} 앨범", "albumWithCount_other": "{{count}} 앨범",
@@ -185,7 +168,7 @@
"song_other": "곡", "song_other": "곡",
"play_other": "{{count}} 재생", "play_other": "{{count}} 재생",
"playlistWithCount_other": "{{count}} 재생목록", "playlistWithCount_other": "{{count}} 재생목록",
"smartPlaylist": "스마트 $t(entity.playlist, {\"count\": 1})", "smartPlaylist": "스마트 $t(entity.playlist_one)",
"track_other": "트랙", "track_other": "트랙",
"radioStation_other": "라디오 방송국", "radioStation_other": "라디오 방송국",
"radioStationWithCount_other": "{{count}}개 라디오 방송국" "radioStationWithCount_other": "{{count}}개 라디오 방송국"
@@ -214,15 +197,7 @@
"localFontAccessDenied": "로컬 글꼴에 접근 거부되었습니다", "localFontAccessDenied": "로컬 글꼴에 접근 거부되었습니다",
"apiRouteError": "요청 보내기 실패", "apiRouteError": "요청 보내기 실패",
"badValue": "옵션이 없습니다 {{value}}. 이 값은 더이상 존재하지 않습니다", "badValue": "옵션이 없습니다 {{value}}. 이 값은 더이상 존재하지 않습니다",
"notificationDenied": "알림에 대한 권한이 거부되었습니다. 이 설정은 변경되지 않습니다", "notificationDenied": "알림에 대한 권한이 거부되었습니다. 이 설정은 변경되지 않습니다"
"invalidJson": "유효하지 않은 JSON",
"multipleServerSaveQueueError": "재생 대기열에 현재 서버에 속하지 않은 곡이 하나 이상 포함되어 있습니다. 이는 지원되지 않습니다",
"noNetwork": "서버를 이용할 수 없음",
"noNetworkDescription": "이 서버에 연결할 수 없습니다",
"playbackPausedDueToError": "오류로 인해 재생이 일시 중지되었습니다",
"saveQueueFailed": "큐 저장 실패",
"serverLockSingleServer": "서버가 잠겨 있을 때는 서버를 하나만 허용합니다",
"settingsSyncError": "렌더러와 메인 프로세스의 설정 간에 불일치가 발견되었습니다. 변경 사항을 적용하려면 애플리케이션을 다시 시작하십시오"
}, },
"filter": { "filter": {
"title": "곡명", "title": "곡명",
@@ -239,22 +214,22 @@
"dateAdded": "추가된 날짜", "dateAdded": "추가된 날짜",
"lastPlayed": "마지막으로 재생한", "lastPlayed": "마지막으로 재생한",
"mostPlayed": "가장 많이 재생한", "mostPlayed": "가장 많이 재생한",
"album": "$t(entity.album, {\"count\": 1})", "album": "$t(entity.album_one)",
"albumArtist": "$t(entity.albumArtist, {\"count\": 1})", "albumArtist": "$t(entity.albumArtist_one)",
"artist": "$t(entity.artist, {\"count\": 1})", "artist": "$t(entity.artist_one)",
"communityRating": "커뮤니티 평점", "communityRating": "커뮤니티 평점",
"criticRating": "비평가 평점", "criticRating": "비평가 평점",
"disc": "디스크", "disc": "디스크",
"bitrate": "비트 전송률", "bitrate": "비트 전송률",
"biography": "바이오그래피", "biography": "바이오그래피",
"channels": "$t(common.channel, {\"count\": 2})", "channels": "$t(common.channel_other)",
"duration": "길이", "duration": "길이",
"bpm": "BPM", "bpm": "bpm",
"albumCount": "$t(entity.album, {\"count\": 2}) 앨범수", "albumCount": "$t(entity.album_other) 앨범수",
"comment": "코멘트", "comment": "코멘트",
"favorited": "즐겨찾기", "favorited": "즐겨찾기",
"fromYear": "시작 년도", "fromYear": "시작 년도",
"genre": "$t(entity.genre, {\"count\": 1})", "genre": "$t(entity.genre_one)",
"id": "아이디", "id": "아이디",
"isCompilation": "편집앨범 여부", "isCompilation": "편집앨범 여부",
"isFavorited": "즐겨찾기 여부", "isFavorited": "즐겨찾기 여부",
@@ -267,10 +242,7 @@
"songCount": "곡 갯수", "songCount": "곡 갯수",
"toYear": "년도까지", "toYear": "년도까지",
"trackNumber": "트랙", "trackNumber": "트랙",
"explicitStatus": "$t(common.explicitStatus)", "explicitStatus": "$t(common.explicitStatus)"
"matchAnd": "그리고",
"matchOr": "또는",
"sortName": "이름 정렬"
}, },
"form": { "form": {
"addServer": { "addServer": {
@@ -279,45 +251,37 @@
"input_name": "서버 이름", "input_name": "서버 이름",
"input_password": "비밀번호", "input_password": "비밀번호",
"input_savePassword": "비밀번호 저장하기", "input_savePassword": "비밀번호 저장하기",
"input_url": "URL", "input_url": "url",
"error_savePassword": "비밀번호를 저장하는 도중 오류가 발생했습니다", "error_savePassword": "비밀번호를 저장하는 도중 오류가 발생했습니다",
"ignoreCors": "CORS 무시 ($t(common.restartRequired))", "ignoreCors": "CORS 무시 ($t(common.restartRequired))",
"ignoreSsl": "SSL 무시 ($t(common.restartRequired))", "ignoreSsl": "SSL 무시 ($t(common.restartRequired))",
"input_legacyAuthentication": "레거시 인증 사용", "input_legacyAuthentication": "레거시 인증 사용",
"input_username": "유저 이름", "input_username": "유저 이름",
"input_preferInstantMix": "즉석 믹스 선호", "input_preferInstantMix": "즉석 믹스 선호",
"input_preferInstantMixDescription": "비슷한 곳을 찾기 위해 즉석 믹스를 사용합니다. 이 명령을 수정하기 위한 플러그인을 설치한 경우 유용합니다", "input_preferInstantMixDescription": "비슷한 곳을 찾기 위해 즉석 믹스를 사용합니다. 이 명령을 수정하기 위한 플러그인을 설치한 경우 유용합니다"
"input_preferRemoteUrl": "공개 URL 선호",
"input_remoteUrl": "공개 URL",
"input_remoteUrlPlaceholder": "선택 사항: 외부 기능을 위한 공개 URL"
}, },
"addToPlaylist": { "addToPlaylist": {
"input_skipDuplicates": "중복 건너뛰기", "input_skipDuplicates": "중복 건너뛰기",
"title": "$t(entity.playlist, {\"count\": 1}) 에 추가", "title": "$t(entity.playlist_one) 에 추가",
"input_playlists": "$t(entity.playlist, {\"count\": 2})", "input_playlists": "$t(entity.playlist_other)",
"success": "$t(entity.playlistWithCount, {\"count\": {{numOfPlaylists}} })에 $t(entity.trackWithCount, {\"count\": {{message}} })가 추가되었습니다", "success": "$t(entity.playlistWithCount, {\"count\": {{numOfPlaylists}} })에 $t(entity.trackWithCount, {\"count\": {{message}} })가 추가되었습니다",
"create": "$t(entity.playlist, {\"count\": 1}) {{playlist}} 생성", "create": "$t(entity.playlist_one) {{playlist}} 생성",
"searchOrCreate": "$t(entity.playlist, {\"count\": 2}) 검색 또는 입력하여 새로 만들기", "searchOrCreate": "$t(entity.playlist_other) 검색 또는 입력하여 새로 만들기"
"noneAdded": "$t(entity.playlist, {\"count\": 1}) '{{playlist}}'에 트랙이 추가되지 않았습니다"
}, },
"lyricSearch": { "lyricSearch": {
"title": "가사 검색", "title": "가사 검색",
"input_name": "$t(common.name)", "input_name": "$t(common.name)",
"input_artist": "$t(entity.artist, {\"count\": 1})" "input_artist": "$t(entity.artist_one)"
}, },
"queryEditor": { "queryEditor": {
"input_optionMatchAll": "모두 일치", "input_optionMatchAll": "모두 일치",
"input_optionMatchAny": "무엇이든 일치", "input_optionMatchAny": "무엇이든 일치",
"title": "쿼리 편집기", "title": "쿼리 편집기"
"addRuleGroup": "규칙 그룹 추가",
"removeRuleGroup": "규칙 그룹 제거",
"resetToDefault": "기본값으로 초기화",
"clearFilters": "필터 초기화"
}, },
"editPlaylist": { "editPlaylist": {
"title": "$t(entity.playlist, {\"count\": 1}) 편집", "title": "$t(entity.playlist_one) 편집",
"publicJellyfinNote": "Jellyfin은 재생목록 공개 여부를 노출하지 않습니다. 만약 공개되길 원한다면 다음을 선택하세요", "publicJellyfinNote": "Jellyfin은 재생목록 공개 여부를 노출하지 않습니다. 만약 공개되길 원한다면 다음을 선택하세요",
"success": "$t(entity.playlist, {\"count\": 1}) 업데이트 되었습니다" "success": "$t(entity.playlist_one) 업데이트 되었습니다"
}, },
"shareItem": { "shareItem": {
"allowDownloading": "다운로드 허용", "allowDownloading": "다운로드 허용",
@@ -325,9 +289,7 @@
"success": "클립보드에 공유 링크를 복사했습니다 (또는 열어보려면 클릭하세요)", "success": "클립보드에 공유 링크를 복사했습니다 (또는 열어보려면 클릭하세요)",
"expireInvalid": "만료 날짜는 미래 날짜여야만 합니다", "expireInvalid": "만료 날짜는 미래 날짜여야만 합니다",
"createFailed": "공유 링크를 생성하는데 실패하였습니다 (혹시 공유하기 설정되어 있나요?)", "createFailed": "공유 링크를 생성하는데 실패하였습니다 (혹시 공유하기 설정되어 있나요?)",
"setExpiration": "만료 기간 설정하기", "setExpiration": "만료 기간 설정하기"
"copyToClipboard": "클립보드로 복사: Ctrl+C, Enter",
"successMustClick": "공유가 성공적으로 생성되었습니다. 여기를 클릭하여 여세요"
}, },
"updateServer": { "updateServer": {
"title": "서버 업데이트", "title": "서버 업데이트",
@@ -336,58 +298,20 @@
"createPlaylist": { "createPlaylist": {
"input_description": "$t(common.description)", "input_description": "$t(common.description)",
"input_name": "$t(common.name)", "input_name": "$t(common.name)",
"success": "$t(entity.playlist, {\"count\": 1})를 생성했습니다", "success": "$t(entity.playlist_one)를 생성했습니다",
"input_owner": "$t(common.owner)", "input_owner": "$t(common.owner)",
"input_public": "공개", "input_public": "공개",
"title": "$t(entity.playlist, {\"count\": 1}) 생성" "title": "$t(entity.playlist_one) 생성"
}, },
"deletePlaylist": { "deletePlaylist": {
"input_confirm": "확인을 위해 $t(entity.playlist, {\"count\": 1})의 이름을 적어주세요", "input_confirm": "확인을 위해 $t(entity.playlist_one)의 이름을 적어주세요",
"success": "$t(entity.playlist, {\"count\": 1})가 삭제되었습니다", "success": "$t(entity.playlist_one)가 삭제되었습니다",
"title": "$t(entity.playlist, {\"count\": 1}) 삭제" "title": "$t(entity.playlist_one) 삭제"
}, },
"privateMode": { "privateMode": {
"enabled": "프라이빗 모드가 활성화되었습니다. 재생상태가 외부 서비스에 지금부터 노출되지 않습니다", "enabled": "프라이빗 모드가 활성화되었습니다. 재생상태가 외부 서비스에 지금부터 노출되지 않습니다",
"disabled": "프라이빗 모드가 비활성화되었습니다. 재생상태가 외부서비스에서 지금부터 표시됩니다", "disabled": "프라이빗 모드가 비활성화되었습니다. 재생상태가 외부서비스에서 지금부터 표시됩니다",
"title": "프라이빗 모드" "title": "프라이빗 모드"
},
"largeFetchConfirmation": {
"title": "대기열에 항목을 추가하세요",
"description": "이 작업은 현재 필터링된 보기의 모든 항목을 추가합니다"
},
"createRadioStation": {
"success": "라디오 방송국이 성공적으로 생성되었습니다",
"title": "라디오 방송국 만들기",
"input_homepageUrl": "홈페이지 URL",
"input_name": "명의",
"input_streamUrl": "스트림 URL"
},
"editRadioStation": {
"success": "라디오 방송국이 성공적으로 업데이트되었습니다"
},
"lyricsExport": {
"export": "가사 내보내기",
"input_synced": "동기화된 가사 내보내기",
"input_offset": "$t(setting.lyricOffset)"
},
"saveQueue": {
"success": "재생 대기열을 서버에 저장했습니다"
},
"shuffleAll": {
"title": "무작위 재생",
"input_kind_albums": "앨범",
"input_kind_songs": "노래들",
"input_kind": "무작위 선택",
"input_limit_albums": "앨범이 몇 장인가요?",
"input_limit_songs": "몇 곡인가요?",
"input_genre": "$t(entity.genre, {\"count\": 1})",
"input_limit": "몇 곡인가요?",
"input_minYear": "연도부터",
"input_maxYear": "연도까지",
"input_played": "재생 필터",
"input_played_optionAll": "모든 트랙",
"input_played_optionUnplayed": "재생하지 않은 트랙만",
"input_played_optionPlayed": "재생된 트랙만"
} }
}, },
"page": { "page": {
@@ -401,13 +325,7 @@
"collapseSidebar": "사이드바 줄이기", "collapseSidebar": "사이드바 줄이기",
"expandSidebar": "사이드바 확장", "expandSidebar": "사이드바 확장",
"privateModeOff": "프라이빗 모드 끄기", "privateModeOff": "프라이빗 모드 끄기",
"privateModeOn": "프라이빗 모드 켜기", "privateModeOn": "프라이빗 모드 켜기"
"commandPalette": "명령 팔레트 열기",
"quit": "$t(common.quit)",
"selectMusicFolder": "음악 폴더 선택",
"noMusicFolder": "음악 폴더가 선택되지 않았습니다",
"multipleMusicFolders": "{{count}}개의 음악 폴더가 선택되었습니다",
"settings": "$t(common.setting, {\"count\": 2})"
}, },
"manageServers": { "manageServers": {
"title": "서버 설정하기", "title": "서버 설정하기",
@@ -432,9 +350,7 @@
"lyricGap": "가사 간격", "lyricGap": "가사 간격",
"lyricSize": "가사 크기", "lyricSize": "가사 크기",
"showLyricMatch": "가사 일치 표시", "showLyricMatch": "가사 일치 표시",
"showLyricProvider": "가사 제공자 표시", "showLyricProvider": "가사 제공자 표시"
"lyricOpacityNonActive": "비활성 가사 불투명도",
"lyricScaleNonActive": "비활성 서정적 척도"
}, },
"lyrics": "가사", "lyrics": "가사",
"related": "관련", "related": "관련",
@@ -446,64 +362,35 @@
"download": "다운로드", "download": "다운로드",
"numberSelected": "{{count}}개 선택됨", "numberSelected": "{{count}}개 선택됨",
"shareItem": "공유", "shareItem": "공유",
"goToAlbum": "$t(entity.album, {\"count\": 1})으로 이동", "goToAlbum": "$t(entity.album_one)으로 이동",
"goToAlbumArtist": "$t(entity.albumArtist, {\"count\": 1})으로 이동", "goToAlbumArtist": "$t(entity.albumArtist_one)으로 이동",
"showDetails": "추가정보", "showDetails": "추가정보"
"addFavorite": "$t(action.addToFavorites)",
"addLast": "$t(player.addLast)",
"addNext": "$t(player.addNext)",
"addToFavorites": "$t(action.addToFavorites)",
"addToPlaylist": "$t(action.addToPlaylist)",
"createPlaylist": "$t(action.createPlaylist)",
"deletePlaylist": "$t(action.deletePlaylist)",
"deselectAll": "$t(action.deselectAll)",
"moveItems": "$t(action.moveItems)",
"moveToNext": "$t(action.moveToNext)",
"moveToBottom": "$t(action.moveToBottom)",
"moveToTop": "$t(action.moveToTop)",
"play": "$t(player.play)",
"playSimilarSongs": "$t(player.playSimilarSongs)",
"removeFromFavorites": "$t(action.removeFromFavorites)",
"removeFromPlaylist": "$t(action.removeFromPlaylist)",
"removeFromQueue": "$t(action.removeFromQueue)",
"setRating": "$t(action.setRating)",
"playShuffled": "$t(player.shuffle)",
"goTo": "이동"
}, },
"albumArtistDetail": { "albumArtistDetail": {
"about": "{{artist}}에 대해", "about": "{{artist}}에 대해",
"viewDiscography": "디스코그래피 보기", "viewDiscography": "디스코그래피 보기",
"appearsOn": "참여 앨범", "appearsOn": "참여 앨범",
"recentReleases": "최근 앨범", "recentReleases": "최근 앨범",
"relatedArtists": "연관 $t(entity.artist, {\"count\": 2})", "relatedArtists": "연관 $t(entity.artist_other)",
"topSongs": "최고의 곡들", "topSongs": "최고의 곡들",
"topSongsFrom": "{{title}}이 포함된 최고의 곡들", "topSongsFrom": "{{title}}이 포함된 최고의 곡들",
"viewAll": "전부 보이기", "viewAll": "전부 보이기",
"viewAllTracks": "$t(entity.track, {\"count\": 2}) 전부 보이기", "viewAllTracks": "$t(entity.track_other) 전부 보이기"
"favoriteSongs": "좋아하는 노래들",
"groupingTypeAll": "모든 릴리스 유형",
"groupingTypePrimary": "주요 릴리스 유형",
"topSongsCommunity": "공동체",
"topSongsPersonal": "개인의",
"favoriteSongsFrom": "{{title}}에서 가장 좋아하는 곡들"
}, },
"albumArtistList": { "albumArtistList": {
"title": "$t(entity.albumArtist, {\"count\": 2})" "title": "$t(entity.albumArtist_other)"
}, },
"albumDetail": { "albumDetail": {
"moreFromArtist": "$t(entity.artist, {\"count\": 1}) 더 보기", "moreFromArtist": "$t(entity.artist_one) 더 보기",
"moreFromGeneric": "{{item}} 더 보기", "moreFromGeneric": "{{item}} 더 보기",
"released": "발매" "released": "발매"
}, },
"albumList": { "albumList": {
"artistAlbums": "{{artist}}의 앨범", "artistAlbums": "{{artist}}의 앨범"
"genreAlbums": "\"{{genre}}\" $t(entity.album, {\"count\": 2})",
"title": "$t(entity.album, {\"count\": 2})"
}, },
"genreList": { "genreList": {
"showAlbums": "$t(entity.genre, {\"count\": 1}) $t(entity.album, {\"count\": 2}) 표시", "showAlbums": "$t(entity.genre_one) $t(entity.album_other) 표시",
"showTracks": "$t(entity.genre, {\"count\": 1}) $t(entity.track, {\"count\": 2}) 표시", "showTracks": "$t(entity.genre_one) $t(entity.track_other) 표시"
"title": "$t(entity.genre, {\"count\": 2})"
}, },
"globalSearch": { "globalSearch": {
"commands": { "commands": {
@@ -518,9 +405,7 @@
"mostPlayed": "자주 플레이된 곡", "mostPlayed": "자주 플레이된 곡",
"newlyAdded": "최근에 추가된 곡", "newlyAdded": "최근에 추가된 곡",
"recentlyPlayed": "최근에 플레이된 곡", "recentlyPlayed": "최근에 플레이된 곡",
"recentlyReleased": "최근에 발매된 곡", "recentlyReleased": "최근에 발매된 곡"
"genres": "$t(entity.genre, {\"count\": 2})",
"title": "$t(common.home)"
}, },
"itemDetail": { "itemDetail": {
"copyPath": "클립보드에 경로를 복사", "copyPath": "클립보드에 경로를 복사",
@@ -535,71 +420,15 @@
"generalTab": "일반", "generalTab": "일반",
"hotkeysTab": "단축키", "hotkeysTab": "단축키",
"playbackTab": "재생", "playbackTab": "재생",
"windowTab": "윈도우", "windowTab": "윈도우"
"analytics": "해석학",
"updates": "업데이트",
"cache": "은닉처",
"application": "애플리케이션",
"queryBuilder": "쿼리 빌더",
"theme": "테마",
"controls": "통제 수단",
"sidebar": "사이드바",
"exportImport": "가져오기/내보내기",
"audio": "오디오",
"lyrics": "가사",
"lyricsDisplay": "가사 표시",
"transcoding": "트랜스코딩",
"discord": "Discord",
"logger": "로거",
"playerFilters": "선수 필터"
}, },
"sidebar": { "sidebar": {
"myLibrary": "내 라이브러리", "myLibrary": "내 라이브러리",
"nowPlaying": "재생중", "nowPlaying": "재생중",
"shared": "공유 $t(entity.playlist, {\"count\": 2})", "shared": "공유 $t(entity.playlist_other)"
"albumArtists": "$t(entity.albumArtist, {\"count\": 2})",
"albums": "$t(entity.album, {\"count\": 2})",
"collections": "컬렉션",
"artists": "$t(entity.artist, {\"count\": 2})",
"favorites": "$t(entity.favorite, {\"count\": 2})",
"folders": "$t(entity.folder, {\"count\": 2})",
"genres": "$t(entity.genre, {\"count\": 2})",
"home": "$t(common.home)",
"radio": "$t(entity.radioStation, {\"count\": 2})",
"playlists": "$t(entity.playlist, {\"count\": 2})",
"search": "$t(common.search)",
"settings": "$t(common.setting, {\"count\": 2})",
"tracks": "$t(entity.track, {\"count\": 2})"
}, },
"trackList": { "trackList": {
"artistTracks": "{{artist}}의 음악", "artistTracks": "{{artist}}의 음악"
"genreTracks": "\"{{genre}}\" $t(entity.track, {\"count\": 2})",
"title": "$t(entity.track, {\"count\": 2})"
},
"radioList": {
"title": "라디오 방송국"
},
"releasenotes": {
"commitsSinceStable": "{{stable}} 이후 커밋",
"noNewCommits": "이 범위에 새로운 커밋이 없습니다",
"noStableReleaseToCompare": "비교할 수 있는 안정화 릴리스가 없습니다"
},
"favorites": {
"title": "$t(entity.favorite, {\"count\": 2})"
},
"windowBar": {
"paused": "(일시 정지됨) ",
"privateMode": "(비공개 모드)"
},
"folderList": {
"title": "$t(entity.folder, {\"count\": 2})"
},
"playlistList": {
"title": "$t(entity.playlist, {\"count\": 2})"
},
"collections": {
"overrideExisting": "기존 항목 덮어쓰기",
"saveAsCollection": "컬렉션으로 저장"
} }
}, },
"table": { "table": {
@@ -629,8 +458,8 @@
"playSimilarSongs": "비슷한 곡 재생", "playSimilarSongs": "비슷한 곡 재생",
"previous": "이전", "previous": "이전",
"queue_clear": "재생 대기열 지우기", "queue_clear": "재생 대기열 지우기",
"queue_moveToBottom": "선택한 곡을 가장 아래로 이동", "queue_moveToBottom": "선택한 곡을 가장 로 이동",
"queue_moveToTop": "선택한 곡을 가장 로 이동", "queue_moveToTop": "선택한 곡을 가장 아래로 이동",
"queue_remove": "선택한 항목 삭제", "queue_remove": "선택한 항목 삭제",
"repeat": "반복", "repeat": "반복",
"repeat_all": "모두 반복하기", "repeat_all": "모두 반복하기",
@@ -644,25 +473,7 @@
"toggleFullscreenPlayer": "전체화면으로 전환", "toggleFullscreenPlayer": "전체화면으로 전환",
"unfavorite": "즐겨찾기 취소", "unfavorite": "즐겨찾기 취소",
"pause": "멈춤", "pause": "멈춤",
"viewQueue": "대기열 보기", "viewQueue": "대기열 보기"
"addLastShuffled": "마지막 (섞인)",
"addNextShuffled": "다음 (무작위)",
"albumRadio": "앨범 라디오",
"artistRadio": "아티스트 라디오",
"holdToShuffle": "길게 눌러 섞기",
"lyrics": "가사",
"restoreQueueFromServer": "서버에서 큐 복원",
"saveQueueToServer": "대기열을 서버에 저장",
"trackRadio": "라디오 추적",
"sleepTimer": "취침 타이머",
"sleepTimer_endOfSong": "현재 곡 종료",
"sleepTimer_endOfAlbum": "현재 앨범의 끝",
"sleepTimer_minutes": "{{count}}분",
"sleepTimer_hours": "{{count}}시간",
"sleepTimer_off": "끄다",
"sleepTimer_timeRemaining": "{{time}} 남음",
"sleepTimer_setCustom": "타이머 설정",
"sleepTimer_cancel": "타이머 취소"
}, },
"setting": { "setting": {
"accentColor_description": "앱의 강조색상 설정", "accentColor_description": "앱의 강조색상 설정",
@@ -671,7 +482,7 @@
"albumBackground": "앨범 배경이미지", "albumBackground": "앨범 배경이미지",
"albumBackgroundBlur_description": "앨범 배경이미지의 흐려짐 정도 조정", "albumBackgroundBlur_description": "앨범 배경이미지의 흐려짐 정도 조정",
"albumBackgroundBlur": "앨범배경이미지 흐려짐 크기", "albumBackgroundBlur": "앨범배경이미지 흐려짐 크기",
"applicationHotkeys_description": "애플리케이션 단축키 설정합니다. 체크박스를 전환하여 전역 단축키 설정하세요(데스크톱 전용)", "applicationHotkeys_description": "앱의 단축키 설정. 앱 전체에 적용되는 단축키 설정하기 위해서는 체크박스에 체크하세요(PC만 가능)",
"applicationHotkeys": "앱 단축키", "applicationHotkeys": "앱 단축키",
"artistBackground": "아티스트 배경이미지", "artistBackground": "아티스트 배경이미지",
"artistBackground_description": "아티스트 페이지에 아티스트가 포함된 배경이미지를 추가", "artistBackground_description": "아티스트 페이지에 아티스트가 포함된 배경이미지를 추가",
@@ -681,7 +492,7 @@
"artistConfiguration_description": "앨범아티스트 페이지에 표시할 정보 및 순서 설정", "artistConfiguration_description": "앨범아티스트 페이지에 표시할 정보 및 순서 설정",
"audioDevice_description": "음악재생에 사용할 장치 선택(웹플레이어만 가능)", "audioDevice_description": "음악재생에 사용할 장치 선택(웹플레이어만 가능)",
"audioDevice": "오디오 장치", "audioDevice": "오디오 장치",
"audioExclusiveMode_description": "독점 출력 모드를 활성화합니다. 이 모드에서는 일반적으로 시스템의 오디오 출력이 차단되며, 오직 mpv만이 오디오를 출력할 수 있습니다. 이 모드가 활성화된 동안에는 비주얼라이저의 시스템 오디오 캡처 기능이 작동하지 않습니다", "audioExclusiveMode_description": "단독재생모드 켜기. 이 모드에서는 일반적으로 시스템의 재생장치가 고정되며 MPV로만 오디오가 재생됩니다",
"audioExclusiveMode": "오디오 단독재생모드", "audioExclusiveMode": "오디오 단독재생모드",
"audioPlayer_description": "재생을 위한 오디오 플레이어 선택", "audioPlayer_description": "재생을 위한 오디오 플레이어 선택",
"audioPlayer": "오디오 플레이어", "audioPlayer": "오디오 플레이어",
@@ -694,8 +505,7 @@
"broadcast": "방송", "broadcast": "방송",
"ep": "ep앨범", "ep": "ep앨범",
"other": "기타", "other": "기타",
"single": "싱글", "single": "싱글"
"album": "$t(entity.album, {\"count\": 1})"
}, },
"secondary": { "secondary": {
"audiobook": "오디오북", "audiobook": "오디오북",
@@ -711,35 +521,5 @@
"soundtrack": "사운드트랙", "soundtrack": "사운드트랙",
"spokenWord": "보컬사운드" "spokenWord": "보컬사운드"
} }
},
"datetime": {
"minuteShort": "분",
"secondShort": "초",
"hourShort": "시간",
"dayShort": "일"
},
"filterOperator": {
"after": "~ 뒤에 있나요",
"afterDate": "(날짜) 이후입니까",
"before": "~보다 앞서 있다",
"beforeDate": "(날짜) 이전인가요",
"contains": "포함",
"endsWith": "~로 끝남",
"inPlaylist": "~ 안에 있다",
"inTheLast": "마지막에 있습니다",
"inTheRange": "범위 내에 있습니다",
"inTheRangeDate": "범위 내에 있음 (날짜)",
"is": "~이다",
"isNot": "~이 아닙니까",
"isGreaterThan": "~보다 크다",
"isLessThan": "~보다 작다",
"matchesRegex": "정규식과 일치",
"notContains": "함유하지 않음",
"notInPlaylist": "~ 안에 있지 않다",
"notInTheLast": "마지막에 있지 않다",
"startsWith": "~로 시작함"
},
"queryBuilder": {
"customTags": "사용자 정의 태그"
} }
} }
File diff suppressed because it is too large Load Diff
+457 -1213
View File
File diff suppressed because it is too large Load Diff
-235
View File
@@ -1,235 +0,0 @@
{
"action": {
"addToFavorites": "Legg til i $t(entity.favorite, {\"count\": 2})",
"addToPlaylist": "Legg til i $t(entity.playlist, {\"count\": 1})",
"addOrRemoveFromSelection": "Legg til eller fjern fra val",
"selectRangeOfItems": "Vel eit utval av element",
"clearQueue": "Tøm kø",
"goToCurrent": "Gå til noverande element",
"collapseAllFolders": "Lukk alle mapper",
"expandAllFolders": "Opne alle mapper",
"createPlaylist": "Lag $t(entity.playlist, {\"count\": 1})",
"createRadioStation": "Lag $t(entity.radioStation, {\"count\": 1})",
"deletePlaylist": "Slett $t(entity.playlist, {\"count\": 1})",
"deleteRadioStation": "Slett $t(entity.radioStation, {\"count\": 1})",
"selectAll": "Vel alle",
"deselectAll": "Opphev alle val",
"downloadStarted": "Starta nedlasting av {{count}} element",
"editPlaylist": "Rediger $t(entity.playlist, {\"count\": 1})",
"goToPage": "Gå til side",
"moveToNext": "Flytt til neste",
"moveToBottom": "Flytt til botnen",
"moveToTop": "Flytt til toppen",
"moveUp": "Flytt opp",
"moveDown": "Flytt ned",
"holdToMoveToTop": "Held inne for å flytte til toppen",
"holdToMoveToBottom": "Held inne for å flytte til botnen",
"moveItems": "Flytt element",
"shuffle": "Stokking",
"shuffleAll": "Stokk alle",
"shuffleSelected": "Stokk valde",
"refresh": "$t(common.refresh)",
"removeFromFavorites": "Fjern frå $t(entity.favorite, {\"count\": 2})",
"removeFromPlaylist": "Fjern frå $t(entity.playlist, {\"count\": 1})",
"removeFromQueue": "Fjern frå kø",
"setRating": "Set vurdering",
"toggleSmartPlaylistEditor": "Slå $t(entity.smartPlaylist) editor av/på",
"viewPlaylists": "Vis $t(entity.playlist, {\"count\": 2})",
"viewMore": "Vis fleire",
"openApplicationDirectory": "Opne applikasjonsmappa",
"openIn": {
"lastfm": "Opne i Last.fm",
"listenbrainz": "Opne i ListenBrainz",
"musicbrainz": "Opne i MusicBrainz",
"qobuz": "Opne i Qobuz",
"spotify": "Opne i Spotify"
}
},
"common": {
"countSelected": "{{count}} valt",
"explicitStatus": "Eksplisittstatus",
"action_one": "Handling",
"action_other": "Handlingar",
"add": "Legg til",
"additionalParticipants": "Ytterlegare deltakarar",
"newVersion": "Ein ny versjon vart installert ({{version}})",
"viewReleaseNotes": "Sjå utgivelsesnotata",
"albumGain": "Albumforsterkning",
"albumPeak": "Albumtopp",
"areYouSure": "Er du sikker?",
"ascending": "Stigande",
"back": "Tilbake",
"backward": "Bakover",
"biography": "Biografi",
"bitDepth": "Bit-dybde",
"bitrate": "Bitrate",
"bpm": "BPM",
"cancel": "Avbryt",
"center": "Sentrer",
"channel_one": "Kanal",
"channel_other": "Kanalar",
"clear": "Tøm",
"close": "Lukk",
"codec": "Codec",
"collapse": "Lukk",
"comingSoon": "Kjem snart…",
"configure": "Konfigurer",
"confirm": "Bekreft",
"create": "Lag",
"currentSong": "Noverande $t(entity.track, {\"count\": 1})",
"decrease": "Reduser",
"delete": "Slett",
"descending": "Søkkande",
"description": "Beskriving",
"disable": "Skru av",
"disc": "Disk",
"dismiss": "Avvis",
"doNotShowAgain": "Ikkje vis dette igjen",
"duration": "Varigheit",
"view": "Vis",
"edit": "Rediger",
"enable": "Skru på",
"expand": "Utvid",
"example": "Døme",
"externalLinks": "Eksterne lenker",
"openFolder": "Open mappe",
"faster": "Raskare",
"favorite": "Favoriser",
"filter_one": "Filter",
"filter_other": "Filter",
"filters": "Filter",
"filter_single": "Single",
"filter_multiple": "Multi",
"forceRestartRequired": "Start på nytt for at endringane vert teke i bruk… lukk varslina for å starte på nytt",
"forward": "Framover",
"gap": "Mellomrom",
"home": "Heim",
"increase": "Auk",
"left": "Venstre",
"limit": "Grense",
"manage": "Administrer",
"maximize": "Maksimer",
"menu": "Meny",
"minimize": "Minimer",
"modified": "Modifisert",
"mbid": "MusicBrainz ID",
"grouping": "Gruppering",
"mood": "Humør",
"name": "Namn",
"no": "Nei",
"none": "Ingen",
"noResultsFromQuery": "Søket gav ingen resultat",
"numberOfResults": "{{numberOfResults}} resultat",
"noFilters": "Ingen filter konfigurert",
"note": "Notat",
"ok": "Ok",
"owner": "Eigar",
"path": "Bane",
"playerMustBePaused": "Spelaren må vere på pause",
"preview": "Førehandsvisning",
"previousSong": "Forrige $t(entity.track, {\"count\": 1})",
"private": "Privat",
"public": "Offentleg",
"quit": "Lukk",
"random": "Tilfeldig",
"rating": "Vurdering",
"retry": "Prøv på nytt",
"recordLabel": "Plateselskap",
"releaseType": "Utgjevingstype",
"refresh": "Oppdater",
"reload": "Oppdater",
"rename": "Gje nytt namn",
"reset": "Tilbakestill",
"resetToDefault": "Tilbakestill til standard",
"restartRequired": "Omstart nødvendig",
"right": "Høgre",
"sampleRate": "Samplingsfrekvens",
"save": "Lagre",
"saveAndReplace": "Lagre og erstatt",
"saveAs": "Lagre som",
"search": "Søk",
"setting_one": "Instilling",
"setting_other": "Instillingar",
"slower": "Saktare",
"share": "Del",
"size": "Storleik",
"sort": "Sorter",
"sortOrder": "Rekkjefølgje",
"tags": "Taggar",
"title": "Tittel",
"trackNumber": "Spor",
"trackGain": "Sporforsterkning",
"trackPeak": "Sporetopp",
"translation": "Omsetjing",
"unknown": "Ukjend",
"version": "Versjon",
"year": "År",
"yes": "Ja",
"explicit": "Eksplisitt",
"clean": "Rein",
"gridRows": "Rutenettrader",
"tableColumns": "Tabellkolonnar",
"itemsMore": "{{count}} fleire",
"newVersionAvailable": "Ein ny versjon er tilgjengeleg"
},
"entity": {
"album_one": "Album",
"album_other": "Album",
"albumArtist_one": "Albumartist",
"albumArtist_other": "Albumartistar",
"albumArtistCount_one": "{{count}} albumartist",
"albumArtistCount_other": "{{count}} albumartistar",
"albumWithCount_one": "{{count}} album",
"albumWithCount_other": "{{count}} album",
"radioStation_one": "Radiostasjon",
"radioStation_other": "Radiostasjonar",
"radioStationWithCount_one": "{{count}} radiostasjon",
"radioStationWithCount_other": "{{count}} radiostasjonar",
"artist_one": "Artist",
"artist_other": "Artistar",
"artistWithCount_one": "{{count}} artist",
"artistWithCount_other": "{{count}} artistar",
"favorite_one": "Favoritt",
"favorite_other": "Favorittar",
"folder_one": "Mappe",
"folder_other": "Mapper",
"folderWithCount_one": "{{count}} mappe",
"folderWithCount_other": "{{count}} mapper",
"genre_one": "Sjanger",
"genre_other": "Sjangrar",
"genreWithCount_one": "{{count}} sjanger",
"genreWithCount_other": "{{count}} sjangrar",
"playlist_one": "Speleliste",
"playlist_other": "Spelelister",
"play_one": "{{count}} avspeling",
"play_other": "{{count}} avspelingar",
"playlistWithCount_one": "{{count}} speleliste",
"playlistWithCount_other": "{{count}} spelelister",
"smartPlaylist": "Smart $t(entity.playlist, {\"count\": 1})",
"track_one": "Spor",
"track_other": "Spor",
"song_one": "Song",
"song_other": "Songar",
"trackWithCount_one": "{{count}} spor",
"trackWithCount_other": "{{count}} spor"
},
"error": {
"apiRouteError": "Kunne ikkje rute førespurnaden",
"audioDeviceFetchError": "Det oppstod ein feil under forsøk på å hente lydeiningar",
"authenticationFailed": "Autentisering feila",
"badAlbum": "Du ser denne sida fordi denne songen ikkje er ein del av eit album. Mest sannsynleg ser du dette fordi du har songen på toppen av musikkmappa di. Jellyfin grupperar berre spor viss dei er i ei mappe",
"badValue": "Ugyldig val \"{{value}}\". Denne verdien finst ikkje lenger",
"credentialsRequired": "Legitimasjon krevjast",
"endpointNotImplementedError": "Endepunktet {{endpoint}} er ikkje implementert for {{serverType}}",
"genericError": "Ein feil skjedde",
"invalidJson": "Ugyldig JSON",
"invalidServer": "Ugyldig sørvar",
"localFontAccessDenied": "Ingen tilgang til lokale skrifttypar",
"loginRateError": "For mange innloggingsforsøk, venlegast prøv på nytt om nokon sekundar",
"mpvRequired": "MPV nødvendig",
"multipleServerSaveQueueError": "Spelekøen har ein eller fleire songar som ikkje er frå den noverande sørvaren. Dette er ikkje støtta",
"networkError": "Ein nettverksfeil skjedde",
"noNetwork": "Sørvar utilgjengeleg",
"noNetworkDescription": "Kunne ikkje kople til denne sørvaren"
}
}
+922 -1080
View File
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+395 -728
View File
File diff suppressed because it is too large Load Diff
+13 -13
View File
@@ -1,19 +1,19 @@
{ {
"common": { "common": {
"confirm": "Confirmă", "confirm": "confirmă",
"create": "Creează", "create": "creează",
"biography": "Biografie", "biography": "biografie",
"areYouSure": "Ești sigur?", "areYouSure": "ești sigur?",
"no": "Nu", "no": "nu",
"name": "Nume", "name": "nume",
"ok": "Ok", "ok": "ok",
"note": "Notă", "note": "notă",
"yes": "Da", "yes": "da",
"explicit": "Explicit", "explicit": "explicit",
"year": "An", "year": "an",
"menu": "Meniu" "menu": "meniu"
}, },
"filter": { "filter": {
"biography": "Biografie" "biography": "biografie"
} }
} }
+575 -1112
View File
File diff suppressed because it is too large Load Diff
+617 -619
View File
File diff suppressed because it is too large Load Diff
+464 -466
View File
File diff suppressed because it is too large Load Diff
+463 -464
View File
File diff suppressed because it is too large Load Diff
+354 -355
View File
@@ -1,323 +1,322 @@
{ {
"action": { "action": {
"editPlaylist": "Redigera $t(entity.playlist, {\"count\": 1})", "editPlaylist": "redigera $t(entity.playlist_one)",
"goToPage": "Gå till sida", "goToPage": "gå till sida",
"moveToTop": "Flytta till toppen", "moveToTop": "flytta till toppen",
"clearQueue": "Rensa kö", "clearQueue": "rensa kö",
"addToFavorites": "Lägg till $t(entity.favorite, {\"count\": 2})", "addToFavorites": "lägg till $t(entity.favorite_other)",
"addToPlaylist": "Lägg till $t(entity.playlist, {\"count\": 1})", "addToPlaylist": "lägg till $t(entity.playlist_one)",
"createPlaylist": "Skapa $t(entity.playlist, {\"count\": 1})", "createPlaylist": "skapa $t(entity.playlist_one)",
"removeFromPlaylist": "Ta bort från $t(entity.playlist, {\"count\": 1})", "removeFromPlaylist": "ta bort från $t(entity.playlist_one)",
"viewPlaylists": "Visa $t(entity.playlist, {\"count\": 2})", "viewPlaylists": "visa $t(entity.playlist_other)",
"refresh": "$t(common.refresh)", "refresh": "$t(common.refresh)",
"deletePlaylist": "Ta bort $t(entity.playlist, {\"count\": 1})", "deletePlaylist": "ta bort $t(entity.playlist_one)",
"removeFromQueue": "Ta bort från kö", "removeFromQueue": "ta bort från kö",
"deselectAll": "Avmarkera alla", "deselectAll": "avmarkera alla",
"moveToBottom": "Flytta till botten", "moveToBottom": "flytta till botten",
"setRating": "Sätt betyg", "setRating": "sätt betyg",
"toggleSmartPlaylistEditor": "Växla $t(entity.smartPlaylist) redigerare", "toggleSmartPlaylistEditor": "växla $t(entity.smartPlaylist) redigerare",
"removeFromFavorites": "Ta bort från $t(entity.favorite, {\"count\": 2})", "removeFromFavorites": "ta bort från $t(entity.favorite_other)",
"downloadStarted": "Startade nedladdning av {{count}} objekt", "downloadStarted": "startade nedladdning av {{count}} objekt",
"moveToNext": "Flytta till nästa", "moveToNext": "flytta till nästa",
"moveUp": "Flytta upp", "moveUp": "flytta upp",
"moveDown": "Flytta ner", "moveDown": "flytta ner",
"holdToMoveToTop": "Håll för att flytta till toppen", "holdToMoveToTop": "håll för att flytta till toppen",
"holdToMoveToBottom": "Håll för att flytta till botten", "holdToMoveToBottom": "håll för att flytta till botten",
"moveItems": "Flytta objekt", "moveItems": "flytta objekt",
"shuffle": "Slumpa", "shuffle": "slumpa",
"shuffleAll": "Slumpa alla", "shuffleAll": "slumpa alla",
"shuffleSelected": "Slumpa valda", "shuffleSelected": "slumpa valda",
"viewMore": "Visa mer", "viewMore": "visa mer",
"openIn": { "openIn": {
"lastfm": "Öppna i Last.fm", "lastfm": "Öppna i Last.fm",
"musicbrainz": "Öppna i MusicBrainz" "musicbrainz": "Öppna i MusicBrainz"
}, },
"createRadioStation": "Skapa $t(entity.radioStation, {\"count\": 1})", "createRadioStation": "skapa $t(entity.radioStation_one)",
"deleteRadioStation": "Ta bort $t(entity.radioStation, {\"count\": 1})", "deleteRadioStation": "ta bort $t(entity.radioStation_one)",
"addOrRemoveFromSelection": "Lägg till eller ta bort från markerade", "addOrRemoveFromSelection": "lägg till eller ta bort från markerade",
"selectRangeOfItems": "Välj en mängd objekt", "selectRangeOfItems": "välj en mängd objekt",
"selectAll": "Markera alla", "selectAll": "markera alla",
"openApplicationDirectory": "Öppna applikationskatalog" "openApplicationDirectory": "öppna applikationskatalog"
}, },
"common": { "common": {
"backward": "Bakåt", "backward": "bakåt",
"increase": "Öka", "increase": "öka",
"rating": "Betyg", "rating": "betyg",
"bpm": "Bpm", "bpm": "bpm",
"refresh": "Laddaom", "refresh": "laddaom",
"unknown": "Okänd", "unknown": "okänd",
"areYouSure": "Är du säker?", "areYouSure": "är du säker?",
"edit": "Redigera", "edit": "redigera",
"favorite": "Favorit", "favorite": "favorit",
"left": "Vänster", "left": "vänster",
"save": "Spara", "save": "spara",
"right": "Höger", "right": "höger",
"currentSong": "Aktuell $t(entity.track, {\"count\": 1})", "currentSong": "aktuell $t(entity.track_one)",
"collapse": "Kollaps", "collapse": "kollaps",
"trackNumber": "Spår", "trackNumber": "spår",
"descending": "Fallande", "descending": "fallande",
"add": "Lägg till", "add": "lägg till",
"gap": "Avstånd", "gap": "avstånd",
"ascending": "Stigande", "ascending": "stigande",
"dismiss": "Avskeda", "dismiss": "avskeda",
"year": "År", "year": "år",
"manage": "Hantera", "manage": "hantera",
"limit": "Gräns", "limit": "gräns",
"minimize": "Minimera", "minimize": "minimera",
"modified": "Modifierad", "modified": "modifierad",
"duration": "Längd", "duration": "längd",
"name": "Namn", "name": "namn",
"maximize": "Maximera", "maximize": "maximera",
"decrease": "Minska", "decrease": "minska",
"ok": "Ok", "ok": "ok",
"description": "Beskrivning", "description": "beskrivning",
"configure": "Konfigurera", "configure": "konfigurera",
"path": "Sökväg", "path": "sökväg",
"no": "Nej", "no": "nej",
"owner": "Ägare", "owner": "ägare",
"enable": "Aktivera", "enable": "aktivera",
"clear": "Töm", "clear": "töm",
"forward": "Framåt", "forward": "framåt",
"delete": "Ta bort", "delete": "ta bort",
"cancel": "Avbryt", "cancel": "avbryt",
"forceRestartRequired": "Starta om för att tillämpa ändringar... Stäng meddelandet för att starta om", "forceRestartRequired": "starta om för att tillämpa ändringar... Stäng meddelandet för att starta om",
"setting_one": "Inställning", "setting": "inställning",
"setting_other": "", "version": "version",
"version": "Version", "title": "titel",
"title": "Titel", "filter_one": "filter",
"filter_one": "Filter", "filter_other": "filter",
"filter_other": "Filter", "filters": "filter",
"filters": "Filter", "create": "skapa",
"create": "Skapa", "bitrate": "bithastighet",
"bitrate": "Bithastighet", "saveAndReplace": "spara och skrivöver",
"saveAndReplace": "Spara och skrivöver", "action_one": "handling",
"action_one": "Handling", "action_other": "handlingar",
"action_other": "Handlingar", "playerMustBePaused": "spelaren måste pausas",
"playerMustBePaused": "Spelaren måste pausas", "confirm": "bekräfta",
"confirm": "Bekräfta", "resetToDefault": "återställ till standard",
"resetToDefault": "Återställ till standard", "home": "hem",
"home": "Hem", "comingSoon": "kommer snart…",
"comingSoon": "Kommer snart…", "reset": "nollställ",
"reset": "Nollställ", "channel_one": "kanal",
"channel_one": "Kanal", "channel_other": "kanaler",
"channel_other": "Kanaler", "disable": "inaktivera",
"disable": "Inaktivera", "sortOrder": "ordning",
"sortOrder": "Ordning", "none": "ingen",
"none": "Ingen", "menu": "meny",
"menu": "Meny", "restartRequired": "omstart krävs",
"restartRequired": "Omstart krävs", "previousSong": "föregående $t(entity.track_one)",
"previousSong": "Föregående $t(entity.track, {\"count\": 1})", "noResultsFromQuery": "frågan returnerade inga resultat",
"noResultsFromQuery": "Frågan returnerade inga resultat", "quit": "avsluta",
"quit": "Avsluta", "expand": "expandera",
"expand": "Expandera", "search": "sök",
"search": "Sök", "saveAs": "spara som",
"saveAs": "Spara som", "disc": "skiva",
"disc": "Skiva", "yes": "ja",
"yes": "Ja", "random": "slumpmässig",
"random": "Slumpmässig", "size": "storlek",
"size": "Storlek", "biography": "biografi",
"biography": "Biografi", "note": "anteckning",
"note": "Anteckning", "center": "center",
"center": "Center", "explicitStatus": "olämplig status",
"explicitStatus": "Olämplig status", "additionalParticipants": "ytterligare medverkare",
"additionalParticipants": "Ytterligare medverkare", "newVersion": "en ny version har installerats {{version}}",
"newVersion": "En ny version har installerats {{version}}", "viewReleaseNotes": "se utgåveinformation",
"viewReleaseNotes": "Se utgåveinformation", "bitDepth": "bitdjup",
"bitDepth": "Bitdjup", "close": "stäng",
"close": "Stäng", "codec": "kodek",
"codec": "Kodek", "doNotShowAgain": "visa inte detta igen",
"doNotShowAgain": "Visa inte detta igen", "view": "visa",
"view": "Visa", "externalLinks": "externa länkar",
"externalLinks": "Externa länkar", "faster": "snabbare",
"faster": "Snabbare",
"mbid": "MusicBrainz ID", "mbid": "MusicBrainz ID",
"noFilters": "Inga filter konfigurerade", "noFilters": "inga filter konfigurerade",
"preview": "Förhandsvisa", "preview": "förhandsvisa",
"private": "Privat", "private": "privat",
"public": "Allmän", "public": "allmän",
"recordLabel": "Skivbolag", "recordLabel": "skivbolag",
"releaseType": "Utgåvetyp", "releaseType": "utgåvetyp",
"reload": "Ladda om", "reload": "ladda om",
"sampleRate": "Samplingstakt", "sampleRate": "samplingstakt",
"slower": "Långsammare", "slower": "långsammare",
"share": "Dela", "share": "dela",
"sort": "Sortera", "sort": "sortera",
"tags": "Taggar", "tags": "taggar",
"translation": "Översättning", "translation": "översättning",
"explicit": "Olämplig", "explicit": "olämplig",
"clean": "Städad", "clean": "städad",
"gridRows": "Rutnätsrader", "gridRows": "rutnätsrader",
"tableColumns": "Tabellkolumner", "tableColumns": "tabellkolumner",
"itemsMore": "{{count}} fler", "itemsMore": "{{count}} fler",
"countSelected": "{{count}} markerade" "countSelected": "{{count}} markerade"
}, },
"error": { "error": {
"remotePortWarning": "Starta om servern för att tillämpa den nya porten", "remotePortWarning": "starta om servern för att tillämpa den nya porten",
"systemFontError": "Ett fel uppstod vid försök att hämta systemteckensnitt", "systemFontError": "ett fel uppstod vid försök att hämta systemteckensnitt",
"playbackError": "Ett fel uppstod vid försök att spela upp media", "playbackError": "ett fel uppstod vid försök att spela upp media",
"endpointNotImplementedError": "Endpoint {{endpoint}} är inte implementerad för {{serverType}}", "endpointNotImplementedError": "endpoint {{endpoint}} är inte implementerad för {{serverType}}",
"remotePortError": "Ett fel uppstod vid försök att ange serverporten", "remotePortError": "ett fel uppstod vid försök att ange serverporten",
"serverRequired": "Server krävs", "serverRequired": "server krävs",
"authenticationFailed": "Autentiseringen misslyckades", "authenticationFailed": "autentiseringen misslyckades",
"apiRouteError": "Det går inte att dirigera begäran", "apiRouteError": "det går inte att dirigera begäran",
"genericError": "Ett fel uppstod", "genericError": "ett fel uppstod",
"credentialsRequired": "Autentiseringsuppgifter som krävs", "credentialsRequired": "autentiseringsuppgifter som krävs",
"sessionExpiredError": "Din session har löpt ut", "sessionExpiredError": "din session har löpt ut",
"remoteEnableError": "Ett fel uppstod vid försök att $t(common.enable) servern", "remoteEnableError": "Ett fel uppstod vid försök att $t(common.enable) servern",
"localFontAccessDenied": "Åtkomst nekad till lokala teckensnitt", "localFontAccessDenied": "åtkomst nekad till lokala teckensnitt",
"serverNotSelectedError": "Ingen server vald", "serverNotSelectedError": "ingen server vald",
"remoteDisableError": "Ett fel uppstod vid försök av $t(common.disable) servern", "remoteDisableError": "ett fel uppstod vid försök av $t(common.disable) servern",
"mpvRequired": "MPV krävs", "mpvRequired": "MPV krävs",
"audioDeviceFetchError": "Ett fel uppstod vid hämtning av ljudenheter", "audioDeviceFetchError": "ett fel uppstod vid hämtning av ljudenheter",
"invalidServer": "Ogiltig server", "invalidServer": "ogiltig server",
"loginRateError": "För många inloggningsförsök, försök igen om några sekunder", "loginRateError": "för många inloggningsförsök, försök igen om några sekunder",
"badAlbum": "Du ser denna sidan eftersom denna låten inte är en del av ett album. du ser troligtvis detta problemet för att du har en låt på toppnivån i din musikmapp. Jellyfin grupperar bara låtar om de finns i en mapp", "badAlbum": "du ser denna sidan eftersom denna låten inte är en del av ett album. du ser troligtvis detta problemet för att du har en låt på toppnivån i din musikmapp. Jellyfin grupperar bara låtar om de finns i en mapp",
"badValue": "Felaktigt alternativ \"{{value}}\". detta värde existerar inte längre", "badValue": "felaktigt alternativ \"{{value}}\". detta värde existerar inte längre",
"multipleServerSaveQueueError": "Spelningskön har en eller flera låtar som inte är från den nuvarande valda servern. detta är inte stöttat", "multipleServerSaveQueueError": "spelningskön har en eller flera låtar som inte är från den nuvarande valda servern. detta är inte stöttat",
"networkError": "En nätverksfel uppstod", "networkError": "en nätverksfel uppstod",
"notificationDenied": "Åtkomst till notifieringarna var nekad. inställningen har ingen verkan", "notificationDenied": "åtkomst till notifieringarna var nekad. inställningen har ingen verkan",
"openError": "Kunde inte öppna filen", "openError": "kunde inte öppna filen",
"settingsSyncError": "Diskrepans hittades mellan inställningarna för renderingsprocessen och huvudprocessen. starta om applikationen för att ändringarna ska tillämpas" "settingsSyncError": "diskrepans hittades mellan inställningarna för renderingsprocessen och huvudprocessen. starta om applikationen för att ändringarna ska tillämpas"
}, },
"filter": { "filter": {
"mostPlayed": "Mest spelade", "mostPlayed": "mest spelade",
"comment": "Kommentar", "comment": "kommentar",
"playCount": "Antal spelningar", "playCount": "antal spelningar",
"recentlyUpdated": "Nyligen uppdaterad", "recentlyUpdated": "nyligen uppdaterad",
"channels": "$t(common.channel_other)", "channels": "$t(common.channel_other)",
"isCompilation": "Är kompilering", "isCompilation": "är kompilering",
"recentlyPlayed": "Nyligen spelad", "recentlyPlayed": "nyligen spelad",
"isRated": "Är betygsatt", "isRated": "är betygsatt",
"owner": "$t(common.owner)", "owner": "$t(common.owner)",
"title": "Titel", "title": "titel",
"rating": "Betyg", "rating": "betyg",
"search": "Sök", "search": "sök",
"bitrate": "Bithastighet", "bitrate": "bithastighet",
"genre": "$t(entity.genre, {\"count\": 1})", "genre": "$t(entity.genre_one)",
"recentlyAdded": "Nyligen tillagda", "recentlyAdded": "nyligen tillagda",
"note": "Anteckning", "note": "anteckning",
"name": "Namn", "name": "namn",
"dateAdded": "Datum tillagt", "dateAdded": "datum tillagt",
"releaseDate": "Utgivningsdag", "releaseDate": "utgivningsdag",
"communityRating": "Betyg från communityn", "communityRating": "betyg från communityn",
"path": "Sökväg", "path": "sökväg",
"favorited": "Favoritmärkt", "favorited": "favoritmärkt",
"albumArtist": "$t(entity.albumArtist, {\"count\": 1})", "albumArtist": "$t(entity.albumArtist_one)",
"isRecentlyPlayed": "Spelas nyligen", "isRecentlyPlayed": "spelas nyligen",
"isFavorited": "Är favoritmärkt", "isFavorited": "är favoritmärkt",
"bpm": "Bpm", "bpm": "bpm",
"releaseYear": "Utgivningsår", "releaseYear": "utgivningsår",
"id": "Id", "id": "id",
"disc": "Skiva", "disc": "skiva",
"biography": "Biografi", "biography": "biografi",
"artist": "$t(entity.artist, {\"count\": 1})", "artist": "$t(entity.artist_one)",
"duration": "Längd", "duration": "längd",
"isPublic": "Är offentlig", "isPublic": "är offentlig",
"random": "Slumpmässig", "random": "slumpmässig",
"lastPlayed": "Senast spelad", "lastPlayed": "senast spelad",
"toYear": "Till år", "toYear": "till år",
"fromYear": "Från år", "fromYear": "från år",
"album": "$t(entity.album, {\"count\": 1})", "album": "$t(entity.album_one)",
"trackNumber": "Spår", "trackNumber": "spår",
"songCount": "Sångräkning", "songCount": "sångräkning",
"criticRating": "Kritikerbetyg", "criticRating": "kritikerbetyg",
"albumCount": "$t(entity.album, {\"count\": 2}) antal", "albumCount": "$t(entity.album_other) antal",
"explicitStatus": "$t(common.explicitStatus)" "explicitStatus": "$t(common.explicitStatus)"
}, },
"form": { "form": {
"deletePlaylist": { "deletePlaylist": {
"title": "Ta bort $t(entity.playlist, {\"count\": 1})", "title": "ta bort $t(entity.playlist_one)",
"success": "$t(entity.playlist, {\"count\": 1}) har tagits bort", "success": "$t(entity.playlist_one) har tagits bort",
"input_confirm": "Skriv namnet på $t(entity.playlist, {\"count\": 1}) för att bekräfta" "input_confirm": "Skriv namnet på $t(entity.playlist_one) för att bekräfta"
}, },
"createPlaylist": { "createPlaylist": {
"input_description": "$t(common.description)", "input_description": "$t(common.description)",
"title": "Skapa $t(entity.playlist, {\"count\": 1})", "title": "skapa $t(entity.playlist_one)",
"input_public": "Offentlig", "input_public": "offentlig",
"input_name": "$t(common.name)", "input_name": "$t(common.name)",
"success": "$t(entity.playlist, {\"count\": 1}) skapad", "success": "$t(entity.playlist_one) skapad",
"input_owner": "$t(common.owner)" "input_owner": "$t(common.owner)"
}, },
"addServer": { "addServer": {
"title": "Lägg till server", "title": "lägg till server",
"input_username": "Användarnamn", "input_username": "användarnamn",
"input_url": "Länk", "input_url": "länk",
"input_password": "Lösenord", "input_password": "lösenord",
"input_legacyAuthentication": "Aktivera äldre autentisering", "input_legacyAuthentication": "aktivera äldre autentisering",
"input_name": "Server namn", "input_name": "server namn",
"success": "Servern har lagts till", "success": "servern har lagts till",
"input_savePassword": "Spara lösenord", "input_savePassword": "spara lösenord",
"ignoreSsl": "Ignorera ssl ($t(common.restartRequired))", "ignoreSsl": "ignorera ssl ($t(common.restartRequired))",
"ignoreCors": "Ignorera cors ($t(common.restartRequired))", "ignoreCors": "ignorera cors ($t(common.restartRequired))",
"error_savePassword": "Ett fel uppstod när lösenordet skulle sparas", "error_savePassword": "ett fel uppstod när lösenordet skulle sparas",
"input_preferInstantMix": "Föredra instant mixning", "input_preferInstantMix": "föredra instant mixning",
"input_preferInstantMixDescription": "Använd bara instant mixning för att få liknande låtar. användbar om du har plugin för att förändra detta beteendet" "input_preferInstantMixDescription": "använd bara instant mixning för att få liknande låtar. användbar om du har plugin för att förändra detta beteendet"
}, },
"addToPlaylist": { "addToPlaylist": {
"success": "Lade till $t(entity.trackWithCount, {\"count\": {{message}} }) till $t(entity.playlistWithCount, {\"count\": {{numOfPlaylists}} })", "success": "lade till $t(entity.trackWithCount, {\"count\": {{message}} }) till $t(entity.playlistWithCount, {\"count\": {{numOfPlaylists}} })",
"title": "Lägg till i $t(entity.playlist, {\"count\": 1})", "title": "lägg till i $t(entity.playlist_one)",
"input_skipDuplicates": "Hoppa över dubbletter", "input_skipDuplicates": "hoppa över dubbletter",
"input_playlists": "$t(entity.playlist, {\"count\": 2})", "input_playlists": "$t(entity.playlist_other)",
"create": "Skapa $t(entity.playlist, {\"count\": 1}) {{playlist}}", "create": "skapa $t(entity.playlist_one) {{playlist}}",
"searchOrCreate": "Sök $t(entity.playlist, {\"count\": 2}) eller skriv för att skapa en ny" "searchOrCreate": "sök $t(entity.playlist_other) eller skriv för att skapa en ny"
}, },
"updateServer": { "updateServer": {
"title": "Uppdatera server", "title": "uppdatera server",
"success": "Servern har uppdaterats" "success": "servern har uppdaterats"
}, },
"queryEditor": { "queryEditor": {
"input_optionMatchAll": "Matcha alla", "input_optionMatchAll": "matcha alla",
"input_optionMatchAny": "Matcha något" "input_optionMatchAny": "matcha något"
}, },
"lyricSearch": { "lyricSearch": {
"input_name": "$t(common.name)", "input_name": "$t(common.name)",
"input_artist": "$t(entity.artist, {\"count\": 1})", "input_artist": "$t(entity.artist_one)",
"title": "Sångtext sök" "title": "sångtext sök"
}, },
"editPlaylist": { "editPlaylist": {
"title": "Redigera $t(entity.playlist, {\"count\": 1})", "title": "redigera $t(entity.playlist_one)",
"publicJellyfinNote": "Jellyfin visar av någon anledning inte om en spellista är publik eller inte. Om du önskar att denna ska förbli publik, så får du ha följande indata markerade" "publicJellyfinNote": "Jellyfin visar av någon anledning inte om en spellista är publik eller inte. Om du önskar att denna ska förbli publik, så får du ha följande indata markerade"
}, },
"largeFetchConfirmation": { "largeFetchConfirmation": {
"title": "Lägg till objekt till kön", "title": "lägg till objekt till kön",
"description": "Åtgärden kommer att lägga till alla objekt till den nuvarande filtrerade vyn" "description": "Åtgärden kommer att lägga till alla objekt till den nuvarande filtrerade vyn"
}, },
"createRadioStation": { "createRadioStation": {
"success": "Radiostation skapades", "success": "radiostation skapades",
"title": "Skapa radiostation", "title": "skapa radiostation",
"input_homepageUrl": "Hemside-URL", "input_homepageUrl": "hemside-URL",
"input_name": "Namn", "input_name": "namn",
"input_streamUrl": "Stream url" "input_streamUrl": "stream url"
} }
}, },
"page": { "page": {
"fullscreenPlayer": { "fullscreenPlayer": {
"config": { "config": {
"showLyricMatch": "Visa låttext matchning", "showLyricMatch": "Visa låttext matchning",
"dynamicBackground": "Dynamisk bakgrund", "dynamicBackground": "dynamisk bakgrund",
"followCurrentLyric": "Följ aktuell låttext", "followCurrentLyric": "följ aktuell låttext",
"opacity": "Ogenomskinlighet", "opacity": "ogenomskinlighet",
"lyricSize": "Låttext storlek", "lyricSize": "låttext storlek",
"lyricAlignment": "Låttext justering", "lyricAlignment": "låttext justering",
"lyricGap": "Låttext mellanrum", "lyricGap": "låttext mellanrum",
"synchronized": "Synkroniserad", "synchronized": "synkroniserad",
"showLyricProvider": "Visa sångtextleverantör", "showLyricProvider": "visa sångtextleverantör",
"unsynchronized": "Osynkroniserad" "unsynchronized": "osynkroniserad"
}, },
"lyrics": "Sångtext", "lyrics": "sångtext",
"related": "Relaterad" "related": "relaterad"
}, },
"appMenu": { "appMenu": {
"selectServer": "Välj server", "selectServer": "välj server",
"version": "Version {{version}}", "version": "version {{version}}",
"settings": "$t(common.setting, {\"count\": 2})", "settings": "$t(common.setting_other)",
"manageServers": "Hantera servrar", "manageServers": "hantera servrar",
"expandSidebar": "Expandera sidofältet", "expandSidebar": "expandera sidofältet",
"openBrowserDevtools": "Öppna webbläsarens utvecklingsverktyg", "openBrowserDevtools": "öppna webbläsarens utvecklingsverktyg",
"quit": "$t(common.quit)", "quit": "$t(common.quit)",
"goBack": "Gå tillbaka", "goBack": "gå tillbaka",
"goForward": "Gå framåt", "goForward": "gå framåt",
"collapseSidebar": "Växla sidofältet" "collapseSidebar": "växla sidofältet"
}, },
"contextMenu": { "contextMenu": {
"addToPlaylist": "$t(action.addToPlaylist)", "addToPlaylist": "$t(action.addToPlaylist)",
@@ -336,146 +335,146 @@
"play": "$t(player.play)", "play": "$t(player.play)",
"numberSelected": "{{count}} vald", "numberSelected": "{{count}} vald",
"removeFromQueue": "$t(action.removeFromQueue)", "removeFromQueue": "$t(action.removeFromQueue)",
"download": "Ladda ner", "download": "ladda ner",
"moveItems": "$t(action.moveItems)", "moveItems": "$t(action.moveItems)",
"moveToNext": "$t(action.moveToNext)", "moveToNext": "$t(action.moveToNext)",
"playSimilarSongs": "$t(player.playSimilarSongs)", "playSimilarSongs": "$t(player.playSimilarSongs)",
"playShuffled": "$t(player.shuffle)", "playShuffled": "$t(player.shuffle)",
"shareItem": "Dela objekt", "shareItem": "dela objekt",
"goTo": "Gå till", "goTo": "gå till",
"goToAlbum": "Gå till $t(entity.album, {\"count\": 1})", "goToAlbum": "gå till $t(entity.album_one)",
"goToAlbumArtist": "Gå till $t(entity.albumArtist, {\"count\": 1})", "goToAlbumArtist": "gå till $t(entity.albumArtist_one)",
"showDetails": "Hämta information" "showDetails": "hämta information"
}, },
"albumDetail": { "albumDetail": {
"moreFromArtist": "Mer från $t(entity.artist, {\"count\": 1})", "moreFromArtist": "mer från $t(entity.artist_one)",
"moreFromGeneric": "Mer från {{item}}" "moreFromGeneric": "mer från {{item}}"
}, },
"albumArtistList": { "albumArtistList": {
"title": "$t(entity.albumArtist, {\"count\": 2})" "title": "$t(entity.albumArtist_other)"
}, },
"albumList": { "albumList": {
"title": "$t(entity.album, {\"count\": 2})" "title": "$t(entity.album_other)"
}, },
"sidebar": { "sidebar": {
"nowPlaying": "Nu spelas" "nowPlaying": "nu spelas"
}, },
"home": { "home": {
"mostPlayed": "Mest spelade", "mostPlayed": "mest spelade",
"newlyAdded": "Nytillkomna utgåvor", "newlyAdded": "nytillkomna utgåvor",
"explore": "Utforska från ditt bibliotek", "explore": "utforska från ditt bibliotek",
"recentlyPlayed": "Nyligen spelat" "recentlyPlayed": "nyligen spelat"
}, },
"setting": { "setting": {
"playbackTab": "Uppspelning", "playbackTab": "uppspelning",
"generalTab": "Allmänt", "generalTab": "allmänt",
"hotkeysTab": "Snabbtangenter", "hotkeysTab": "snabbtangenter",
"windowTab": "Fönster" "windowTab": "fönster"
}, },
"globalSearch": { "globalSearch": {
"commands": { "commands": {
"serverCommands": "Serverkommandon", "serverCommands": "serverkommandon",
"goToPage": "Gå till sidan", "goToPage": "gå till sidan",
"searchFor": "Sök efter {{query}}" "searchFor": "sök efter {{query}}"
}, },
"title": "Kommandon" "title": "kommandon"
}, },
"manageServers": { "manageServers": {
"url": "URL", "url": "URL",
"username": "Användarnamn", "username": "användarnamn",
"editServerDetailsTooltip": "Redigera serverinställningar", "editServerDetailsTooltip": "redigera serverinställningar",
"removeServer": "Ta bort server" "removeServer": "ta bort server"
} }
}, },
"entity": { "entity": {
"playlist_one": "Spellista", "playlist_one": "spellista",
"playlist_other": "Spellistor", "playlist_other": "spellistor",
"artist_one": "Artist", "artist_one": "artist",
"artist_other": "Artister", "artist_other": "artister",
"albumArtist_one": "Albumartist", "albumArtist_one": "albumartist",
"albumArtist_other": "Albumartister", "albumArtist_other": "albumartister",
"albumArtistCount_one": "{{count}} albumartist", "albumArtistCount_one": "{{count}} Albumartist",
"albumArtistCount_other": "{{count}} albumartister", "albumArtistCount_other": "{{count}} Albumartister",
"albumWithCount_one": "{{count}} album", "albumWithCount_one": "{{count}} album",
"albumWithCount_other": "{{count}} album", "albumWithCount_other": "{{count}} album",
"favorite_one": "Favorit", "favorite_one": "favorit",
"favorite_other": "Favoriter", "favorite_other": "favoriter",
"folder_one": "Mapp", "folder_one": "mapp",
"folder_other": "Mappar", "folder_other": "mappar",
"album_one": "Album", "album_one": "album",
"album_other": "Album", "album_other": "album",
"playlistWithCount_one": "{{count}} spellista", "playlistWithCount_one": "{{count}} spellista",
"playlistWithCount_other": "{{count}} spellistor", "playlistWithCount_other": "{{count}} spellistor",
"folderWithCount_one": "{{count}} mapp", "folderWithCount_one": "{{count}} mapp",
"folderWithCount_other": "{{count}} mappar", "folderWithCount_other": "{{count}} mappar",
"track_one": "Spår", "track_one": "spår",
"track_other": "Spår", "track_other": "spår",
"trackWithCount_one": "{{count}} spår", "trackWithCount_one": "{{count}} spår",
"trackWithCount_other": "{{count}} spår", "trackWithCount_other": "{{count}} spår",
"artistWithCount_one": "{{count}} artist", "artistWithCount_one": "{{count}} artist",
"artistWithCount_other": "{{count}} artister", "artistWithCount_other": "{{count}} artister",
"genre_one": "Genre", "genre_one": "genre",
"genre_other": "Genrer", "genre_other": "genrer",
"genreWithCount_one": "{{count}} genre", "genreWithCount_one": "{{count}} genre",
"genreWithCount_other": "{{count}} genrer", "genreWithCount_other": "{{count}} genrer",
"play_one": "{{count}} spelning", "play_one": "{{count}} spelning",
"play_other": "{{count}} spelningar", "play_other": "{{count}} spelningar",
"smartPlaylist": "Smart $t(entity.playlist, {\"count\": 1})", "smartPlaylist": "smart $t(entity.playlist_one)",
"song_one": "Låt", "song_one": "låt",
"song_other": "Låtar", "song_other": "låtar",
"radioStation_one": "Radiostation", "radioStation_one": "radiostation",
"radioStation_other": "Radiostationer", "radioStation_other": "radiostationer",
"radioStationWithCount_one": "{{count}} radiostation", "radioStationWithCount_one": "{{count}} radiostation",
"radioStationWithCount_other": "{{count}} radiostationer" "radioStationWithCount_other": "{{count}} radiostationer"
}, },
"player": { "player": {
"repeat_all": "Repetera alla", "repeat_all": "repetera alla",
"repeat": "Repetera", "repeat": "repetera",
"queue_remove": "Ta bort markerad", "queue_remove": "ta bort markerad",
"playRandom": "Spela slumpmässigt", "playRandom": "spela slumpmässigt",
"previous": "Föregående", "previous": "föregående",
"favorite": "Favorit", "favorite": "favorit",
"next": "Nästa", "next": "nästa",
"shuffle": "Blanda", "shuffle": "blanda",
"playbackFetchNoResults": "Inga låtar hittades", "playbackFetchNoResults": "inga låtar hittades",
"playbackFetchInProgress": "Laddar låtar…", "playbackFetchInProgress": "laddar låtar…",
"addNext": "Lägg till nästa", "addNext": "lägg till nästa",
"playbackSpeed": "Uppspelningshastighet", "playbackSpeed": "uppspelningshastighet",
"playbackFetchCancel": "Det här tar ett tag... stäng aviseringen för att avbryta", "playbackFetchCancel": "det här tar ett tag... stäng aviseringen för att avbryta",
"play": "Spela", "play": "spela",
"repeat_off": "Repetera inaktiverad", "repeat_off": "repetera inaktiverad",
"queue_clear": "Rensa kö", "queue_clear": "rensa kö",
"muted": "Mutad", "muted": "mutad",
"queue_moveToTop": "Flytta markerad till toppen", "queue_moveToTop": "flytta markerad till botten",
"queue_moveToBottom": "Flytta markerad till botten", "queue_moveToBottom": "flytta markerad till toppen",
"addLast": "Lägg till sist", "addLast": "lägg till sist",
"mute": "Muta" "mute": "muta"
}, },
"datetime": { "datetime": {
"minuteShort": "Min", "minuteShort": "min",
"secondShort": "Sek", "secondShort": "sek",
"hourShort": "H", "hourShort": "h",
"dayShort": "Dag" "dayShort": "dag"
}, },
"filterOperator": { "filterOperator": {
"after": "Är efter", "after": "är efter",
"afterDate": "Är efter (datum)", "afterDate": "är efter (datum)",
"before": "Är före", "before": "är före",
"beforeDate": "Är före (datum)", "beforeDate": "är före (datum)",
"contains": "Innehåller", "contains": "innehåller",
"endsWith": "Slutar med", "endsWith": "slutar med",
"inPlaylist": "Är inom", "inPlaylist": "är inom",
"inTheLast": "Är i den sista", "inTheLast": "är i den sista",
"inTheRange": "Är i spannet", "inTheRange": "är i spannet",
"inTheRangeDate": "Är i spannet (datum)", "inTheRangeDate": "är i spannet (datum)",
"is": "Är", "is": "är",
"isNot": "Är inte", "isNot": "är inte",
"isGreaterThan": "Är större än", "isGreaterThan": "är större än",
"isLessThan": "Är mindre än", "isLessThan": "är mindre än",
"matchesRegex": "Matchar regex", "matchesRegex": "matchar regex",
"notContains": "Innehåller inte", "notContains": "innehåller inte",
"notInPlaylist": "Är inte inom", "notInPlaylist": "är inte inom",
"notInTheLast": "Är inte inom den sista", "notInTheLast": "är inte inom den sista",
"startsWith": "Startar med" "startsWith": "startar med"
} }
} }

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