Compare commits
23 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a137de612a | |||
| ae9a8e6d08 | |||
| 9c3053608d | |||
| d6ea97fa2a | |||
| 578b00fe3d | |||
| f43f696f54 | |||
| 4a81d7b249 | |||
| 88fbc22923 | |||
| daef3b31fe | |||
| 7142017c26 | |||
| f30a466fb2 | |||
| f2e3e7a74e | |||
| 83efd6e8c5 | |||
| 515496ab85 | |||
| 16b99ef597 | |||
| b607c57f59 | |||
| 9f0a8f2bae | |||
| 0e384a6302 | |||
| 0c7cec9f4f | |||
| f30a706eef | |||
| a980a8de0b | |||
| 9abda23a4a | |||
| 4e3a3742a5 |
@@ -5,7 +5,6 @@
|
||||
*.jpeg binary
|
||||
*.ico binary
|
||||
*.icns binary
|
||||
*.webp binary
|
||||
*.eot binary
|
||||
*.otf binary
|
||||
*.ttf binary
|
||||
|
||||
@@ -1,189 +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
|
||||
with:
|
||||
version: 10
|
||||
|
||||
- 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-latest, ubuntu-latest]
|
||||
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v6
|
||||
|
||||
- name: Install Node and PNPM
|
||||
uses: pnpm/action-setup@v4
|
||||
with:
|
||||
version: 10
|
||||
|
||||
- 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-latest'
|
||||
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
|
||||
@@ -15,12 +15,12 @@ jobs:
|
||||
version: ${{ steps.version.outputs.version }}
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Install Node and PNPM
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
with:
|
||||
version: 10
|
||||
version: 9
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
@@ -119,12 +119,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Install Node and PNPM
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
with:
|
||||
version: 10
|
||||
version: 9
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
@@ -146,7 +146,7 @@ jobs:
|
||||
if: matrix.os == 'windows-latest'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: nick-invision/retry@v3.0.2
|
||||
uses: nick-invision/retry@v2.8.2
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
@@ -159,7 +159,7 @@ jobs:
|
||||
if: matrix.os == 'macos-latest'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: nick-invision/retry@v3.0.2
|
||||
uses: nick-invision/retry@v2.8.2
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
@@ -172,7 +172,7 @@ jobs:
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: nick-invision/retry@v3.0.2
|
||||
uses: nick-invision/retry@v2.8.2
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
@@ -185,7 +185,7 @@ jobs:
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: nick-invision/retry@v3.0.2
|
||||
uses: nick-invision/retry@v2.8.2
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
@@ -199,7 +199,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Edit release with commits and title
|
||||
shell: pwsh
|
||||
@@ -346,7 +346,7 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Delete existing prereleases
|
||||
shell: pwsh
|
||||
|
||||
@@ -20,7 +20,7 @@ jobs:
|
||||
packages: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
|
||||
with:
|
||||
|
||||
@@ -15,7 +15,7 @@ jobs:
|
||||
packages: write
|
||||
steps:
|
||||
- name: Checkout repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v4
|
||||
- name: Log in to the Container registry
|
||||
uses: docker/login-action@65b78e6e13532edd9afa3aa52ac7964289d1a9c1
|
||||
with:
|
||||
|
||||
@@ -12,12 +12,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Install Node and PNPM
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
with:
|
||||
version: 10
|
||||
version: 9
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
- name: Build and Publish releases
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: nick-invision/retry@v3.0.2
|
||||
uses: nick-invision/retry@v2.8.2
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
@@ -37,7 +37,7 @@ jobs:
|
||||
- name: Build and Publish releases (arm64)
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: nick-invision/retry@v3.0.2
|
||||
uses: nick-invision/retry@v2.8.2
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
|
||||
@@ -12,12 +12,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Install Node and PNPM
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
with:
|
||||
version: 10
|
||||
version: 9
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
- name: Build and Publish releases
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: nick-invision/retry@v3.0.2
|
||||
uses: nick-invision/retry@v2.8.2
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
|
||||
@@ -1,31 +1,12 @@
|
||||
name: Publish (PR)
|
||||
|
||||
on:
|
||||
workflow_dispatch:
|
||||
pull_request:
|
||||
branches:
|
||||
- development
|
||||
paths:
|
||||
- 'src/**'
|
||||
- 'electron-builder*.yml'
|
||||
|
||||
jobs:
|
||||
wait-for-lint:
|
||||
if: github.event_name == 'pull_request'
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Wait for Test workflow to complete
|
||||
uses: lewagon/wait-on-check-action@v1.4.1
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.head.sha }}
|
||||
check-name: 'lint'
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
wait-interval: 10
|
||||
allowed-conclusions: success
|
||||
|
||||
publish:
|
||||
needs: wait-for-lint
|
||||
if: always() && (needs.wait-for-lint.result == 'success' || needs.wait-for-lint.result == 'skipped')
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
strategy:
|
||||
@@ -34,19 +15,19 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v3
|
||||
|
||||
- name: Install Node and PNPM
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
with:
|
||||
version: 10
|
||||
version: 9
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
- name: Build for Windows
|
||||
if: ${{ matrix.os == 'windows-latest' }}
|
||||
uses: nick-invision/retry@v3.0.2
|
||||
uses: nick-invision/retry@v2.8.2
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
@@ -56,7 +37,7 @@ jobs:
|
||||
|
||||
- name: Build for Linux
|
||||
if: ${{ matrix.os == 'ubuntu-latest' }}
|
||||
uses: nick-invision/retry@v3.0.2
|
||||
uses: nick-invision/retry@v2.8.2
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
@@ -66,7 +47,7 @@ jobs:
|
||||
|
||||
- name: Build for MacOS
|
||||
if: ${{ matrix.os == 'macos-latest' }}
|
||||
uses: nick-invision/retry@v3.0.2
|
||||
uses: nick-invision/retry@v2.8.2
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
@@ -92,21 +73,21 @@ jobs:
|
||||
|
||||
- name: Upload Windows Binaries
|
||||
if: ${{ matrix.os == 'windows-latest' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: windows-binaries
|
||||
path: dist/windows-binaries.zip
|
||||
|
||||
- name: Upload Linux Binaries
|
||||
if: ${{ matrix.os == 'ubuntu-latest' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: linux-binaries
|
||||
path: dist/linux-binaries.zip
|
||||
|
||||
- name: Upload MacOS Binaries
|
||||
if: ${{ matrix.os == 'macos-latest' }}
|
||||
uses: actions/upload-artifact@v7
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: macos-binaries
|
||||
path: dist/macos-binaries.zip
|
||||
|
||||
@@ -12,12 +12,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Install Node and PNPM
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
with:
|
||||
version: 10
|
||||
version: 9
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
@@ -25,7 +25,7 @@ jobs:
|
||||
- name: Build and Publish releases
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: nick-invision/retry@v3.0.2
|
||||
uses: nick-invision/retry@v2.8.2
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
|
||||
@@ -16,5 +16,6 @@ jobs:
|
||||
- uses: vedantmgoyal9/winget-releaser@main
|
||||
with:
|
||||
identifier: jeffvli.Feishin
|
||||
installers-regex: 'Feishin-*-win-(x64|arm64)\.exe'
|
||||
installers-regex: 'Feishin-*-win-x64\.exe'
|
||||
token: ${{ secrets.WINGET_ACC_TOKEN }}
|
||||
|
||||
|
||||
@@ -12,12 +12,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Checkout git repo
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Install Node and PNPM
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
with:
|
||||
version: 10
|
||||
version: 9
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
@@ -26,7 +26,7 @@ jobs:
|
||||
if: matrix.os == 'windows-latest'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: nick-invision/retry@v3.0.2
|
||||
uses: nick-invision/retry@v2.8.2
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
@@ -39,7 +39,7 @@ jobs:
|
||||
if: matrix.os == 'macos-latest'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: nick-invision/retry@v3.0.2
|
||||
uses: nick-invision/retry@v2.8.2
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
@@ -52,7 +52,7 @@ jobs:
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: nick-invision/retry@v3.0.2
|
||||
uses: nick-invision/retry@v2.8.2
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
@@ -65,7 +65,7 @@ jobs:
|
||||
if: matrix.os == 'ubuntu-latest'
|
||||
env:
|
||||
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
uses: nick-invision/retry@v3.0.2
|
||||
uses: nick-invision/retry@v2.8.2
|
||||
with:
|
||||
timeout_minutes: 30
|
||||
max_attempts: 3
|
||||
|
||||
@@ -8,12 +8,12 @@ jobs:
|
||||
|
||||
steps:
|
||||
- name: Check out Git repository
|
||||
uses: actions/checkout@v6
|
||||
uses: actions/checkout@v1
|
||||
|
||||
- name: Install Node.js and PNPM
|
||||
uses: pnpm/action-setup@v4
|
||||
uses: pnpm/action-setup@v4.1.0
|
||||
with:
|
||||
version: 10
|
||||
version: 9
|
||||
|
||||
- name: Install dependencies
|
||||
run: pnpm install
|
||||
|
||||
@@ -14,7 +14,9 @@
|
||||
".eslintignore": "ignore"
|
||||
},
|
||||
"eslint.validate": ["typescript", "typescriptreact"],
|
||||
"eslint.workingDirectories": [{ "directory": "./", "changeProcessCWD": true }],
|
||||
"eslint.workingDirectories": [
|
||||
{ "directory": "./", "changeProcessCWD": true },
|
||||
],
|
||||
"typescript.tsserver.experimental.enableProjectDiagnostics": false,
|
||||
"editor.codeActionsOnSave": {
|
||||
"source.fixAll.eslint": "explicit",
|
||||
@@ -48,10 +50,7 @@
|
||||
"typescript.preferences.autoImportFileExcludePatterns": [
|
||||
"@mantine/core",
|
||||
"@mantine/modals",
|
||||
"@mantine/dates",
|
||||
"@mantine/hooks",
|
||||
"@mantine/form",
|
||||
"@radix-ui/react-context-menu"
|
||||
"@mantine/dates"
|
||||
],
|
||||
"[typescriptreact]": { "editor.defaultFormatter": "esbenp.prettier-vscode" },
|
||||
"typescript.format.insertSpaceAfterOpeningAndBeforeClosingTemplateStringBraces": true,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
# --- Builder stage
|
||||
FROM node:23-alpine AS builder
|
||||
FROM node:23-alpine as builder
|
||||
WORKDIR /app
|
||||
|
||||
# Copy package.json first to cache node_modules
|
||||
@@ -14,14 +14,12 @@ COPY . .
|
||||
RUN pnpm run build:web
|
||||
|
||||
# --- 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 ./settings.js.template /etc/nginx/templates/settings.js.template
|
||||
COPY --chown=nginx:nginx ng.conf.template /etc/nginx/templates/default.conf.template
|
||||
|
||||
ENV SERVER_LOCK=false SERVER_NAME="" SERVER_TYPE="" SERVER_URL="" REMOTE_URL=""
|
||||
ENV LEGACY_AUTHENTICATION="" ANALYTICS_DISABLED="" PUBLIC_PATH="/"
|
||||
COPY ./settings.js.template /etc/nginx/templates/settings.js.template
|
||||
COPY ng.conf.template /etc/nginx/templates/default.conf.template
|
||||
|
||||
ENV PUBLIC_PATH="/"
|
||||
EXPOSE 9180
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
|
||||
@@ -43,7 +43,7 @@ Rewrite of [Sonixd](https://github.com/jeffvli/sonixd).
|
||||
|
||||
## 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
|
||||
|
||||
@@ -59,28 +59,21 @@ For media keys to work, you will be prompted to allow Feishin to be a Trusted Ac
|
||||
|
||||
#### Linux Notes
|
||||
|
||||
Feishin is available in [Flathub](https://flathub.org/en/apps/org.jeffvli.feishin).
|
||||
|
||||
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.
|
||||
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:
|
||||
|
||||
```sh
|
||||
dir=/your/application/directory
|
||||
curl 'https://raw.githubusercontent.com/jeffvli/feishin/refs/heads/development/install-feishin-appimage' | sh -s -- "$dir"
|
||||
```
|
||||
|
||||
The script also has an option to add launch arguments to run Feishin in native Wayland mode. Note that this is experimental in Electron and therefore not officially supported. If you want to use it, run this instead:
|
||||
|
||||
```sh
|
||||
dir=/your/application/directory
|
||||
curl 'https://raw.githubusercontent.com/jeffvli/feishin/refs/heads/development/install-feishin-appimage' | sh -s -- "$dir" wayland-native
|
||||
```
|
||||
|
||||
It also provides a simple uninstall routine, removing the downloaded files:
|
||||
|
||||
```sh
|
||||
dir=/your/application/directory
|
||||
curl 'https://raw.githubusercontent.com/jeffvli/feishin/refs/heads/development/install-feishin-appimage' | sh -s -- "$dir" remove
|
||||
@@ -105,25 +98,25 @@ docker run --name feishin -p 9180:9180 feishin
|
||||
|
||||
#### Docker Compose
|
||||
|
||||
To install via Docker Compose, use the following snippet. This also works on Portainer.
|
||||
To install via Docker Compose use the following snippit. This also works on Portainer.
|
||||
|
||||
```yaml
|
||||
services:
|
||||
feishin:
|
||||
container_name: feishin
|
||||
image: 'ghcr.io/jeffvli/feishin:latest'
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- SERVER_NAME=jellyfin # pre-defined server name
|
||||
- SERVER_NAME=jellyfin # pre defined server name
|
||||
- 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_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
|
||||
- ANALYTICS_DISABLED=true # Set to true to disable Umami analytics tracking
|
||||
- SERVER_TYPE=jellyfin # navidrome also works
|
||||
- SERVER_URL= # http://address:port
|
||||
- PUID=1000
|
||||
- PGID=1000
|
||||
- UMASK=002
|
||||
- TZ=America/Los_Angeles
|
||||
ports:
|
||||
- 9180:9180
|
||||
# Alternatively, to restrict to only localhost, - 127.0.0.1:9180:8190
|
||||
restart: unless-stopped
|
||||
```
|
||||
|
||||
### Configuration
|
||||
@@ -133,17 +126,11 @@ services:
|
||||
2. After restarting the app, you will be prompted to select a server. Click the `Open menu` button and select `Manage servers`. Click the `Add server` button in the popup and fill out all applicable details. You will need to enter the full URL to your server, including the protocol and port if applicable (e.g. `https://navidrome.my-server.com` or `http://192.168.0.1:4533`).
|
||||
|
||||
- **Navidrome** - For the best experience, select "Save password" when creating the server and configure the `SessionTimeout` setting in your Navidrome config to a larger value (e.g. 72h).
|
||||
- **Linux users** - The default password store uses `libsecret`. `kwallet4/5/6` are also supported, but must be explicitly set in Settings > Window > Passwords/secret store.
|
||||
- **Linux users** - The default password store uses `libsecret`. `kwallet4/5/6` are also supported, but must be explicitly set in Settings > Window > Passwords/secret score.
|
||||
|
||||
3. _Optional_ - If you want to host Feishin on a subpath (not `/`), then pass in the following environment variable: `PUBLIC_PATH=PATH`. For example, to host on `/feishin`, pass in `PUBLIC_PATH=/feishin`.
|
||||
|
||||
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.
|
||||
|
||||
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.
|
||||
4. _Optional_ - To hard code the server url, pass the following environment variables: `SERVER_NAME`, `SERVER_TYPE` (one of `jellyfin` or `navidrome`), `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.
|
||||
|
||||
## FAQ
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 73 KiB After Width: | Height: | Size: 154 KiB |
|
Before Width: | Height: | Size: 6.4 KiB After Width: | Height: | Size: 6.3 KiB |
|
Before Width: | Height: | Size: 651 B |
|
Before Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 14 KiB After Width: | Height: | Size: 16 KiB |
|
Before Width: | Height: | Size: 1.5 KiB After Width: | Height: | Size: 1.4 KiB |
|
Before Width: | Height: | Size: 2.3 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 48 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 4.8 KiB |
|
Before Width: | Height: | Size: 277 B |
|
Before Width: | Height: | Size: 447 B |
|
Before Width: | Height: | Size: 422 KiB After Width: | Height: | Size: 176 KiB |
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 48 KiB |
@@ -1,16 +1,13 @@
|
||||
version: '3.5'
|
||||
services:
|
||||
feishin:
|
||||
container_name: feishin
|
||||
image: "ghcr.io/jeffvli/feishin:latest"
|
||||
image: ghcr.io/jeffvli/feishin:latest
|
||||
restart: unless-stopped
|
||||
environment:
|
||||
- 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_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
|
||||
# - 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)
|
||||
- ANALYTICS_DISABLED=false # Set to true to disable Umami analytics tracking
|
||||
ports:
|
||||
- 9180:9180
|
||||
# Alternatively, to restrict to only localhost, - 127.0.0.1:9180:8190
|
||||
environment:
|
||||
- SERVER_NAME=jellyfin # pre defined server name
|
||||
- SERVER_LOCK=true # When true AND name/type/url are set, only username/password can be toggled
|
||||
- SERVER_TYPE=jellyfin # navidrome also works
|
||||
- SERVER_URL= # http://address:port
|
||||
|
||||
@@ -1,129 +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 0–9 (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.sidebarPlaylistList` | `true` | `FS_GENERAL_SIDEBAR_PLAYLIST_LIST` | `true` / `false` — Show playlist list in sidebar. |
|
||||
| `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 theme’s accent color instead of custom. |
|
||||
| `general.useThemePrimaryShade` | `true` | `FS_GENERAL_USE_THEME_PRIMARY_SHADE` | `true` / `false` — Use theme’s 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. |
|
||||
|
||||
---
|
||||
|
||||
## 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.enabled` | `false` | `FS_AUTO_DJ_ENABLED` | `true` / `false`. |
|
||||
| `autoDJ.itemCount` | `5` | `FS_AUTO_DJ_ITEM_COUNT` | Number of items to add. |
|
||||
| `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`). |
|
||||
@@ -1,72 +0,0 @@
|
||||
appId: org.jeffvli.feishin
|
||||
productName: Feishin
|
||||
artifactName: ${productName}-${version}-${os}-${arch}.${ext}
|
||||
electronVersion: 39.4.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: assets/icons/icon.icns
|
||||
type: distribution
|
||||
hardenedRuntime: false
|
||||
identity: "-"
|
||||
gatekeeperAssess: false
|
||||
notarize: false
|
||||
|
||||
|
||||
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.2"
|
||||
|
||||
npmRebuild: false
|
||||
|
||||
publish:
|
||||
provider: s3
|
||||
bucket: feishin-nightly
|
||||
channel: alpha
|
||||
endpoint: https://065f090c64de2dc707dd70ac72db9669.r2.cloudflarestorage.com
|
||||
@@ -1,7 +1,7 @@
|
||||
appId: org.jeffvli.feishin
|
||||
productName: Feishin
|
||||
artifactName: ${productName}-${version}-${os}-${arch}.${ext}
|
||||
electronVersion: 39.4.0
|
||||
electronVersion: 38.5.0
|
||||
directories:
|
||||
buildResources: assets
|
||||
files:
|
||||
@@ -13,15 +13,9 @@ asarUnpack:
|
||||
- resources/**
|
||||
win:
|
||||
target:
|
||||
- target: zip
|
||||
arch:
|
||||
- x64
|
||||
- arm64
|
||||
- target: nsis
|
||||
arch:
|
||||
- x64
|
||||
- arm64
|
||||
icon: assets/icons/icon.ico
|
||||
- zip
|
||||
- nsis
|
||||
icon: assets/icons/icon.png
|
||||
|
||||
nsis:
|
||||
allowToChangeInstallationDirectory: true
|
||||
@@ -32,18 +26,15 @@ nsis:
|
||||
|
||||
mac:
|
||||
target:
|
||||
- target: dmg
|
||||
arch:
|
||||
- arm64
|
||||
- x64
|
||||
- target: zip
|
||||
arch:
|
||||
- arm64
|
||||
- x64
|
||||
target: default
|
||||
arch:
|
||||
- arm64
|
||||
- x64
|
||||
icon: assets/icons/icon.icns
|
||||
type: distribution
|
||||
hardenedRuntime: false
|
||||
identity: "-"
|
||||
hardenedRuntime: true
|
||||
entitlements: assets/entitlements.mac.plist
|
||||
entitlementsInherit: assets/entitlements.mac.plist
|
||||
gatekeeperAssess: false
|
||||
notarize: false
|
||||
|
||||
@@ -53,15 +44,11 @@ dmg:
|
||||
linux:
|
||||
target:
|
||||
- AppImage
|
||||
- deb
|
||||
- tar.xz
|
||||
category: AudioVideo;Audio;Player
|
||||
icon: assets/icons/icon.png
|
||||
artifactName: ${productName}-${os}-${arch}.${ext}
|
||||
|
||||
toolsets:
|
||||
appimage: "1.0.2"
|
||||
|
||||
npmRebuild: false
|
||||
publish:
|
||||
provider: github
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
appId: org.jeffvli.feishin
|
||||
productName: Feishin
|
||||
artifactName: ${productName}-${version}-${os}-${arch}.${ext}
|
||||
electronVersion: 39.4.0
|
||||
electronVersion: 38.5.0
|
||||
directories:
|
||||
buildResources: assets
|
||||
files:
|
||||
@@ -13,15 +13,9 @@ asarUnpack:
|
||||
- resources/**
|
||||
win:
|
||||
target:
|
||||
- target: zip
|
||||
arch:
|
||||
- x64
|
||||
- arm64
|
||||
- target: nsis
|
||||
arch:
|
||||
- x64
|
||||
- arm64
|
||||
icon: assets/icons/icon.ico
|
||||
- zip
|
||||
- nsis
|
||||
icon: assets/icons/icon.png
|
||||
|
||||
nsis:
|
||||
allowToChangeInstallationDirectory: true
|
||||
@@ -32,18 +26,15 @@ nsis:
|
||||
|
||||
mac:
|
||||
target:
|
||||
- target: dmg
|
||||
arch:
|
||||
- arm64
|
||||
- x64
|
||||
- target: zip
|
||||
arch:
|
||||
- arm64
|
||||
- x64
|
||||
target: default
|
||||
arch:
|
||||
- arm64
|
||||
- x64
|
||||
icon: assets/icons/icon.icns
|
||||
type: distribution
|
||||
hardenedRuntime: false
|
||||
identity: "-"
|
||||
hardenedRuntime: true
|
||||
entitlements: assets/entitlements.mac.plist
|
||||
entitlementsInherit: assets/entitlements.mac.plist
|
||||
gatekeeperAssess: false
|
||||
notarize: false
|
||||
|
||||
@@ -53,17 +44,12 @@ dmg:
|
||||
linux:
|
||||
target:
|
||||
- AppImage
|
||||
- deb
|
||||
- tar.xz
|
||||
category: AudioVideo;Audio;Player
|
||||
icon: assets/icons/icon.png
|
||||
artifactName: ${productName}-${os}-${arch}.${ext}
|
||||
|
||||
toolsets:
|
||||
appimage: "1.0.2"
|
||||
|
||||
npmRebuild: false
|
||||
afterAllArtifactBuild: scripts/after-all-artifact-build.mjs
|
||||
publish:
|
||||
provider: github
|
||||
owner: jeffvli
|
||||
|
||||
@@ -6,7 +6,6 @@ import dynamicImportPlugin from 'vite-plugin-dynamic-import';
|
||||
import { ViteEjsPlugin } from 'vite-plugin-ejs';
|
||||
|
||||
const currentOSEnv = process.platform;
|
||||
const electronRendererTarget = 'chrome87';
|
||||
|
||||
const config: UserConfig = {
|
||||
main: {
|
||||
@@ -37,9 +36,6 @@ const config: UserConfig = {
|
||||
},
|
||||
},
|
||||
preload: {
|
||||
build: {
|
||||
sourcemap: true,
|
||||
},
|
||||
plugins: [externalizeDepsPlugin()],
|
||||
resolve: {
|
||||
alias: {
|
||||
@@ -49,15 +45,6 @@ const config: UserConfig = {
|
||||
},
|
||||
},
|
||||
renderer: {
|
||||
build: {
|
||||
cssMinify: 'esbuild',
|
||||
minify: 'esbuild',
|
||||
modulePreload: {
|
||||
polyfill: false,
|
||||
},
|
||||
sourcemap: true,
|
||||
target: electronRendererTarget,
|
||||
},
|
||||
css: {
|
||||
modules: {
|
||||
generateScopedName: 'fs-[name]-[local]',
|
||||
|
||||
@@ -43,8 +43,6 @@ export default tseslint.config(
|
||||
'no-unused-vars': 'off',
|
||||
'no-use-before-define': 'off',
|
||||
quotes: ['error', 'single'],
|
||||
'react-hooks/refs': 'off',
|
||||
'react-hooks/set-state-in-effect': 'off',
|
||||
'react-refresh/only-export-components': 'off',
|
||||
'react/display-name': 'off',
|
||||
semi: ['error', 'always'],
|
||||
|
||||
|
After Width: | Height: | Size: 118 KiB |
|
Before Width: | Height: | Size: 81 KiB |
|
Before Width: | Height: | Size: 77 KiB |
|
Before Width: | Height: | Size: 214 KiB |
|
After Width: | Height: | Size: 101 KiB |
@@ -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 |
|
Before Width: | Height: | Size: 733 KiB After Width: | Height: | Size: 644 KiB |
|
Before Width: | Height: | Size: 371 KiB After Width: | Height: | Size: 186 KiB |
|
Before Width: | Height: | Size: 869 KiB After Width: | Height: | Size: 465 KiB |
|
Before Width: | Height: | Size: 49 KiB |
|
Before Width: | Height: | Size: 990 KiB After Width: | Height: | Size: 887 KiB |
|
Before Width: | Height: | Size: 356 KiB After Width: | Height: | Size: 396 KiB |
@@ -1,6 +1,5 @@
|
||||
server {
|
||||
listen 9180;
|
||||
listen [::]:9180;
|
||||
sendfile on;
|
||||
default_type application/octet-stream;
|
||||
|
||||
@@ -20,11 +19,9 @@ server {
|
||||
|
||||
location ${PUBLIC_PATH}settings.js {
|
||||
alias /etc/nginx/conf.d/settings.js;
|
||||
add_header Cache-Control "no-store";
|
||||
}
|
||||
|
||||
location ${PUBLIC_PATH}/settings.js {
|
||||
alias /etc/nginx/conf.d/settings.js;
|
||||
add_header Cache-Control "no-store";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "feishin",
|
||||
"version": "1.9.0",
|
||||
"version": "0.21.2",
|
||||
"description": "A modern self-hosted music player.",
|
||||
"keywords": [
|
||||
"subsonic",
|
||||
@@ -16,12 +16,11 @@
|
||||
"license": "GPL-3.0",
|
||||
"author": {
|
||||
"name": "jeffvli",
|
||||
"email": "feishin@users.noreply.github.com",
|
||||
"url": "https://github.com/jeffvli/"
|
||||
},
|
||||
"main": "./out/main/index.js",
|
||||
"scripts": {
|
||||
"build": "pnpm run build:electron && pnpm run build:remote",
|
||||
"build": "pnpm run typecheck && pnpm run build:electron && pnpm run build:remote",
|
||||
"build:electron": "electron-vite build",
|
||||
"build:remote": "vite build --config remote.vite.config.ts",
|
||||
"build:web": "vite build --config web.vite.config.ts",
|
||||
@@ -30,7 +29,7 @@
|
||||
"dev:watch": "electron-vite dev --watch",
|
||||
"i18next": "i18next -c src/i18n/i18next-parser.config.js",
|
||||
"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-code": "eslint --max-warnings=0 --cache .",
|
||||
"lint-code:fix": "eslint --cache --fix .",
|
||||
"lint-styles": "stylelint --max-warnings=0 'src/**/*.{css,scss}'",
|
||||
@@ -44,22 +43,14 @@
|
||||
"package:mac": "pnpm run build && electron-builder --mac",
|
||||
"package:mac:pr": "pnpm run build && electron-builder --mac --publish never",
|
||||
"package:win": "pnpm run build && electron-builder --win",
|
||||
"package:win-arm64:pr": "pnpm run build && electron-builder --win --arm64 --publish never",
|
||||
"package:win:pr": "pnpm run build && electron-builder --win --publish never",
|
||||
"publish:linux": "pnpm run build && electron-builder --publish always --linux",
|
||||
"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: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: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:win": "pnpm run build && electron-builder --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",
|
||||
"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",
|
||||
"start": "electron-vite preview",
|
||||
"typecheck": "pnpm run typecheck:node && pnpm run typecheck:web",
|
||||
@@ -69,73 +60,75 @@
|
||||
"postversion": "node ./scripts/update-app-stream.mjs"
|
||||
},
|
||||
"dependencies": {
|
||||
"@atlaskit/pragmatic-drag-and-drop": "1.7.7",
|
||||
"@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^2.1.2",
|
||||
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.1.0",
|
||||
"@ag-grid-community/client-side-row-model": "^28.2.1",
|
||||
"@ag-grid-community/core": "^28.2.1",
|
||||
"@ag-grid-community/infinite-row-model": "^28.2.1",
|
||||
"@ag-grid-community/react": "^28.2.1",
|
||||
"@ag-grid-community/styles": "^28.2.1",
|
||||
"@atlaskit/pragmatic-drag-and-drop": "1.4.0",
|
||||
"@atlaskit/pragmatic-drag-and-drop-auto-scroll": "^2.1.0",
|
||||
"@atlaskit/pragmatic-drag-and-drop-hitbox": "^1.0.3",
|
||||
"@electron-toolkit/preload": "^3.0.1",
|
||||
"@electron-toolkit/utils": "^4.0.0",
|
||||
"@mantine/colors-generator": "^8.3.8",
|
||||
"@mantine/core": "^8.3.8",
|
||||
"@mantine/dates": "^8.3.8",
|
||||
"@mantine/form": "^8.3.8",
|
||||
"@mantine/hooks": "^8.3.8",
|
||||
"@mantine/modals": "^8.3.8",
|
||||
"@mantine/notifications": "^8.3.8",
|
||||
"@radix-ui/react-context-menu": "^2.2.16",
|
||||
"@tanstack/react-query": "^5.90.9",
|
||||
"@tanstack/react-query-devtools": "^5.90.2",
|
||||
"@tanstack/react-query-persist-client": "^5.90.11",
|
||||
"@ts-rest/core": "^3.52.1",
|
||||
"@wavesurfer/react": "^1.0.11",
|
||||
"@mantine/colors-generator": "^8.2.8",
|
||||
"@mantine/core": "^8.2.8",
|
||||
"@mantine/dates": "^8.2.8",
|
||||
"@mantine/form": "^8.2.8",
|
||||
"@mantine/hooks": "^8.2.8",
|
||||
"@mantine/modals": "^8.2.8",
|
||||
"@mantine/notifications": "^8.2.8",
|
||||
"@tanstack/react-query": "^5.89.0",
|
||||
"@tanstack/react-query-devtools": "^5.89.0",
|
||||
"@tanstack/react-query-persist-client": "^5.89.0",
|
||||
"@ts-rest/core": "^3.23.0",
|
||||
"@xhayper/discord-rpc": "^1.3.0",
|
||||
"audiomotion-analyzer": "^4.5.1",
|
||||
"axios": "^1.13.5",
|
||||
"butterchurn": "^3.0.0-beta.5",
|
||||
"butterchurn-presets": "^3.0.0-beta.4",
|
||||
"cheerio": "^1.1.2",
|
||||
"clsx": "^2.1.1",
|
||||
"cmdk": "^1.1.1",
|
||||
"dayjs": "^1.11.19",
|
||||
"dompurify": "^3.3.0",
|
||||
"audiomotion-analyzer": "^4.5.0",
|
||||
"auto-text-size": "^0.2.3",
|
||||
"axios": "^1.12.0",
|
||||
"cheerio": "^1.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"cmdk": "^0.2.0",
|
||||
"dayjs": "^1.11.6",
|
||||
"dompurify": "^3.1.6",
|
||||
"electron-debug": "^3.2.0",
|
||||
"electron-localshortcut": "^3.2.1",
|
||||
"electron-log": "^5.4.3",
|
||||
"electron-store": "^8.2.0",
|
||||
"electron-updater": "^6.6.2",
|
||||
"fast-average-color": "^9.5.0",
|
||||
"fast-xml-parser": "^5.3.8",
|
||||
"format-duration": "^3.0.2",
|
||||
"fuse.js": "^7.1.0",
|
||||
"i18next": "^25.6.2",
|
||||
"icecast-metadata-stats": "^0.1.12",
|
||||
"idb-keyval": "^6.2.2",
|
||||
"immer": "^10.2.0",
|
||||
"electron-log": "^5.1.1",
|
||||
"electron-store": "^8.1.0",
|
||||
"electron-updater": "^6.3.9",
|
||||
"fast-average-color": "^9.3.0",
|
||||
"fast-xml-parser": "^5.3.0",
|
||||
"format-duration": "^2.0.0",
|
||||
"fuse.js": "^6.6.2",
|
||||
"i18next": "^21.10.0",
|
||||
"idb-keyval": "^6.2.1",
|
||||
"immer": "^9.0.21",
|
||||
"is-electron": "^2.2.2",
|
||||
"lodash": "^4.17.23",
|
||||
"lodash": "^4.17.21",
|
||||
"md5": "^2.3.0",
|
||||
"motion": "^12.23.24",
|
||||
"memoize-one": "^6.0.0",
|
||||
"motion": "^12.18.1",
|
||||
"mpris-service": "^2.1.2",
|
||||
"nanoid": "^3.3.11",
|
||||
"nanoid": "^3.3.3",
|
||||
"node-mpv": "github:jeffvli/Node-MPV#32b4d64395289ad710c41d481d2707a7acfc228f",
|
||||
"nuqs": "^2.7.1",
|
||||
"overlayscrollbars": "^2.11.1",
|
||||
"overlayscrollbars-react": "^0.5.6",
|
||||
"qs": "^6.14.2",
|
||||
"qs": "^6.14.0",
|
||||
"react": "^19.1.0",
|
||||
"react-call": "^1.8.1",
|
||||
"react-dom": "^19.1.0",
|
||||
"react-error-boundary": "^5.0.0",
|
||||
"react-i18next": "^16.3.3",
|
||||
"react-error-boundary": "^3.1.4",
|
||||
"react-i18next": "^11.18.6",
|
||||
"react-icons": "^5.5.0",
|
||||
"react-player": "^2.16.0",
|
||||
"react-router": "^7.13.1",
|
||||
"react-split-pane": "^3.0.4",
|
||||
"react-virtualized-auto-sizer": "^1.0.26",
|
||||
"react-window": "1.8.11",
|
||||
"react-window-v2": "npm:react-window@^2.2.3",
|
||||
"react-image": "^4.1.0",
|
||||
"react-loading-skeleton": "^3.5.0",
|
||||
"react-player": "^2.11.0",
|
||||
"react-router": "^6.16.0",
|
||||
"react-router-dom": "^6.16.0",
|
||||
"react-virtualized-auto-sizer": "^1.0.17",
|
||||
"react-window": "^1.8.9",
|
||||
"react-window-infinite-loader": "^1.0.9",
|
||||
"semver": "^7.5.4",
|
||||
"string-to-color": "^2.2.2",
|
||||
"wavesurfer.js": "^7.11.1",
|
||||
"swiper": "^9.3.1",
|
||||
"use-sync-external-store": "^1.5.0",
|
||||
"ws": "^8.18.2",
|
||||
"zod": "^3.22.3",
|
||||
"zustand": "^5.0.5"
|
||||
@@ -143,44 +136,45 @@
|
||||
"devDependencies": {
|
||||
"@electron-toolkit/eslint-config-prettier": "^3.0.0",
|
||||
"@electron-toolkit/eslint-config-ts": "^3.0.0",
|
||||
"@electron-toolkit/tsconfig": "^2.0.0",
|
||||
"@electron-toolkit/tsconfig": "^1.0.1",
|
||||
"@types/electron-localshortcut": "^3.1.0",
|
||||
"@types/lodash": "^4.17.18",
|
||||
"@types/md5": "^2.3.5",
|
||||
"@types/node": "^24.10.1",
|
||||
"@types/react": "^19.2.5",
|
||||
"@types/react-dom": "^19.2.3",
|
||||
"@types/react-window": "^1.8.8",
|
||||
"@types/node": "^22.15.32",
|
||||
"@types/react": "^18.3.23",
|
||||
"@types/react-dom": "^18.3.7",
|
||||
"@types/react-window": "^1.8.5",
|
||||
"@types/react-window-infinite-loader": "^1.0.6",
|
||||
"@types/source-map-support": "^0.5.10",
|
||||
"@types/ws": "^8.18.1",
|
||||
"@vitejs/plugin-react": "^5.1.1",
|
||||
"concurrently": "^9.2.1",
|
||||
"cross-env": "^10.1.0",
|
||||
"electron": "^39.4.0",
|
||||
"electron-builder": "^26.8.2",
|
||||
"electron-devtools-installer": "^4.0.0",
|
||||
"electron-vite": "^4.0.1",
|
||||
"@vitejs/plugin-react": "^4.3.4",
|
||||
"concurrently": "^7.1.0",
|
||||
"cross-env": "^7.0.3",
|
||||
"electron": "^38.5.0",
|
||||
"electron-builder": "^26.0.12",
|
||||
"electron-devtools-installer": "^3.2.0",
|
||||
"electron-vite": "^3.1.0",
|
||||
"eslint": "^9.24.0",
|
||||
"eslint-plugin-perfectionist": "^4.13.0",
|
||||
"eslint-plugin-prettier": "^5.4.0",
|
||||
"eslint-plugin-react": "^7.37.5",
|
||||
"eslint-plugin-react-hooks": "^7.0.1",
|
||||
"eslint-plugin-react-refresh": "^0.4.24",
|
||||
"i18next-parser": "^9.3.0",
|
||||
"postcss-preset-mantine": "^1.18.0",
|
||||
"postcss-simple-vars": "^7.0.1",
|
||||
"prettier": "^3.6.2",
|
||||
"prettier-plugin-packagejson": "^2.5.19",
|
||||
"stylelint": "^16.25.0",
|
||||
"stylelint-config-css-modules": "^4.5.1",
|
||||
"stylelint-config-recess-order": "^7.4.0",
|
||||
"stylelint-config-standard": "^39.0.1",
|
||||
"eslint-plugin-react-hooks": "^5.2.0",
|
||||
"eslint-plugin-react-refresh": "^0.4.19",
|
||||
"i18next-parser": "^9.0.2",
|
||||
"postcss-preset-mantine": "^1.17.0",
|
||||
"prettier": "^3.5.3",
|
||||
"prettier-plugin-packagejson": "^2.5.14",
|
||||
"sass-embedded": "^1.89.0",
|
||||
"stylelint": "^16.14.1",
|
||||
"stylelint-config-css-modules": "^4.4.0",
|
||||
"stylelint-config-recess-order": "^7.1.0",
|
||||
"stylelint-config-standard": "^38.0.0",
|
||||
"typescript": "^5.8.3",
|
||||
"vite": "^7.2.2",
|
||||
"vite": "^6.4.1",
|
||||
"vite-plugin-conditional-import": "^0.1.7",
|
||||
"vite-plugin-dynamic-import": "^1.6.0",
|
||||
"vite-plugin-ejs": "^1.7.0",
|
||||
"vite-plugin-pwa": "^1.1.0"
|
||||
"vite-plugin-pwa": "^1.0.3"
|
||||
},
|
||||
"pnpm": {
|
||||
"onlyBuiltDependencies": [
|
||||
|
||||
@@ -1,16 +1,5 @@
|
||||
module.exports = {
|
||||
plugins: {
|
||||
'postcss-preset-mantine': {},
|
||||
'postcss-simple-vars': {
|
||||
variables: {
|
||||
'mantine-breakpoint-2xl': '120em',
|
||||
'mantine-breakpoint-3xl': '160em',
|
||||
'mantine-breakpoint-lg': '75em',
|
||||
'mantine-breakpoint-md': '62em',
|
||||
'mantine-breakpoint-sm': '48em',
|
||||
'mantine-breakpoint-xl': '88em',
|
||||
'mantine-breakpoint-xs': '36em',
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
@@ -7,9 +7,7 @@ import { version } from './package.json';
|
||||
|
||||
export default defineConfig({
|
||||
build: {
|
||||
cssMinify: 'esbuild',
|
||||
emptyOutDir: true,
|
||||
minify: 'esbuild',
|
||||
outDir: path.resolve(__dirname, './out/remote'),
|
||||
rollupOptions: {
|
||||
input: {
|
||||
@@ -23,7 +21,6 @@ export default defineConfig({
|
||||
assetFileNames: '[name].[ext]',
|
||||
chunkFileNames: '[name].js',
|
||||
entryFileNames: '[name].js',
|
||||
sourcemapExcludeSources: false,
|
||||
},
|
||||
},
|
||||
sourcemap: true,
|
||||
|
||||
|
Before Width: | Height: | Size: 32 KiB After Width: | Height: | Size: 48 KiB |
@@ -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 [];
|
||||
}
|
||||
@@ -3,51 +3,30 @@ import fs from 'fs';
|
||||
import path from 'path';
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
|
||||
// Parse flags and positional arguments
|
||||
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]',
|
||||
);
|
||||
if (args.length > 3) {
|
||||
console.error('Usage: node update-app-stream.js [package-file] [date] [metainfo-file]');
|
||||
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 packageJson = JSON.parse(packageContent);
|
||||
const version = packageJson.version;
|
||||
|
||||
const time = Math.floor((Date.parse(positionalArgs[1]) || Date.now()) / 1000);
|
||||
const metainfoFile =
|
||||
positionalArgs[2] || path.resolve(process.cwd(), 'org.jeffvli.feishin.metainfo.xml');
|
||||
const time = Math.floor((Date.parse(args[1]) || Date.now()) / 1000);
|
||||
const metainfoFile = args[2] || path.resolve(process.cwd(), 'org.jeffvli.feishin.metainfo.xml');
|
||||
|
||||
const parser = new XMLParser({ ignoreAttributes: false });
|
||||
const metainfoContent = fs.readFileSync(metainfoFile, 'utf8');
|
||||
const metainfo = parser.parse(metainfoContent);
|
||||
|
||||
const newRelease = {
|
||||
'@_date': new Date(time * 1000).toISOString().split('T')[0],
|
||||
'@_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);
|
||||
}
|
||||
if (!metainfo.component.releases.release.find((release) => release['@_version'] === version)) {
|
||||
metainfo.component.releases.release.unshift({
|
||||
'@_date': new Date(time * 1000).toISOString().split('T')[0],
|
||||
'@_type': version.includes('-') ? 'development' : 'stable',
|
||||
'@_version': version,
|
||||
});
|
||||
}
|
||||
|
||||
const builder = new XMLBuilder({ format: true, ignoreAttributes: false, indentBy: ' ' });
|
||||
|
||||
@@ -1,90 +1 @@
|
||||
"use strict";
|
||||
|
||||
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_LIST = "${FS_GENERAL_SIDEBAR_PLAYLIST_LIST}";
|
||||
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_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_ENABLED = "${FS_AUTO_DJ_ENABLED}";
|
||||
window.FS_AUTO_DJ_ITEM_COUNT = "${FS_AUTO_DJ_ITEM_COUNT}";
|
||||
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}";
|
||||
"use strict";window.SERVER_URL="${SERVER_URL}";window.SERVER_NAME="${SERVER_NAME}";window.SERVER_TYPE="${SERVER_TYPE}";window.SERVER_LOCK=${SERVER_LOCK};
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { PostProcessorModule, TOptions } from 'i18next';
|
||||
import { PostProcessorModule, StringMap, TOptions } from 'i18next';
|
||||
import i18n from 'i18next';
|
||||
import { initReactI18next } from 'react-i18next';
|
||||
|
||||
@@ -207,12 +207,7 @@ const ignoreSentenceCaseLanguages = ['de'];
|
||||
|
||||
const sentenceCasePostProcessor: PostProcessorModule = {
|
||||
name: 'sentenceCase',
|
||||
process: (
|
||||
value: string,
|
||||
_key: string,
|
||||
_options: TOptions<Record<string, string>>,
|
||||
translator: any,
|
||||
) => {
|
||||
process: (value: string, _key: string, _options: TOptions<StringMap>, translator: any) => {
|
||||
const sentences = value.split('. ');
|
||||
|
||||
return sentences
|
||||
|
||||
@@ -1,33 +1,27 @@
|
||||
{
|
||||
"action": {
|
||||
"addToFavorites": "إضافة الى $t(entity.favorite, {\"count\": 2})",
|
||||
"addToPlaylist": "إضافة الى $t(entity.playlist, {\"count\": 1})",
|
||||
"addToFavorites": "إضافة الى $t(entity.favorite_other)",
|
||||
"addToPlaylist": "إضافة الى $t(entity.playlist_one)",
|
||||
"clearQueue": "مسح قائمة الإنتظار",
|
||||
"createPlaylist": "إنشاء $t(entity.playlist, {\"count\": 1})",
|
||||
"deletePlaylist": "حذف $t(entity.playlist, {\"count\": 1})",
|
||||
"createPlaylist": "إنشاء $t(entity.playlist_one)",
|
||||
"deletePlaylist": "حذف $t(entity.playlist_one)",
|
||||
"deselectAll": "إلغاء تحديد الكل",
|
||||
"editPlaylist": "تعديل $t(entity.playlist, {\"count\": 1})",
|
||||
"editPlaylist": "تعديل $t(entity.playlist_one)",
|
||||
"goToPage": "اذهب الى صفحة",
|
||||
"moveToNext": "الذهاب الى التالي",
|
||||
"moveToBottom": "الذهاب الى الأسفل",
|
||||
"moveToTop": "الذهاب الى الأعلى",
|
||||
"refresh": "$t(common.refresh)",
|
||||
"removeFromFavorites": "حذف من $t(entity.favorite, {\"count\": 2})",
|
||||
"removeFromPlaylist": "حذف من $t(entity.playlist, {\"count\": 1})",
|
||||
"removeFromFavorites": "حذف من $t(entity.favorite_other)",
|
||||
"removeFromPlaylist": "حذف من $t(entity.playlist_one)",
|
||||
"removeFromQueue": "حذف من قائمة الإنتظار",
|
||||
"setRating": "تحديد التقييم",
|
||||
"toggleSmartPlaylistEditor": "تشغيل / إطفاء وضع التعديل لـ $t(entity.smartPlaylist)",
|
||||
"viewPlaylists": "إظهار $t(entity.playlist, {\"count\": 2})",
|
||||
"viewPlaylists": "إظهار $t(entity.playlist_other)",
|
||||
"openIn": {
|
||||
"lastfm": "فتح في Last.fm",
|
||||
"musicbrainz": "فتح في MusicBrainz"
|
||||
},
|
||||
"addOrRemoveFromSelection": "إضافة أو إزالة من الإختيارات",
|
||||
"selectRangeOfItems": "اختر مجموعة من العناصر",
|
||||
"goToCurrent": "الانتقال إلى العنصر الحالي",
|
||||
"createRadioStation": "يخلق $t(entity.radioStation, {\"count\": 1})",
|
||||
"deleteRadioStation": "يمسح $t(entity.radioStation, {\"count\": 1})",
|
||||
"selectAll": "تحديد الكل"
|
||||
}
|
||||
},
|
||||
"common": {
|
||||
"action_zero": "عملية",
|
||||
@@ -65,7 +59,7 @@
|
||||
"configure": "تعديل",
|
||||
"confirm": "تأكيد",
|
||||
"create": "إنشاء",
|
||||
"currentSong": "$t(entity.track, {\"count\": 1}) الحالي",
|
||||
"currentSong": "$t(entity.track_one) الحالي",
|
||||
"decrease": "تنقيص",
|
||||
"delete": "حذف",
|
||||
"descending": "تنازلي",
|
||||
@@ -108,7 +102,7 @@
|
||||
"path": "المسار",
|
||||
"playerMustBePaused": "يجب إيقاف المشغل",
|
||||
"preview": "معاينة",
|
||||
"previousSong": "$t(entity.track, {\"count\": 1}) السابق",
|
||||
"previousSong": "$t(entity.track_one) السابق",
|
||||
"quit": "خروج",
|
||||
"random": "عشوائي",
|
||||
"rating": "التقييم",
|
||||
@@ -123,12 +117,7 @@
|
||||
"saveAndReplace": "حفظ واستبدال",
|
||||
"saveAs": "حفظ بإسم",
|
||||
"search": "بحث",
|
||||
"setting_zero": "إعداد",
|
||||
"setting_one": "",
|
||||
"setting_two": "",
|
||||
"setting_few": "",
|
||||
"setting_many": "",
|
||||
"setting_other": "",
|
||||
"setting": "إعداد",
|
||||
"share": "نشر",
|
||||
"size": "حجم",
|
||||
"sortOrder": "الترتيب",
|
||||
|
||||
@@ -1,43 +1,27 @@
|
||||
{
|
||||
"action": {
|
||||
"deselectAll": "deshautatu dena",
|
||||
"editPlaylist": "editatu $t(entity.playlist, {\"count\": 1})",
|
||||
"editPlaylist": "editatu $t(entity.playlist_one)",
|
||||
"goToPage": "joan orrira",
|
||||
"moveToNext": "mugitu hurrengora",
|
||||
"moveToBottom": "mugitu behera",
|
||||
"moveToTop": "mugitu gora",
|
||||
"refresh": "$t(common.refresh)",
|
||||
"removeFromFavorites": "kendu gogokoetatik",
|
||||
"removeFromPlaylist": "kendu $t(entity.playlist, {\"count\": 1})-(e)tik",
|
||||
"removeFromFavorites": "kendu $t(entity.favorite_other)-(e)tik",
|
||||
"removeFromPlaylist": "kendu $t(entity.playlist_one)-(e)tik",
|
||||
"removeFromQueue": "kendu ilaratik",
|
||||
"setRating": "ezarri balorazioa",
|
||||
"toggleSmartPlaylistEditor": "txandakatu $t(entity.smartPlaylist) editorea",
|
||||
"viewPlaylists": "ikusi $t(entity.playlist, {\"count\": 2})",
|
||||
"viewPlaylists": "ikusi $t(entity.playlist_other)",
|
||||
"openIn": {
|
||||
"lastfm": "Ireki Last.fm-n",
|
||||
"musicbrainz": "Ireki MusicBrainz-en",
|
||||
"listenbrainz": "Ireki ListenBrainz-en",
|
||||
"qobuz": "Ireki Qobuz-en",
|
||||
"spotify": "Ireki Spotify-n"
|
||||
"musicbrainz": "Ireki MusicBrainz-en"
|
||||
},
|
||||
"clearQueue": "garbitu ilara",
|
||||
"createPlaylist": "sortu $t(entity.playlist, {\"count\": 1})",
|
||||
"deletePlaylist": "ezabatu $t(entity.playlist, {\"count\": 1})",
|
||||
"addToFavorites": "gehitu gogokoetara",
|
||||
"addToPlaylist": "gehitu $t(entity.playlist, {\"count\": 1})ra",
|
||||
"createRadioStation": "sortu $t(entity.radioStation, {\"count\": 1})",
|
||||
"deleteRadioStation": "ezabatu $t(entity.radioStation, {\"count\": 1})",
|
||||
"viewMore": "ikusi gehiago",
|
||||
"shuffle": "nahastu",
|
||||
"selectAll": "aukeratu guztiak",
|
||||
"downloadStarted": "{{count}} elementuren deskarga hasi da",
|
||||
"addOrRemoveFromSelection": "gehitu edo kendu hautapenetik",
|
||||
"selectRangeOfItems": "aukeratu elementu sorta bat",
|
||||
"shuffleAll": "nahastu dena",
|
||||
"shuffleSelected": "nahastu aukeratutak",
|
||||
"moveItems": "elementuak mugitu",
|
||||
"openApplicationDirectory": "ireki aplikazioaren direktorioa",
|
||||
"goToCurrent": "joan uneko elementura"
|
||||
"createPlaylist": "sortu $t(entity.playlist_one)",
|
||||
"deletePlaylist": "ezabatu $t(entity.playlist_one)",
|
||||
"addToFavorites": "gehitu $t(entity.favorite_other)-(e)ra",
|
||||
"addToPlaylist": "gehitu $t(entity.playlist_one)-(e)ra"
|
||||
},
|
||||
"common": {
|
||||
"add": "gehitu",
|
||||
@@ -54,7 +38,7 @@
|
||||
"configure": "konfiguratu",
|
||||
"confirm": "berretsi",
|
||||
"create": "sortu",
|
||||
"currentSong": "uneko $t(entity.track, {\"count\": 1})",
|
||||
"currentSong": "uneko $t(entity.track_one)",
|
||||
"decrease": "gutxitu",
|
||||
"delete": "ezabatu",
|
||||
"descending": "beheranzkoa",
|
||||
@@ -71,8 +55,7 @@
|
||||
"filter_other": "iragazkiak",
|
||||
"filters": "iragazkiak",
|
||||
"forceRestartRequired": "berreabiarazi aldaketak aplikatzeko... itxi notifikazioa berreabiarazteko",
|
||||
"setting_one": "ezarpena",
|
||||
"setting_other": "ezarpenak",
|
||||
"setting": "ezarpena",
|
||||
"share": "partekatu",
|
||||
"action_one": "ekintza",
|
||||
"action_other": "ekintzak",
|
||||
@@ -108,7 +91,7 @@
|
||||
"path": "bidea",
|
||||
"playerMustBePaused": "erreproduzitzailea pausatuta egon behar da",
|
||||
"preview": "aurrebista",
|
||||
"previousSong": "aurreko $t(entity.track, {\"count\": 1})",
|
||||
"previousSong": "aurreko $t(entity.track_one)",
|
||||
"quit": "irten",
|
||||
"random": "ausazkoa",
|
||||
"rating": "balorazioa",
|
||||
@@ -141,23 +124,7 @@
|
||||
"clean": "garbia",
|
||||
"private": "pribatua",
|
||||
"public": "publikoa",
|
||||
"releaseType": "argitalpen mota",
|
||||
"countSelected": "{{count}} hautatuta",
|
||||
"view": "ikuspegia",
|
||||
"externalLinks": "kanpoko estekak",
|
||||
"faster": "azkarrago",
|
||||
"noFilters": "ez dago iragazkirik konfiguratuta",
|
||||
"retry": "saiatu berriro",
|
||||
"slower": "motelago",
|
||||
"itemsMore": "{{count}} gehiago",
|
||||
"sort": "ordenatu",
|
||||
"recordLabel": "diskoetxea",
|
||||
"example": "adibidea",
|
||||
"tableColumns": "taulako zutabeak",
|
||||
"doNotShowAgain": "ez erakutsi hau berriro",
|
||||
"numberOfResults": "{{numberOfResults}} emaitza",
|
||||
"rename": "berrizendatu",
|
||||
"newVersionAvailable": "bertsio berri bat eskuragarri dago"
|
||||
"releaseType": "argitalpen mota"
|
||||
},
|
||||
"player": {
|
||||
"repeat": "errepikatu",
|
||||
@@ -184,53 +151,35 @@
|
||||
"queue_remove": "kendu hautatutakoak",
|
||||
"repeat_all": "errepikatu dena",
|
||||
"repeat_off": "errepikapena desgaituta",
|
||||
"shuffle": "erreproduzitu (ausaz)",
|
||||
"shuffle": "erreproduzitu ausaz",
|
||||
"shuffle_off": "auza desgaituta",
|
||||
"skip_back": "saltatu atzeraka",
|
||||
"skip_forward": "saltatu aurreraka",
|
||||
"toggleFullscreenPlayer": "txandakatu pantaila osoko erreproduzitzailea",
|
||||
"viewQueue": "ikusi ilara",
|
||||
"playbackFetchCancel": "honek denbora pixka bat behar du... itxi jakinarazpena bertan behera uzteko",
|
||||
"lyrics": "letrak",
|
||||
"restoreQueueFromServer": "berrezarri ilara zerbitzaritik",
|
||||
"saveQueueToServer": "gorde ilara zerbitzarira",
|
||||
"addLastShuffled": "azkena (ausaz)",
|
||||
"addNextShuffled": "hurrengoa (ausaz)",
|
||||
"artistRadio": "artista irratia",
|
||||
"trackRadio": "pista irratia"
|
||||
"playbackFetchCancel": "honek denbora pixka bat behar du... itxi jakinarazpena bertan behera uzteko"
|
||||
},
|
||||
"table": {
|
||||
"config": {
|
||||
"view": {
|
||||
"table": "taula",
|
||||
"list": "zerrenda",
|
||||
"grid": "sareta"
|
||||
"card": "txartela",
|
||||
"grid": "sareta",
|
||||
"poster": "kartela"
|
||||
},
|
||||
"general": {
|
||||
"gap": "$t(common.gap)",
|
||||
"size": "$t(common.size)",
|
||||
"tableColumns": "taula zutabeak",
|
||||
"itemSize": "elementuaren tamaina (px)",
|
||||
"followCurrentSong": "jarraitu uneko abestia",
|
||||
"size_default": "lehenetsia",
|
||||
"advancedSettings": "ezarpen aurreratuak",
|
||||
"autoFitColumns": "zutabeak automatikoki doitu",
|
||||
"pinToLeft": "ezkerrera finkatu",
|
||||
"pinToRight": "eskuinera finkatu",
|
||||
"alignLeft": "ezkerrean lerrokatu",
|
||||
"alignCenter": "lerrokatu erdian",
|
||||
"alignRight": "eskuinean lerrokatu",
|
||||
"itemGap": "elementuen arteko tartea (px)",
|
||||
"itemsPerRow": "elementuak errenkada bakoitzeko",
|
||||
"size_large": "handia",
|
||||
"pagination_itemsPerPage": "elementuak orrialde bakoitzeko",
|
||||
"pagination_infinite": "infinitua"
|
||||
"followCurrentSong": "jarraitu uneko abestia"
|
||||
},
|
||||
"label": {
|
||||
"actions": "$t(common.action_other)",
|
||||
"album": "$t(entity.album, {\"count\": 1})",
|
||||
"albumArtist": "$t(entity.albumArtist, {\"count\": 1})",
|
||||
"artist": "$t(entity.artist, {\"count\": 1})",
|
||||
"album": "$t(entity.album_one)",
|
||||
"albumArtist": "$t(entity.albumArtist_one)",
|
||||
"artist": "$t(entity.artist_one)",
|
||||
"biography": "$t(common.biography)",
|
||||
"bitrate": "$t(common.bitrate)",
|
||||
"bpm": "$t(common.bpm)",
|
||||
@@ -238,13 +187,13 @@
|
||||
"codec": "$t(common.codec)",
|
||||
"duration": "$t(common.duration)",
|
||||
"favorite": "$t(common.favorite)",
|
||||
"genre": "$t(entity.genre, {\"count\": 1})",
|
||||
"genre": "$t(entity.genre_one)",
|
||||
"note": "$t(common.note)",
|
||||
"owner": "$t(common.owner)",
|
||||
"path": "$t(common.path)",
|
||||
"rating": "$t(common.rating)",
|
||||
"size": "$t(common.size)",
|
||||
"songCount": "$t(entity.track, {\"count\": 2})",
|
||||
"songCount": "$t(entity.track_other)",
|
||||
"title": "$t(common.title)",
|
||||
"year": "$t(common.year)",
|
||||
"titleCombined": "$t(common.title) (batuta)",
|
||||
@@ -252,29 +201,25 @@
|
||||
"playCount": "erreprodukzio kopurua",
|
||||
"lastPlayed": "azken aldiz entzunda",
|
||||
"discNumber": "disko zenbakia",
|
||||
"dateAdded": "gehitze data",
|
||||
"albumCount": "$t(entity.album, {\"count\": 2})",
|
||||
"image": "irudia",
|
||||
"bitDepth": "$t(common.bitDepth)",
|
||||
"sampleRate": "$t(common.sampleRate)"
|
||||
"dateAdded": "gehitze data"
|
||||
}
|
||||
},
|
||||
"column": {
|
||||
"album": "albuma",
|
||||
"albumCount": "$t(entity.album, {\"count\": 2})",
|
||||
"artist": "$t(entity.artist, {\"count\": 1})",
|
||||
"albumCount": "$t(entity.album_other)",
|
||||
"artist": "$t(entity.artist_one)",
|
||||
"biography": "biografia",
|
||||
"bitrate": "bit-emaria",
|
||||
"channels": "$t(common.channel_other)",
|
||||
"codec": "$t(common.codec)",
|
||||
"discNumber": "diskoa",
|
||||
"favorite": "gogokoa",
|
||||
"genre": "$t(entity.genre, {\"count\": 1})",
|
||||
"genre": "$t(entity.genre_one)",
|
||||
"path": "bidea",
|
||||
"rating": "balorazioa",
|
||||
"releaseYear": "urtea",
|
||||
"size": "$t(common.size)",
|
||||
"songCount": "$t(entity.track, {\"count\": 2})",
|
||||
"songCount": "$t(entity.track_other)",
|
||||
"title": "tituloa",
|
||||
"trackNumber": "pista",
|
||||
"bpm": "bpm",
|
||||
@@ -283,10 +228,7 @@
|
||||
"releaseDate": "argitalpen data",
|
||||
"lastPlayed": "azken aldiz entzundakoa",
|
||||
"dateAdded": "gehitutako data",
|
||||
"albumArtist": "albumeko artista",
|
||||
"owner": "jabea",
|
||||
"bitDepth": "$t(common.bitDepth)",
|
||||
"sampleRate": "$t(common.sampleRate)"
|
||||
"albumArtist": "albumeko artista"
|
||||
}
|
||||
},
|
||||
"entity": {
|
||||
@@ -318,17 +260,13 @@
|
||||
"play_other": "{{count}} erreprodukzio",
|
||||
"playlistWithCount_one": "erreprodukzio-zerrenda {{count}}",
|
||||
"playlistWithCount_other": "{{count}} erreprodukzio-zerrenda",
|
||||
"smartPlaylist": "$t(entity.playlist, {\"count\": 1}) adimentsua",
|
||||
"smartPlaylist": "$t(entity.playlist_one) adimentsua",
|
||||
"track_one": "pista",
|
||||
"track_other": "pistak",
|
||||
"song_one": "abestia",
|
||||
"song_other": "abestiak",
|
||||
"trackWithCount_one": "pista {{count}}",
|
||||
"trackWithCount_other": "{{count}} pista",
|
||||
"radioStation_one": "irrati-katea",
|
||||
"radioStation_other": "irrati-kateak",
|
||||
"radioStationWithCount_one": "irrati-kate {{count}}",
|
||||
"radioStationWithCount_other": "{{count}} irrati-kate"
|
||||
"trackWithCount_other": "{{count}} pista"
|
||||
},
|
||||
"error": {
|
||||
"apiRouteError": "ezin izan da eskaera bideratu",
|
||||
@@ -354,15 +292,7 @@
|
||||
"badAlbum": "Orrialde hau ikusten ari zara abesti hau album batekoa ez delako. Ziurrenik arazo hau ikusten ari zara zure musika karpetaren goiko mailan abesti bat baduzu. Jellyfinek abestiak karpeta batean badaude taldekatzen ditu bakarrik",
|
||||
"loginRateError": "Saioa hasteko saiakera gehiegi egin dira, saiatu berriro segundo batzuk barru",
|
||||
"notificationDenied": "jakinarazpenetarako baimenak ukatu dira. Ezarpen honek ez du eraginik",
|
||||
"systemFontError": "errore bat gertatu da sistemaren letra-tipoak lortzen saiatzean",
|
||||
"noNetwork": "zerbitzaria ez dago erabilgarri",
|
||||
"noNetworkDescription": "ezin izan da zerbitzari honetara konektatu",
|
||||
"saveQueueFailed": "huts egin du ilara gordetzean",
|
||||
"multipleServerSaveQueueError": "erreprodukzio-ilarak zerbitzarikoak ez diren abesti bat edo gehiago ditu. hau ez da onartzen",
|
||||
"invalidJson": "JSON baliogabea",
|
||||
"playbackPausedDueToError": "erreprodukzioa eten egin da errore baten ondorioz",
|
||||
"serverLockSingleServer": "zerbitzaria blokeatuta dagoenean, zerbitzari bakarra onartzen da",
|
||||
"settingsSyncError": "desadostasunak aurkitu dira errendatzailearen ezarpenen eta prozesu nagusiaren artean. berrabiarazi aplikazioa aldaketak aplikatzeko"
|
||||
"systemFontError": "errore bat gertatu da sistemaren letra-tipoak lortzen saiatzean"
|
||||
},
|
||||
"filter": {
|
||||
"disc": "diskoa",
|
||||
@@ -376,19 +306,19 @@
|
||||
"random": "ausazkoa",
|
||||
"rating": "balorazioa",
|
||||
"trackNumber": "pista",
|
||||
"album": "$t(entity.album, {\"count\": 1})",
|
||||
"albumArtist": "$t(entity.albumArtist, {\"count\": 1})",
|
||||
"artist": "$t(entity.artist, {\"count\": 1})",
|
||||
"album": "$t(entity.album_one)",
|
||||
"albumArtist": "$t(entity.albumArtist_one)",
|
||||
"artist": "$t(entity.artist_one)",
|
||||
"biography": "biografia",
|
||||
"bitrate": "bit-emaria",
|
||||
"bpm": "bpm-ak",
|
||||
"channels": "$t(common.channel, {\"count\": 2})",
|
||||
"channels": "$t(common.channel_other)",
|
||||
"comment": "iruzkina",
|
||||
"favorited": "gogoko gisa markatua",
|
||||
"genre": "$t(entity.genre, {\"count\": 1})",
|
||||
"genre": "$t(entity.genre_one)",
|
||||
"search": "bilatu",
|
||||
"title": "tituloa",
|
||||
"albumCount": "$t(entity.album, {\"count\": 2}) kopurua",
|
||||
"albumCount": "$t(entity.album_other) kopurua",
|
||||
"communityRating": "komunitatearen balorazioa",
|
||||
"criticRating": "kritikarien balorazioa",
|
||||
"dateAdded": "gehitutako data",
|
||||
@@ -407,9 +337,7 @@
|
||||
"releaseYear": "argitalpen urtea",
|
||||
"toYear": "urtera arte",
|
||||
"fromYear": "urtetik aurrera",
|
||||
"explicitStatus": "$t(common.explicitStatus)",
|
||||
"matchAnd": "eta",
|
||||
"matchOr": "edo"
|
||||
"explicitStatus": "$t(common.explicitStatus)"
|
||||
},
|
||||
"setting": {
|
||||
"hotkey_playbackPause": "pausatu",
|
||||
@@ -417,9 +345,9 @@
|
||||
"playbackStyle_optionNormal": "normala",
|
||||
"playButtonBehavior_optionPlay": "$t(player.play)",
|
||||
"playButtonBehavior_optionPlayShuffled": "$t(player.shuffle)",
|
||||
"replayGainMode_optionAlbum": "$t(entity.album, {\"count\": 1})",
|
||||
"replayGainMode_optionAlbum": "$t(entity.album_one)",
|
||||
"replayGainMode_optionNone": "$t(common.none)",
|
||||
"replayGainMode_optionTrack": "$t(entity.track, {\"count\": 1})",
|
||||
"replayGainMode_optionTrack": "$t(entity.track_one)",
|
||||
"font": "letra-tipoa",
|
||||
"hotkey_playbackStop": "gelditu",
|
||||
"buttonSize_description": "erreproduzitzailearen barrako botoien tamaina",
|
||||
@@ -432,6 +360,7 @@
|
||||
"customCss": "css pertsonalizatua",
|
||||
"customFontPath": "letra-tipo pertsonalizatuaren bidea",
|
||||
"customFontPath_description": "aplikazioan erabiliko den letra-tipo pertsonalizatuaren bidea ezartzen du",
|
||||
"disableAutomaticUpdates": "desgaitu eguneratze automatikoak",
|
||||
"discordApplicationId": "{{discord}} aplikazioaren IDa",
|
||||
"followLyric": "jarraitu uneko letra",
|
||||
"font_description": "aplikazioan erabiliko den letra-tipoa ezartzen du",
|
||||
@@ -519,6 +448,7 @@
|
||||
"discordDisplayType_description": "zure egoeran entzuten ari zarena aldatzen du",
|
||||
"discordLinkType": "{{discord}} egoera estekak",
|
||||
"fontType_description": "barneko letra-tipoa feishinek eskaintzen dituen letra-tipoetako bat aukeratzen du. sistemaren letra-tipoa zure sistema eragileak eskaintzen duen edozein letra-tipo hautatzeko aukera ematen dizu. pertsonalizatua zure letra-tipoa eskaintzeko aukera ematen dizu",
|
||||
"genreBehavior": "genero orriaren portaera lehenetsia",
|
||||
"homeConfiguration_description": "konfiguratu zein elementu erakusten diren hasierako orrian eta zein ordenatan",
|
||||
"homeFeature": "etxeko karrusela nabarmendua",
|
||||
"homeFeature_description": "hasierako orrian karrusel nabarmen handia erakutsi behar den ala ez kontrolatzen du",
|
||||
@@ -566,6 +496,7 @@
|
||||
"accentColor": "azentu-kolorea",
|
||||
"clearCache_description": "feishinen 'garbiketa gogorra'. feishinen katxea garbitzeaz gain, hustu nabigatzailearen katxea (gordetako irudiak eta bestelako aktiboak). zerbitzari-kredentzialak eta ezarpenak gorde egiten dira",
|
||||
"clearQueryCache_description": "feishinen 'garbiketa ahula'. honek erreprodukzio-zerrendak eta pisten metadatuak freskatuko ditu eta gordetako letrak berrezarriko ditu. ezarpenak, zerbitzari-kredentzialak eta katxetutako irudiak gorde egiten dira",
|
||||
"doubleClickBehavior": "jarri ilaran bilatutako pista guztiak klik bikoitza egitean",
|
||||
"exitToTray_description": "irten aplikaziotik sistemaren erretilura",
|
||||
"followLyric_description": "mugitu letra uneko erreprodukzio-posiziora",
|
||||
"preferLocalLyrics": "nahiago izan letra lokalak",
|
||||
@@ -574,7 +505,7 @@
|
||||
"hotkey_browserForward": "nabigatzailean aurreraka",
|
||||
"imageAspectRatio": "erabili jatorrizko azaleko artearen aspektu-erlazioa",
|
||||
"lyricFetchProvider": "letrak eskuratzeko hornitzaileak",
|
||||
"lyricFetchProvider_description": "aukeratu letrak eskuratzeko hornitzaileak",
|
||||
"lyricFetchProvider_description": "aukeratu letrak eskuratzeko hornitzaileak. hornitzaileen ordena kontsultatuko diren ordena da",
|
||||
"minimizeToTray": "minimizatu erretilura",
|
||||
"minimizeToTray_description": "minimizatu aplikazioa sistemaren erretilura",
|
||||
"minimumScrobblePercentage": "scrobble iraupen minimoa (ehunekoa)",
|
||||
@@ -592,8 +523,10 @@
|
||||
"playbackStyle_description": "aukeratu audio erreproduzitzailearentzat erabiliko den erreprodukzio estiloa",
|
||||
"playButtonBehavior": "erreprodukzio botoiaren portaera",
|
||||
"playButtonBehavior_description": "ezartzen du erreprodukzio botoiaren portaera lehenetsia abestiak ilaran gehitzean",
|
||||
"playerAlbumArtResolution": "erreproduzitzailearen albumaren arte-azalaren erresoluzioa",
|
||||
"gaplessAudio": "hutsune gabeko audioa",
|
||||
"gaplessAudio_description": "ezartzen du hutsunik gabeko audio ezarpena mpv-rako",
|
||||
"genreBehavior_description": "genero batean klik egiteak abestien edo albumen zerrendan lehenespenez irekitzen den zehazten du",
|
||||
"passwordStore": "pasahitzak/biltegi sekretua",
|
||||
"playerbarOpenDrawer": "txandakatu erreproduzitzailearen barra pantaila osora",
|
||||
"playerbarOpenDrawer_description": "aukera ematen du erreproduzitzailearen barran klik egiteak pantaila osoko erreproduzitzailea irekitzeko",
|
||||
@@ -601,120 +534,11 @@
|
||||
"customCss_description": "css eduki pertsonalizatua. Oharra: edukia eta urruneko URLak debekatutako propietateak dira. Zure edukiaren aurrebista erakusten da behean. Ezarri ez dituzun eremu gehigarriak daude garbiketa dela eta",
|
||||
"enableRemote": "gaitu urruneko kontrol zerbitzaria",
|
||||
"enableRemote_description": "urruneko kontrol zerbitzariari beste gailu batzuei aplikazioa kontrolatzeko aukera ematen dio",
|
||||
"doubleClickBehavior_description": "egia bada, bilaketa batean bat datozen pista guztiak ilaran jarriko dira. bestela, klikatutakoak bakarrik jarriko dira ilaran",
|
||||
"imageAspectRatio_description": "gaituta badago, azaleko artea jatorrizko aspektu-erlazioa erabiliz erakutsiko da. 1:1 ez den arterako, gainerako espazioa hutsik egongo da",
|
||||
"crossfadeStyle": "crossfade estiloa",
|
||||
"discordRichPresence": "{{discord}}-en jarduera-egoera",
|
||||
"enableAutoTranslation": "gaitu itzulpen automatikoa",
|
||||
"exportImportSettings_control_exportText": "esportatu ezarpenak",
|
||||
"exportImportSettings_control_importText": "inportatu ezarpenak",
|
||||
"exportImportSettings_control_title": "inportatu / esportatu ezarpenak",
|
||||
"exportImportSettings_importBtn": "inportatu ezarpenak",
|
||||
"exportImportSettings_importModalTitle": "inportatu feishin ezarpenak",
|
||||
"autoDJ_itemCount": "elementu kopurua",
|
||||
"language": "hizkuntza",
|
||||
"queryBuilderCustomFields_inputTag": "etiketa",
|
||||
"logLevel_optionError": "errore bat",
|
||||
"logLevel_optionInfo": "informazioa",
|
||||
"imageResolution_optionTable": "taula",
|
||||
"imageResolution_optionSidebar": "alboko barra",
|
||||
"replayGainClipping": "{{ReplayGain}} mozketa",
|
||||
"replayGainFallback": "{{ReplayGain}} ordezko aukera",
|
||||
"trayEnabled": "erakutsi erretilua",
|
||||
"artistReleaseTypeConfiguration": "artistaren argitalpen motaren konfigurazioa",
|
||||
"artistReleaseTypeConfiguration_description": "konfiguratu zein argitalpen mota erakusten diren, eta zein ordenatan, albumaren artistaren orrian",
|
||||
"useThemeAccentColor": "erabili gaiaren azentu-kolorea",
|
||||
"useThemeAccentColor_description": "erabili hautatutako gaian definitutako kolore nagusia azentu-kolore pertsonalizatuaren ordez",
|
||||
"showRatings": "erakutsi izarren balorazioak",
|
||||
"showRatings_description": "izarren balorazioen funtzioa interfazean agertzen den ala ez kontrolatzen du",
|
||||
"imageResolution": "irudiaren erresoluzioa",
|
||||
"imageResolution_description": "aplikazioan erabilitako irudien erresoluzioa. 0 balioa erabiliz gero, jatorrizko irudiaren erresoluzioa erabiliko da lehenespenez",
|
||||
"followCurrentSong_description": "automatikoki korritu erreprodukzio-ilara uneko abestira",
|
||||
"followCurrentSong": "jarraitu uneko abestia",
|
||||
"lyricOffset_description": "letra zehaztutako milisegundo kopuruarekin desplazatu",
|
||||
"lyricOffset": "letraren desplazamendua (ms)",
|
||||
"mpvExtraParameters": "mpv parametro gehigarriak",
|
||||
"mpvExtraParameters_description": "mpv-ri pasatzeko argumentu gehigarriak",
|
||||
"notify": "abestien jakinarazpenak gaitu",
|
||||
"notify_description": "erakutsi jakinarazpenak uneko abestia aldatzean",
|
||||
"pathReplace": "fitxategiaren bidearen ordezkapena",
|
||||
"pathReplace_description": "ordezkatu zure zerbitzariaren fitxategi-bide lehenetsia",
|
||||
"pathReplace_optionRemovePrefix": "kendu aurrizkia",
|
||||
"pathReplace_optionAddPrefix": "gehitu aurrizkia",
|
||||
"passwordStore_description": "zein pasahitz/sekretu biltegi erabili. aldatu hau pasahitzak gordetzeko arazoak badituzu",
|
||||
"playerFilters": "Iragazi ilarako abestiak",
|
||||
"sidePlayQueueStyle_description": "alboko erreprodukzio-ilararen estiloa ezartzen du",
|
||||
"mediaSession_description": "Windows Media Session integrazioa gaitzen du, multimedia kontrolak eta metadatuak sistemaren bolumenaren gainjartzean eta blokeo pantailan bistaratuz (Windows bakarrik)",
|
||||
"sidePlayQueueStyle": "alboko erreprodukzio-ilarako estiloa",
|
||||
"skipPlaylistPage": "saltatu erreprodukzio-zerrenda orria",
|
||||
"startMinimized_description": "abiarazi aplikazioa sistemaren erretiluan",
|
||||
"startMinimized": "hasi minimizatuta",
|
||||
"transcode": "gaitu transkodetzea",
|
||||
"transcode_description": "formatu ezberdinetara transkodetzea ahalbidetzen du",
|
||||
"transcodeBitrate_description": "transkodetzeko bit-emaria hautatzen du. 0k zerbitzariari aukeratzen uzten diola esan nahi du",
|
||||
"transcodeBitrate": "transkodetzeko bit-emaria",
|
||||
"transcodeFormat_description": "transkodetzeko formatua hautatzen du. utzi hutsik zerbitzariak erabaki dezan",
|
||||
"transcodeFormat": "transkodetzeko formatua",
|
||||
"queryBuilderCustomFields_inputLabel": "etiketa",
|
||||
"autoDJ": "DJ automatikoa",
|
||||
"autoDJ_description": "automatikoki gehitu antzeko abestiak ilaran",
|
||||
"autoDJ_itemCount_description": "DJ automatikoa gaituta dagoenean ilaran gehitzen saiatu diren elementuen kopurua",
|
||||
"autoDJ_timing_description": "DJ automatikoa aktibatu aurretik ilaran geratzen diren abestien kopurua",
|
||||
"analyticsDisable": "Erabileran oinarritutako analisiei uko egin",
|
||||
"analyticsDisable_description": "Erabilera-datu anonimoak garatzaileari bidaltzen zaizkio aplikazioa hobetzen laguntzeko",
|
||||
"contextMenu_description": "elementu batean eskuineko botoiarekin klik egitean menuan agertzen diren elementuak ezkutatzeko aukera ematen dizu. hautatuta ez dauden elementuak ezkutatuta egongo dira",
|
||||
"enableAutoTranslation_description": "Gaitu itzulpena automatikoki letra kargatzen denean",
|
||||
"exportImportSettings_control_description": "JSON bidez ezarpenak esportatu eta inportatu",
|
||||
"exportImportSettings_destructiveWarning": "Ezarpenak inportatzea arriskutsua da, mesedez, berrikusi goikoa beheko \"inportatu\" klikatu aurretik!",
|
||||
"exportImportSettings_importSuccess": "ezarpenak behar bezala inportatu dira!",
|
||||
"exportImportSettings_offendingKeyError": "\"{{offendingKey}}\" okerra da - {{reason}}",
|
||||
"hotkey_listPlayDefault": "zerrenda erreproduzitu",
|
||||
"hotkey_listPlayLast": "zerrenda erreproduzitu amaieran",
|
||||
"hotkey_listPlayNow": "zerrenda erreproduzitu orain",
|
||||
"logLevel": "erregistro maila",
|
||||
"logLevel_description": "Bistaratzeko erregistroen gutxieneko maila ezartzen du. Debug-ek erregistro guztiak erakusten ditu, «erroreak» erroreak bakarrik erakusten ditu",
|
||||
"logLevel_optionDebug": "arazketa",
|
||||
"playerFilters_description": "saltatu abestiak ilaran gehitzea irizpide hauen arabera",
|
||||
"artistRadioCount_description": "artista eta abestien irratian bilatu beharreko abesti kopurua ezartzen du",
|
||||
"artistRadioCount": "artista/abesti irratiko kopurua",
|
||||
"imageResolution_optionItemCard": "elementu txartela",
|
||||
"imageResolution_optionHeader": "goiburua",
|
||||
"imageResolution_optionFullScreenPlayer": "pantaila osoko erreproduzitzailea",
|
||||
"showVisualizerInSidebar": "erakutsi bistaratzailea erreproduzitzailearen alboko barran",
|
||||
"combinedLyricsAndVisualizer_description": "konbinatu letrak eta bistaratzailea panel berean",
|
||||
"combinedLyricsAndVisualizer": "konbinatu letrak eta bistaratzailea erreproduzitzailearen alboko barran",
|
||||
"preventSleepOnPlayback_description": "saihestu pantaila lotan jartzea musika erreproduzitzen ari den bitartean",
|
||||
"remotePassword_description": "urruneko kontrol zerbitzariaren pasahitza ezartzen du. Kredentzial hauek modu ez-seguruan transferitzen dira lehenespenez, beraz, axola ez zaizun pasahitz bakarra erabili beharko zenuke",
|
||||
"remotePassword": "urruneko kontrol zerbitzariaren pasahitza",
|
||||
"remotePort_description": "urruneko kontrol zerbitzariaren portua ezartzen du",
|
||||
"remotePort": "urruneko kontrol zerbitzariaren ataka",
|
||||
"remoteUsername_description": "urruneko kontrol zerbitzariaren erabiltzaile-izena ezartzen du. Erabiltzaile-izena eta pasahitza hutsik badaude, autentifikazioa desgaituta egongo da",
|
||||
"remoteUsername": "urruneko kontrol zerbitzariaren erabiltzaile-izena",
|
||||
"logLevel_optionWarn": "abisua",
|
||||
"qobuz_description": "erakutsi Qobuz-erako estekak artista/album orrialdeetan",
|
||||
"qobuz": "erakutsi Qobuz-erako estekak",
|
||||
"spotify_description": "erakutsi Spotify-rako estekak artista/album orrialdeetan",
|
||||
"spotify": "erakutsi Spotify-rako estekak",
|
||||
"nativeSpotify_description": "ireki Spotify aplikazioan, arakatzailearen ordez",
|
||||
"nativeSpotify": "erabili Spotify aplikazioa",
|
||||
"playerbarSlider_description": "uhin-forma ez da gomendagarria interneteko konexio motela edo neurtua baduzu",
|
||||
"playerbarSliderType_optionWaveform": "uhin-forma",
|
||||
"playerbarWaveformAlign": "uhin-formaren lerrokatzea",
|
||||
"playerbarWaveformAlign_optionTop": "nagusia",
|
||||
"playerbarWaveformBarWidth": "uhin-formako barraren zabalera",
|
||||
"playerbarWaveformGap": "uhin-formaren tartea",
|
||||
"playerbarWaveformRadius": "uhin-formaren erradioa",
|
||||
"showLyricsInSidebar_description": "letrak erakusten dituen panel bat gehituko da erantsitako erreprodukzio-ilaran",
|
||||
"showLyricsInSidebar": "erakutsi letra erreproduzitzailearen alboko barran",
|
||||
"blurExplicitImages": "irudi esplizituak lausotu",
|
||||
"blurExplicitImages_description": "esplizitu gisa etiketatutako albumaren eta abestiaren azalak lausotuta agertuko dira",
|
||||
"enableGridMultiSelect": "gaitu sareta anitzeko hautaketa",
|
||||
"enableGridMultiSelect_description": "gaituta dagoenean, sareta-ikuspegietan hainbat elementu hautatzea ahalbidetzen du. desgaituta dagoenean, sareta-elementuen irudietan klik egitean elementuaren orrialdera nabigatuko da",
|
||||
"showVisualizerInSidebar_description": "bistaratzailea erakusten duen panel bat gehituko da erreproduzitzailearen alboko barran",
|
||||
"preservePitch_description": "erreprodukzio-abiadura aldatzean tonua mantentzen du",
|
||||
"preservePitch": "mantendu tonua",
|
||||
"preventSleepOnPlayback": "erreprodukzioan loa saihestu",
|
||||
"replayGainClipping_description": "Saihestu {{ReplayGain}}-k eragindako mozketa irabazpena automatikoki jaitsiz",
|
||||
"replayGainMode_description": "doitu bolumenaren irabazia fitxategiaren metadatuetan gordetako {{ReplayGain}} balioen arabera"
|
||||
"enableAutoTranslation": "gaitu itzulpen automatikoa"
|
||||
},
|
||||
"form": {
|
||||
"addServer": {
|
||||
@@ -730,27 +554,26 @@
|
||||
"input_legacyAuthentication": "gaitu zaharkitutako autentifikazioa",
|
||||
"success": "zerbitzaria behar bezala gehitu da",
|
||||
"input_preferInstantMix": "nahiago izan berehalako nahasketa",
|
||||
"input_preferInstantMixDescription": "erabili berehalako nahasketa soilik antzeko abestiak lortzeko. erabilgarria portaera hau aldatzen duten pluginak badituzu",
|
||||
"input_remoteUrl": "URL publikoa"
|
||||
"input_preferInstantMixDescription": "erabili berehalako nahasketa soilik antzeko abestiak lortzeko. erabilgarria portaera hau aldatzen duten pluginak badituzu"
|
||||
},
|
||||
"addToPlaylist": {
|
||||
"input_playlists": "$t(entity.playlist, {\"count\": 2})",
|
||||
"input_playlists": "$t(entity.playlist_other)",
|
||||
"success": "$t(entity.trackWithCount, {\"count\": {{message}} }) gehitu da $t(entity.playlistWithCount, {\"count\": {{numOfPlaylists}} })-ra",
|
||||
"input_skipDuplicates": "saltatu bikoiztuak",
|
||||
"title": "gehitu $t(entity.playlist, {\"count\": 1})-(a)ri",
|
||||
"create": "sortu $t(entity.playlist, {\"count\": 1}) {{playlist}}",
|
||||
"searchOrCreate": "bilatu $t(entity.playlist, {\"count\": 2}) edo idatzi berri bat sortzeko"
|
||||
"title": "gehitu $t(entity.playlist_one)-(a)ri",
|
||||
"create": "sortu $t(entity.playlist_one) {{playlist}}",
|
||||
"searchOrCreate": "bilatu $t(entity.playlist_other) edo idatzi berri bat sortzeko"
|
||||
},
|
||||
"createPlaylist": {
|
||||
"input_description": "$t(common.description)",
|
||||
"input_name": "$t(common.name)",
|
||||
"input_owner": "$t(common.owner)",
|
||||
"input_public": "publikoa",
|
||||
"title": "$t(entity.playlist, {\"count\": 1}) sortu",
|
||||
"success": "$t(entity.playlist, {\"count\": 1}) behar bezala sortu da"
|
||||
"title": "$t(entity.playlist_one) sortu",
|
||||
"success": "$t(entity.playlist_one) behar bezala sortu da"
|
||||
},
|
||||
"lyricSearch": {
|
||||
"input_artist": "$t(entity.artist, {\"count\": 1})",
|
||||
"input_artist": "$t(entity.artist_one)",
|
||||
"input_name": "$t(common.name)",
|
||||
"title": "letra bilatu"
|
||||
},
|
||||
@@ -763,23 +586,19 @@
|
||||
"createFailed": "partekatzea sortzeak huts egin du (partekatzea gaituta al dago?)"
|
||||
},
|
||||
"deletePlaylist": {
|
||||
"success": "$t(entity.playlist, {\"count\": 1}) behar bezala ezabatu da",
|
||||
"title": "$t(entity.playlist, {\"count\": 1}) ezabatu",
|
||||
"input_confirm": "idatzi $t(entity.playlist, {\"count\": 1})-(a)ren izena berresteko"
|
||||
"success": "$t(entity.playlist_one) behar bezala ezabatu da",
|
||||
"title": "$t(entity.playlist_one) ezabatu",
|
||||
"input_confirm": "idatzi $t(entity.playlist_one)-(a)ren izena berresteko"
|
||||
},
|
||||
"editPlaylist": {
|
||||
"success": "$t(entity.playlist, {\"count\": 1}) behar bezala eguneratu da",
|
||||
"title": "$t(entity.playlist, {\"count\": 1}) editatu",
|
||||
"success": "$t(entity.playlist_one) behar bezala eguneratu da",
|
||||
"title": "$t(entity.playlist_one) editatu",
|
||||
"publicJellyfinNote": "Arrazoiren batengatik, Jellyfin ez du erakusten erreprodukzio-zerrendak publikoak diren edo ez. Hau publiko izaten jarraitzea nahi baduzu, hautatu sarrera hau"
|
||||
},
|
||||
"queryEditor": {
|
||||
"title": "kontsulta editorea",
|
||||
"input_optionMatchAll": "guztiak bat etorri",
|
||||
"input_optionMatchAny": "edozeinekin bat etorri",
|
||||
"resetToDefault": "lehenetsitako egoerara berrezarri",
|
||||
"clearFilters": "garbitu iragazkiak",
|
||||
"addRuleGroup": "gehitu arau-taldea",
|
||||
"removeRuleGroup": "kendu arau-taldea"
|
||||
"input_optionMatchAny": "edozeinekin bat etorri"
|
||||
},
|
||||
"updateServer": {
|
||||
"success": "zerbitzaria behar bezala eguneratu da",
|
||||
@@ -789,51 +608,25 @@
|
||||
"title": "modu pribatua",
|
||||
"enabled": "modu pribatua gaituta, erreprodukzio egoera kanpoko integrazioetatik ezkutatuta dago orain",
|
||||
"disabled": "modu pribatua desgaituta, erreprodukzio egoera ikusgai dago orain gaitutako kanpoko integrazioentzat"
|
||||
},
|
||||
"largeFetchConfirmation": {
|
||||
"title": "gehitu elementuak ilaran",
|
||||
"description": "Ekintza honek uneko iragazki-ikuspegian dauden elementu guztiak gehituko ditu"
|
||||
},
|
||||
"createRadioStation": {
|
||||
"input_homepageUrl": "hasierako orriaren URLa",
|
||||
"input_name": "izena",
|
||||
"title": "irrati-katea sortu",
|
||||
"success": "irrati-katea behar bezala sortu da"
|
||||
},
|
||||
"lyricsExport": {
|
||||
"export": "esportatu letrak",
|
||||
"input_synced": "esportatu sinkronizatutako letrak",
|
||||
"input_offset": "$t(setting.lyricOffset)"
|
||||
},
|
||||
"shuffleAll": {
|
||||
"input_genre": "$t(entity.genre, {\"count\": 1})",
|
||||
"title": "ausaz erreproduzitu",
|
||||
"input_limit": "zenbat abesti?",
|
||||
"input_played_optionAll": "pista guztiak",
|
||||
"input_played_optionUnplayed": "erreproduzitu gabeko pistak bakarrik",
|
||||
"input_played_optionPlayed": "erreproduzitutako pistak bakarrik"
|
||||
},
|
||||
"saveQueue": {
|
||||
"success": "erreprodukzio-ilara zerbitzarian gordeta"
|
||||
}
|
||||
},
|
||||
"page": {
|
||||
"albumArtistList": {
|
||||
"title": "$t(entity.albumArtist, {\"count\": 2})"
|
||||
"title": "$t(entity.albumArtist_other)"
|
||||
},
|
||||
"albumDetail": {
|
||||
"released": "argitaratuta",
|
||||
"moreFromArtist": "$t(entity.artist, {\"count\": 1}) honetatik gehiago",
|
||||
"moreFromArtist": "$t(entity.artist_one) honetatik gehiago",
|
||||
"moreFromGeneric": "{{item}}-(e)tik gehiago"
|
||||
},
|
||||
"albumList": {
|
||||
"title": "$t(entity.album, {\"count\": 2})",
|
||||
"genreAlbums": "\"{{genre}}\" $t(entity.album, {\"count\": 2})",
|
||||
"title": "$t(entity.album_other)",
|
||||
"genreAlbums": "\"{{genre}}\" $t(entity.album_other)",
|
||||
"artistAlbums": "{{artist}}-(a)ren albumak"
|
||||
},
|
||||
"appMenu": {
|
||||
"quit": "$t(common.quit)",
|
||||
"settings": "$t(common.setting, {\"count\": 2})",
|
||||
"settings": "$t(common.setting_other)",
|
||||
"collapseSidebar": "tolestu alboko barra",
|
||||
"expandSidebar": "zabaldu alboko barra",
|
||||
"goBack": "atzera",
|
||||
@@ -843,11 +636,7 @@
|
||||
"privateModeOn": "aktibatu modu pribatua",
|
||||
"selectServer": "aukeratu zerbitzaria",
|
||||
"version": "bertsioa {{version}}",
|
||||
"openBrowserDevtools": "ireki nabigatzailearen garapen tresnak",
|
||||
"commandPalette": "ireki komando-paleta",
|
||||
"noMusicFolder": "ez da musika karpetarik hautatu",
|
||||
"selectMusicFolder": "aukeratu musika karpeta",
|
||||
"multipleMusicFolders": "{{count}} musika karpeta aukeratuta"
|
||||
"openBrowserDevtools": "ireki nabigatzailearen garapen tresnak"
|
||||
},
|
||||
"manageServers": {
|
||||
"url": "URLa",
|
||||
@@ -879,10 +668,9 @@
|
||||
"playShuffled": "$t(player.shuffle)",
|
||||
"numberSelected": "{{count}} hautatuta",
|
||||
"shareItem": "partekatu elementua",
|
||||
"goToAlbum": "joan $t(entity.album, {\"count\": 1})-(e)ra",
|
||||
"goToAlbum": "joan $t(entity.album_one)-(e)ra",
|
||||
"goToAlbumArtist": "joan albumera",
|
||||
"showDetails": "informazioa lortu",
|
||||
"moveItems": "$t(action.moveItems)"
|
||||
"showDetails": "informazioa lortu"
|
||||
},
|
||||
"fullscreenPlayer": {
|
||||
"config": {
|
||||
@@ -908,9 +696,9 @@
|
||||
"noLyrics": "ez da letrarik aurkitu"
|
||||
},
|
||||
"genreList": {
|
||||
"title": "$t(entity.genre, {\"count\": 2})",
|
||||
"showAlbums": "erakutsi $t(entity.genre, {\"count\": 1}) $t(entity.album, {\"count\": 2})",
|
||||
"showTracks": "erakutsi $t(entity.genre, {\"count\": 1}) $t(entity.track, {\"count\": 2})"
|
||||
"title": "$t(entity.genre_other)",
|
||||
"showAlbums": "erakutsi $t(entity.genre_one) $t(entity.album_other)",
|
||||
"showTracks": "erakutsi $t(entity.genre_one) $t(entity.track_other)"
|
||||
},
|
||||
"globalSearch": {
|
||||
"title": "komandoak",
|
||||
@@ -926,69 +714,48 @@
|
||||
"newlyAdded": "azken aldian gehitutako argitalpenak",
|
||||
"recentlyPlayed": "azken aldian entzundakoak",
|
||||
"recentlyReleased": "azken aldian argitaratutak",
|
||||
"explore": "arakatu zure liburutegitik",
|
||||
"genres": "$t(entity.genre, {\"count\": 2})"
|
||||
"explore": "arakatu zure liburutegitik"
|
||||
},
|
||||
"playlistList": {
|
||||
"title": "$t(entity.playlist, {\"count\": 2})"
|
||||
"title": "$t(entity.playlist_other)"
|
||||
},
|
||||
"setting": {
|
||||
"advanced": "aurreratua",
|
||||
"generalTab": "orokorra",
|
||||
"playbackTab": "erreprodukzioa",
|
||||
"windowTab": "leihoa",
|
||||
"hotkeysTab": "laster-teklak",
|
||||
"cache": "katxea",
|
||||
"application": "aplikazioa",
|
||||
"theme": "gaia",
|
||||
"sidebar": "alboko barra",
|
||||
"exportImport": "inportatu/esportatu",
|
||||
"scrobble": "scrobble",
|
||||
"audio": "audioa",
|
||||
"lyrics": "letrak",
|
||||
"discord": "discord",
|
||||
"playerFilters": "erreproduzitzailearen iragazkiak",
|
||||
"updates": "eguneraketa",
|
||||
"queryBuilder": "kontsulta-sortzailea",
|
||||
"controls": "kontrolak",
|
||||
"remote": "urrunekoa",
|
||||
"lyricsDisplay": "erakutsi letrak"
|
||||
"hotkeysTab": "laster-teklak"
|
||||
},
|
||||
"sidebar": {
|
||||
"albumArtists": "$t(entity.albumArtist, {\"count\": 2})",
|
||||
"albums": "$t(entity.album, {\"count\": 2})",
|
||||
"artists": "$t(entity.artist, {\"count\": 2})",
|
||||
"folders": "$t(entity.folder, {\"count\": 2})",
|
||||
"genres": "$t(entity.genre, {\"count\": 2})",
|
||||
"albumArtists": "$t(entity.albumArtist_other)",
|
||||
"albums": "$t(entity.album_other)",
|
||||
"artists": "$t(entity.artist_other)",
|
||||
"folders": "$t(entity.folder_other)",
|
||||
"genres": "$t(entity.genre_other)",
|
||||
"home": "$t(common.home)",
|
||||
"playlists": "$t(entity.playlist, {\"count\": 2})",
|
||||
"playlists": "$t(entity.playlist_other)",
|
||||
"search": "$t(common.search)",
|
||||
"settings": "$t(common.setting, {\"count\": 2})",
|
||||
"tracks": "$t(entity.track, {\"count\": 2})",
|
||||
"settings": "$t(common.setting_other)",
|
||||
"tracks": "$t(entity.track_other)",
|
||||
"myLibrary": "nire liburutegia",
|
||||
"nowPlaying": "orain erreproduzitzen",
|
||||
"shared": "partekatutako $t(entity.playlist, {\"count\": 2})",
|
||||
"favorites": "$t(entity.favorite, {\"count\": 2})",
|
||||
"radio": "$t(entity.radioStation, {\"count\": 2})",
|
||||
"collections": "bildumak"
|
||||
"shared": "partekatutako $t(entity.playlist_other)"
|
||||
},
|
||||
"trackList": {
|
||||
"title": "$t(entity.track, {\"count\": 2})",
|
||||
"genreTracks": "\"{{genre}}\" $t(entity.track, {\"count\": 2})",
|
||||
"title": "$t(entity.track_other)",
|
||||
"genreTracks": "\"{{genre}}\" $t(entity.track_other)",
|
||||
"artistTracks": "{{artist}}-(r)en abestiak"
|
||||
},
|
||||
"albumArtistDetail": {
|
||||
"about": "{{artist}}-(r)i buruz",
|
||||
"relatedArtists": "erlazionatutako $t(entity.artist, {\"count\": 2})",
|
||||
"relatedArtists": "erlazionatutako $t(entity.artist_other)",
|
||||
"topSongs": "abesti nagusiak",
|
||||
"topSongsFrom": "{{title}}-(a)ren abesti nagusiak",
|
||||
"viewAll": "ikusi guztiak",
|
||||
"viewAllTracks": "ikusi $t(entity.track, {\"count\": 2}) guztiak",
|
||||
"viewAllTracks": "ikusi $t(entity.track_other) guztiak",
|
||||
"appearsOn": "agertzen da hemen",
|
||||
"recentReleases": "azken argitalpenak",
|
||||
"viewDiscography": "ikusi diskografia",
|
||||
"groupingTypeAll": "argitalpen mota guztiak",
|
||||
"groupingTypePrimary": "argitalpen mota nagusiak"
|
||||
"viewDiscography": "ikusi diskografia"
|
||||
},
|
||||
"itemDetail": {
|
||||
"copyPath": "kopiatu bidea arbelean",
|
||||
@@ -997,168 +764,14 @@
|
||||
},
|
||||
"playlist": {
|
||||
"reorder": "berrantolaketa IDaren arabera ordenatzean bakarrik gaituta dago"
|
||||
},
|
||||
"folderList": {
|
||||
"title": "$t(entity.folder, {\"count\": 2})"
|
||||
},
|
||||
"favorites": {
|
||||
"title": "$t(entity.favorite, {\"count\": 2})"
|
||||
},
|
||||
"radioList": {
|
||||
"title": "irrati-kateak"
|
||||
}
|
||||
},
|
||||
"releaseType": {
|
||||
"primary": {
|
||||
"album": "$t(entity.album, {\"count\": 1})",
|
||||
"other": "bestelakoa",
|
||||
"ep": "ep"
|
||||
"album": "$t(entity.album_one)"
|
||||
},
|
||||
"secondary": {
|
||||
"compilation": "konpilazioa",
|
||||
"audiobook": "audioliburua",
|
||||
"interview": "elkarrizketa",
|
||||
"remix": "nahasketa",
|
||||
"djMix": "dj nahasketa"
|
||||
"compilation": "konpilazioa"
|
||||
}
|
||||
},
|
||||
"datetime": {
|
||||
"minuteShort": "m",
|
||||
"secondShort": "s",
|
||||
"hourShort": "h",
|
||||
"dayShort": "d"
|
||||
},
|
||||
"queryBuilder": {
|
||||
"customTags": "etiketa pertsonalizatutak",
|
||||
"standardTags": "etiketa estandarrak"
|
||||
},
|
||||
"filterOperator": {
|
||||
"is": "da",
|
||||
"contains": "dauka",
|
||||
"notContains": "ez dauka",
|
||||
"startsWith": "honekin hasten da",
|
||||
"endsWith": "honekin amaitzen da",
|
||||
"isNot": "ez da"
|
||||
},
|
||||
"visualizer": {
|
||||
"general": "Orokorra",
|
||||
"mode": "Modua",
|
||||
"vertical": "Bertikala",
|
||||
"horizontal": "Horizontala",
|
||||
"position": "Posizioa",
|
||||
"level": "Maila",
|
||||
"remove": "Kendu",
|
||||
"custom": "Pertsonalizatua",
|
||||
"builtIn": "Barneratua",
|
||||
"colors": "Koloreak",
|
||||
"gradient": "Gradientea",
|
||||
"fft": "FFT",
|
||||
"sensitivity": "Sentikortasuna",
|
||||
"smoothing": "Leuntzea",
|
||||
"gravity": "Grabitatea",
|
||||
"radial": "Erradiala",
|
||||
"radius": "Erradioa",
|
||||
"mirror": "Ispilua",
|
||||
"options": {
|
||||
"colorMode": {
|
||||
"gradient": "Gradientea",
|
||||
"barIndex": "Barra-indizea",
|
||||
"barLevel": "Barra-maila"
|
||||
},
|
||||
"gradient": {
|
||||
"classic": "Klasikoa",
|
||||
"prism": "Prisma",
|
||||
"rainbow": "Ostadarra",
|
||||
"orangered": "Laranja-gorria"
|
||||
},
|
||||
"weightingFilter": {
|
||||
"none": "Bat ere ez",
|
||||
"a": "A",
|
||||
"b": "B",
|
||||
"c": "C",
|
||||
"d": "D",
|
||||
"z": "Z"
|
||||
},
|
||||
"mode": {
|
||||
"0": "[0] Maiztasun Diskretuak",
|
||||
"1": "[1] 1/24 oktaba / 240 banda",
|
||||
"2": "[2] 1/12 oktaba / 120 banda",
|
||||
"3": "[3] 1/8 oktaba / 80 banda",
|
||||
"4": "[4] 1/6ko oktaba / 60 banda",
|
||||
"5": "[5] 1/4 oktaba / 40 banda",
|
||||
"6": "[6] 1/3 oktaba / 30 banda",
|
||||
"7": "[7] Oktaba erdi / 20 banda",
|
||||
"8": "[8] Oktaba osoa / 10 banda",
|
||||
"10": "[10] Lerroa / Azalera grafikoa"
|
||||
},
|
||||
"frequencyScale": {
|
||||
"none": "Bat ere ez",
|
||||
"linear": "Eskala Lineala",
|
||||
"bark": "Bark Eskala",
|
||||
"mel": "Mel Eskala"
|
||||
}
|
||||
},
|
||||
"opacity": "Opakotasuna",
|
||||
"minimumFrequency": "Gutxieneko Maiztasuna",
|
||||
"maximumFrequency": "Gehienezko Maiztasuna",
|
||||
"frequencyScale": "Maiztasun Eskala",
|
||||
"weightingFilter": "Ponderazio-iragazkia",
|
||||
"minimumDecibels": "Gutxieneko Dezibelioak",
|
||||
"maximumDecibels": "Gehienezko Dezibelioak",
|
||||
"linearAmplitude": "Anplitude Lineala",
|
||||
"linearBoost": "Bultzada Lineala",
|
||||
"showPeaks": "Erakutsi Gailurrak",
|
||||
"configCopied": "Konfigurazioa arbelean kopiatu da",
|
||||
"configCopyFailed": "Konfigurazioa kopiatzeak huts egin du",
|
||||
"configPasted": "Konfigurazioa behar bezala aplikatu da",
|
||||
"configPasteFailed": "Konfigurazioa aplikatzeak huts egin du. Mesedez, egiaztatu formatua.",
|
||||
"configPasteReadFailed": "Arbelatik irakurtzeak huts egin du",
|
||||
"colorMode": "Kolore Modua",
|
||||
"fftSize": "FFT tamaina",
|
||||
"frequencyRangeAndScaling": "Maiztasun-tartea eta eskalatzea",
|
||||
"showScaleY": "Erakutsi Y Eskala",
|
||||
"pasteGradientPlaceholder": "Itsatsi JSON gradientea hemen...",
|
||||
"pasteGradient": "Itsatsi Gradientea",
|
||||
"addColor": "Gehitu Kolorea",
|
||||
"colorStops": "Kolore Geldialdiak",
|
||||
"gradientNamePlaceholder": "Gradientearen Izena",
|
||||
"gradientName": "Gradientearen Izena",
|
||||
"addCustomGradient": "Gehitu Gradiente Pertsonalizatua",
|
||||
"customGradients": "Gradiente Pertsonalizatuak",
|
||||
"maxFPS": "FPS maximoak",
|
||||
"channelLayout": "Kanalaren Diseinua",
|
||||
"lineWidth": "Lerroaren Zabalera",
|
||||
"presetNamePlaceholder": "Sartu aurrezarpenaren izena",
|
||||
"presetName": "Aurrezarpenaren Izena",
|
||||
"applyConfiguration": "Aplikatu konfigurazioa",
|
||||
"pasteFromClipboard": "Itsatsi Arbeletik",
|
||||
"pasteConfigurationPlaceholder": "Itsatsi JSON konfigurazioa hemen...",
|
||||
"pasteConfiguration": "Itsatsi Konfigurazioa",
|
||||
"copyConfiguration": "Kopiatu Konfigurazioa",
|
||||
"updatePreset": "Aurrezarpena Eguneratu",
|
||||
"saveAsPreset": "Aurrezarpen gisa gorde",
|
||||
"applyPreset": "Aurrezarpena Aplikatu",
|
||||
"selectPreset": "Aukeratu Aurrezarpena",
|
||||
"presets": "Aurrezarpenak",
|
||||
"visualizerType": "Bistaratzaile Mota",
|
||||
"cycleTime": "Zikloaren denbora (segundoak)",
|
||||
"includeAllPresets": "Aurrezarpen guztiak sartu",
|
||||
"ignoredPresets": "Aurrezarpen baztertuak",
|
||||
"selectedPresets": "Hautatutako aurrezarpenak",
|
||||
"mode1To8": "1 - 8 modua",
|
||||
"mode10": "10 modua",
|
||||
"gradientLeft": "Gradientearen ezkerra",
|
||||
"gradientRight": "Gradientearen eskuina",
|
||||
"peakBehavior": "Gailurraren Portaera",
|
||||
"peakLine": "Gailurraren lerroa",
|
||||
"miscellaneousSettings": "Hainbat ezarpen",
|
||||
"alphaBars": "Alfa barrak",
|
||||
"ansiBands": "ANSI bandak",
|
||||
"ledBars": "LED barrak",
|
||||
"trueLeds": "True LED-ak",
|
||||
"roundBars": "Barra biribilduak",
|
||||
"lowResolution": "Erresoluzio baxua",
|
||||
"showFPS": "Erakutsi FPS",
|
||||
"showScaleX": "Erakutsi X eskala"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,23 +33,23 @@
|
||||
"muted": "بیصدا"
|
||||
},
|
||||
"action": {
|
||||
"editPlaylist": "ویرایش $t(entity.playlist, {\"count\": 1})",
|
||||
"editPlaylist": "ویرایش $t(entity.playlist_one)",
|
||||
"goToPage": "برو به صفحهٔ",
|
||||
"moveToTop": "انتقال به بالا",
|
||||
"clearQueue": "خالی کردن صف",
|
||||
"addToFavorites": "افزودن به $t(entity.favorite, {\"count\": 2})",
|
||||
"addToPlaylist": "افزودن به $t(entity.playlist, {\"count\": 1})",
|
||||
"createPlaylist": "ساخت $t(entity.playlist, {\"count\": 1})",
|
||||
"removeFromPlaylist": "حذف از $t(entity.playlist, {\"count\": 1})",
|
||||
"viewPlaylists": "نمایش $t(entity.playlist, {\"count\": 2})",
|
||||
"addToFavorites": "افزودن به $t(entity.favorite_other)",
|
||||
"addToPlaylist": "افزودن به $t(entity.playlist_one)",
|
||||
"createPlaylist": "ساخت $t(entity.playlist_one)",
|
||||
"removeFromPlaylist": "حذف از $t(entity.playlist_one)",
|
||||
"viewPlaylists": "نمایش $t(entity.playlist_other)",
|
||||
"refresh": "$t(common.refresh)",
|
||||
"deletePlaylist": "حذف $t(entity.playlist, {\"count\": 1})",
|
||||
"deletePlaylist": "حذف $t(entity.playlist_one)",
|
||||
"removeFromQueue": "حذف از صف",
|
||||
"deselectAll": "لغو انتخاب همه",
|
||||
"moveToBottom": "انتقال به پایین",
|
||||
"setRating": "تعیین امتیاز",
|
||||
"toggleSmartPlaylistEditor": "تغییر ویرایشگر $t(entity.smartPlaylist)",
|
||||
"removeFromFavorites": "حذف از $t(entity.favorite, {\"count\": 2})",
|
||||
"removeFromFavorites": "حذف از $t(entity.favorite_other)",
|
||||
"openIn": {
|
||||
"lastfm": "باز کردن در Last.fm",
|
||||
"musicbrainz": "باز کردن در MusicBranz"
|
||||
@@ -76,15 +76,16 @@
|
||||
"hotkey_volumeDown": "کم کردن صدا",
|
||||
"audioPlayer_description": "پخشکنندهٔ صدا را برای پخش انتخاب کنید",
|
||||
"hotkey_globalSearch": "جست و جوی سراسری",
|
||||
"disableAutomaticUpdates": "غیرفعال کردن بهروزرسانی خودکار",
|
||||
"exitToTray_description": "خروج از اپلیکیشن به system tray",
|
||||
"replayGainMode_optionAlbum": "$t(entity.album, {\"count\": 1})",
|
||||
"replayGainMode_optionAlbum": "$t(entity.album_one)",
|
||||
"discordUpdateInterval_description": "فاصلهٔ بین هر به روزرسانی به ثانیه (حداقل ۱۵ ثانیه)",
|
||||
"audioExclusiveMode": "حالت اختصاصی صدا",
|
||||
"remotePassword": "رمز عبور کنترل از راه دور",
|
||||
"language_description": "زبان اپلیکیشن را معین میکند $t(common.restartRequired)",
|
||||
"hotkey_rate3": "امتیاز ۳ ستاره",
|
||||
"font": "قلم",
|
||||
"replayGainMode_optionTrack": "$t(entity.track, {\"count\": 1})",
|
||||
"replayGainMode_optionTrack": "$t(entity.track_one)",
|
||||
"hotkey_toggleFullScreenPlayer": "تغییر به پخشکنندهٔ تمامصفحه",
|
||||
"hotkey_localSearch": "جست و جو در صفحه",
|
||||
"hotkey_toggleQueue": "تغییر صف",
|
||||
@@ -185,7 +186,7 @@
|
||||
"left": "چپ",
|
||||
"save": "ذخیره",
|
||||
"right": "راست",
|
||||
"currentSong": "فعلی $t(entity.track, {\"count\": 1})",
|
||||
"currentSong": "فعلی $t(entity.track_one)",
|
||||
"collapse": "بستن",
|
||||
"trackNumber": "قطعه",
|
||||
"descending": "نزولی",
|
||||
@@ -238,7 +239,7 @@
|
||||
"none": "هیچ",
|
||||
"menu": "منو",
|
||||
"restartRequired": "راهاندازی دوباره لازم است",
|
||||
"previousSong": "$t(entity.track, {\"count\": 1}) پیشین",
|
||||
"previousSong": "$t(entity.track_one) پیشین",
|
||||
"noResultsFromQuery": "جستوجو نتیجهای نداشت",
|
||||
"quit": "خروج",
|
||||
"expand": "گسترش",
|
||||
@@ -255,8 +256,7 @@
|
||||
"albumPeak": "اوج آلبوم",
|
||||
"mbid": "شناسهی MusicBrainz",
|
||||
"reload": "بارگذاری مجدد",
|
||||
"setting_one": "پیکربندی",
|
||||
"setting_other": "",
|
||||
"setting": "پیکربندی",
|
||||
"trackGain": "گین قطعه",
|
||||
"trackPeak": "اوج قطعه",
|
||||
"translation": "ترجمه",
|
||||
@@ -301,16 +301,16 @@
|
||||
"rating": "امتیاز",
|
||||
"search": "جستوجو",
|
||||
"bitrate": "بیتریت",
|
||||
"genre": "$t(entity.genre, {\"count\": 1})",
|
||||
"genre": "$t(entity.genre_one)",
|
||||
"recentlyAdded": "به تازگی افزوده شده",
|
||||
"note": "توجه",
|
||||
"name": "نام",
|
||||
"dateAdded": "تاریخ افزوده شدن",
|
||||
"releaseDate": "تاریخ انتشار",
|
||||
"albumCount": "$t(entity.album, {\"count\": 2}) عدد",
|
||||
"albumCount": "$t(entity.album_other) عدد",
|
||||
"path": "مسیر",
|
||||
"favorited": "موردعلاقه",
|
||||
"albumArtist": "$t(entity.albumArtist, {\"count\": 1})",
|
||||
"albumArtist": "$t(entity.albumArtist_one)",
|
||||
"isRecentlyPlayed": "به تازگی پخش شده است",
|
||||
"isFavorited": "موردعلاقه است",
|
||||
"bpm": "bpm",
|
||||
@@ -319,7 +319,7 @@
|
||||
"disc": "دیسک",
|
||||
"biography": "زندگینامه",
|
||||
"songCount": "تعداد ترانه",
|
||||
"artist": "$t(entity.artist, {\"count\": 1})",
|
||||
"artist": "$t(entity.artist_one)",
|
||||
"duration": "مدت",
|
||||
"isPublic": "عمومی است",
|
||||
"random": "تصادفی",
|
||||
@@ -327,23 +327,23 @@
|
||||
"toYear": "تا سال",
|
||||
"fromYear": "از سال",
|
||||
"criticRating": "امتیاز منتقدین",
|
||||
"album": "$t(entity.album, {\"count\": 1})",
|
||||
"album": "$t(entity.album_one)",
|
||||
"trackNumber": "قطعه",
|
||||
"communityRating": "رتبه بندی جامعه",
|
||||
"isCompilation": "مخلوط است"
|
||||
},
|
||||
"form": {
|
||||
"deletePlaylist": {
|
||||
"title": "حذف $t(entity.playlist, {\"count\": 1})",
|
||||
"success": "$t(entity.playlist, {\"count\": 1}) حذف شد",
|
||||
"input_confirm": "برای تایید، نام $t(entity.playlist, {\"count\": 1}) را وارد کنید"
|
||||
"title": "حذف $t(entity.playlist_one)",
|
||||
"success": "$t(entity.playlist_one) حذف شد",
|
||||
"input_confirm": "برای تایید، نام $t(entity.playlist_one) را وارد کنید"
|
||||
},
|
||||
"createPlaylist": {
|
||||
"input_description": "$t(common.description)",
|
||||
"title": "ساخت $t(entity.playlist, {\"count\": 1})",
|
||||
"title": "ساخت $t(entity.playlist_one)",
|
||||
"input_public": "عمومی",
|
||||
"input_name": "$t(common.name)",
|
||||
"success": "$t(entity.playlist, {\"count\": 1}) ساخته شد",
|
||||
"success": "$t(entity.playlist_one) ساخته شد",
|
||||
"input_owner": "$t(common.owner)"
|
||||
},
|
||||
"addServer": {
|
||||
@@ -360,19 +360,19 @@
|
||||
"ignoreSsl": "نادیده گرفتن ssl ($t(common.restartRequired))"
|
||||
},
|
||||
"addToPlaylist": {
|
||||
"success": "$t(entity.song, {\"count\": 2}) به {{numOfPlaylists}}$t(entity.playlist, {\"count\": 2}) افزوده شد",
|
||||
"title": "افزودن به $t(entity.playlist, {\"count\": 1})",
|
||||
"input_playlists": "$t(entity.playlist, {\"count\": 2})",
|
||||
"success": "$t(entity.song_other) به {{numOfPlaylists}}$t(entity.playlist_other) افزوده شد",
|
||||
"title": "افزودن به $t(entity.playlist_one)",
|
||||
"input_playlists": "$t(entity.playlist_other)",
|
||||
"input_skipDuplicates": "پرش از تکراریها"
|
||||
},
|
||||
"lyricSearch": {
|
||||
"input_name": "$t(common.name)",
|
||||
"input_artist": "$t(entity.artist, {\"count\": 1})",
|
||||
"input_artist": "$t(entity.artist_one)",
|
||||
"title": "جستوجو در متن شعر"
|
||||
},
|
||||
"editPlaylist": {
|
||||
"title": "ویرایش $t(entity.playlist, {\"count\": 1})",
|
||||
"success": "$t(entity.playlist, {\"count\": 1}) با موفقیت بروزرسانی شد",
|
||||
"title": "ویرایش $t(entity.playlist_one)",
|
||||
"success": "$t(entity.playlist_one) با موفقیت بروزرسانی شد",
|
||||
"publicJellyfinNote": "جلیفین به دلیلی اینکه فهرست پخش عمومیست یا خصوصی را فاش نمیکند. اگر میخواهید این عمومی باقی بماند، لطفاٌ ورودی پیشرو را منتخب داشته باشید"
|
||||
},
|
||||
"queryEditor": {
|
||||
@@ -417,7 +417,7 @@
|
||||
"artistWithCount_other": "{{count}} هنرمند",
|
||||
"folder_one": "پوشه",
|
||||
"folder_other": "پوشهها",
|
||||
"smartPlaylist": "$t(entity.playlist, {\"count\": 1}) هوشمند",
|
||||
"smartPlaylist": "$t(entity.playlist_one) هوشمند",
|
||||
"album_one": "آلبوم",
|
||||
"album_other": "آلبومها",
|
||||
"genreWithCount_one": "{{count}} ژانر",
|
||||
@@ -431,12 +431,12 @@
|
||||
},
|
||||
"page": {
|
||||
"albumList": {
|
||||
"title": "$t(entity.album, {\"count\": 2})",
|
||||
"title": "$t(entity.album_other)",
|
||||
"artistAlbums": "آلبومهای {{artist}}",
|
||||
"genreAlbums": "\"{{genre}}\" $t(entity.album, {\"count\": 2})"
|
||||
"genreAlbums": "\"{{genre}}\" $t(entity.album_other)"
|
||||
},
|
||||
"appMenu": {
|
||||
"settings": "$t(common.setting, {\"count\": 2})",
|
||||
"settings": "$t(common.setting_other)",
|
||||
"selectServer": "گزینش سرویسدهنده",
|
||||
"expandSidebar": "گسترش نوار کناری",
|
||||
"collapseSidebar": "فروکش نوار کناری",
|
||||
@@ -451,11 +451,11 @@
|
||||
"appearsOn": "مشاهده میشود در",
|
||||
"about": "دربارهی {{artist}}",
|
||||
"recentReleases": "عرضههای اخیر",
|
||||
"viewAllTracks": "نمایش همهی $t(entity.track, {\"count\": 2})",
|
||||
"viewAllTracks": "نمایش همهی $t(entity.track_other)",
|
||||
"topSongsFrom": "قطعههای برتر از {{title}}",
|
||||
"viewAll": "نمایش همه",
|
||||
"viewDiscography": "نمایش کاتالوگ",
|
||||
"relatedArtists": "$t(entity.artist, {\"count\": 2}) مربوطه",
|
||||
"relatedArtists": "$t(entity.artist_other) مربوطه",
|
||||
"topSongs": "قطعههای برتر"
|
||||
},
|
||||
"contextMenu": {
|
||||
@@ -523,21 +523,21 @@
|
||||
"playbackTab": "پخش"
|
||||
},
|
||||
"sidebar": {
|
||||
"genres": "$t(entity.genre, {\"count\": 2})",
|
||||
"playlists": "$t(entity.playlist, {\"count\": 2})",
|
||||
"genres": "$t(entity.genre_other)",
|
||||
"playlists": "$t(entity.playlist_other)",
|
||||
"search": "$t(common.search)",
|
||||
"albumArtists": "$t(entity.albumArtist, {\"count\": 2})",
|
||||
"albums": "$t(entity.album, {\"count\": 2})",
|
||||
"folders": "$t(entity.folder, {\"count\": 2})",
|
||||
"artists": "$t(entity.artist, {\"count\": 2})",
|
||||
"albumArtists": "$t(entity.albumArtist_other)",
|
||||
"albums": "$t(entity.album_other)",
|
||||
"folders": "$t(entity.folder_other)",
|
||||
"artists": "$t(entity.artist_other)",
|
||||
"home": "$t(common.home)",
|
||||
"nowPlaying": "پخش کنونی",
|
||||
"tracks": "$t(entity.track, {\"count\": 2})",
|
||||
"settings": "$t(common.setting, {\"count\": 2})",
|
||||
"shared": "$t(entity.playlist, {\"count\": 2}) اشتراکگذاری شده"
|
||||
"tracks": "$t(entity.track_other)",
|
||||
"settings": "$t(common.setting_other)",
|
||||
"shared": "$t(entity.playlist_other) اشتراکگذاری شده"
|
||||
},
|
||||
"albumDetail": {
|
||||
"moreFromArtist": "موارد بیشتر از این $t(entity.artist, {\"count\": 1})",
|
||||
"moreFromArtist": "موارد بیشتر از این $t(entity.artist_one)",
|
||||
"moreFromGeneric": "موارد بیشتر از {{item}}",
|
||||
"released": "عرضه شده"
|
||||
},
|
||||
@@ -550,9 +550,9 @@
|
||||
"editServerDetailsTooltip": "ویرایش ریزگان سرویسدهنده"
|
||||
},
|
||||
"genreList": {
|
||||
"showAlbums": "نمایش $t(entity.genre, {\"count\": 1}) $t(entity.album, {\"count\": 2})",
|
||||
"title": "$t(entity.genre, {\"count\": 2})",
|
||||
"showTracks": "نمایش $t(entity.genre, {\"count\": 1}) $t(entity.track, {\"count\": 2})"
|
||||
"showAlbums": "نمایش $t(entity.genre_one) $t(entity.album_other)",
|
||||
"title": "$t(entity.genre_other)",
|
||||
"showTracks": "نمایش $t(entity.genre_one) $t(entity.track_other)"
|
||||
},
|
||||
"globalSearch": {
|
||||
"commands": {
|
||||
@@ -563,15 +563,15 @@
|
||||
"title": "فرمانها"
|
||||
},
|
||||
"playlistList": {
|
||||
"title": "$t(entity.playlist, {\"count\": 2})"
|
||||
"title": "$t(entity.playlist_other)"
|
||||
},
|
||||
"trackList": {
|
||||
"title": "$t(entity.track, {\"count\": 2})",
|
||||
"title": "$t(entity.track_other)",
|
||||
"artistTracks": "قطعههای {{artist}}",
|
||||
"genreTracks": "$t(entity.track, {\"count\": 2}) \"{{genre}}\""
|
||||
"genreTracks": "$t(entity.track_other) \"{{genre}}\""
|
||||
},
|
||||
"albumArtistList": {
|
||||
"title": "$t(entity.albumArtist, {\"count\": 2})"
|
||||
"title": "$t(entity.albumArtist_other)"
|
||||
},
|
||||
"itemDetail": {
|
||||
"copyPath": "کپی کردن مسیر در کلیپبورد",
|
||||
@@ -584,11 +584,11 @@
|
||||
"size": "$t(common.size)",
|
||||
"lastPlayed": "آخرین بار پخش شده",
|
||||
"discNumber": "دیسک",
|
||||
"songCount": "$t(entity.track, {\"count\": 2})",
|
||||
"songCount": "$t(entity.track_other)",
|
||||
"title": "عنوان",
|
||||
"trackNumber": "قطعه",
|
||||
"favorite": "مورد علاقه",
|
||||
"genre": "$t(entity.genre, {\"count\": 1})",
|
||||
"genre": "$t(entity.genre_one)",
|
||||
"comment": "دیدگاه",
|
||||
"playCount": "تعداد پخش",
|
||||
"rating": "امتیاز",
|
||||
@@ -608,6 +608,9 @@
|
||||
"gap": "$t(common.gap)",
|
||||
"itemGap": "فاصلهی آیتم (px)"
|
||||
},
|
||||
"view": {
|
||||
"card": "کارت"
|
||||
},
|
||||
"label": {
|
||||
"playCount": "تعداد پخش",
|
||||
"dateAdded": "تاریخ افزوده شدن",
|
||||
|
||||